changeset 2868:5ee1aaa48fc7

C++: The last signal handler change only worked with Clang/LLVM. Less desirable but cross platform solution, attach all signal handlers on widget creation, when called if not overridden remove the unused handler. Started the work of filling in the widget classes and functions.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 18 Dec 2022 11:40:22 +0000
parents ada74f4d3f39
children c873b6f862b9
files dw.hpp dwtestoo.cpp
diffstat 2 files changed, 59 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/dw.hpp	Sat Dec 17 21:39:00 2022 +0000
+++ b/dw.hpp	Sun Dec 18 11:40:22 2022 +0000
@@ -14,45 +14,64 @@
 // The base system handles
 class Handle 
 {
-private:
+protected:
 	void *handle;
+	void SetHandle(void *newhandle) { handle = newhandle; }
 public:
-	void SetHandle(void *newhandle) { handle = newhandle; }
 	void *GetHandle() { return handle; }
 };
 
 // Widget class allows packing and style
 class Widget : public Handle
 {
-public:
+protected:
+	void SetHWND(HWND newhwnd) { hwnd = newhwnd; 
+		SetHandle(reinterpret_cast<void *>(newhwnd));
+		// Save the C++ class pointer in the window data for later
+		dw_window_set_data(hwnd, "_dw_classptr", this);
+	}
 	HWND hwnd; 
-	HWND GetHWND() { return reinterpret_cast<HWND>(GetHandle()); }
-	void SetHWND(HWND newhwnd) { hwnd = newhwnd; SetHandle(reinterpret_cast<void *>(newhwnd)); }
+public:
+	HWND GetHWND() { return hwnd; }
+	int Unpack() { return dw_box_unpack(hwnd); }
+	void SetStyle(unsigned long style, unsigned long mask) { dw_window_set_style(hwnd, style, mask); }
+	void SetTooltip(char *bubbletext) { dw_window_set_tooltip(hwnd, bubbletext); }
 };
 
 // Box class is a packable object
 class Box : public Widget
 {
+public:
+	void PackStart(Widget *item, int width, int height, int hsize, int vsize, int pad) { 
+		dw_box_pack_start(hwnd, item ? item->GetHWND() : nullptr, width, height, hsize, vsize, pad); }
+	void PackEnd(Widget *item, int width, int height, int hsize, int vsize, int pad) { 
+		dw_box_pack_end(hwnd, item ? item->GetHWND() : nullptr, width, height, hsize, vsize, pad); }
+	void PackAtIndex(Widget *item, int index, int width, int height, int hsize, int vsize, int pad) { 
+		dw_box_pack_at_index(hwnd, item ? item->GetHWND() : nullptr, index, width, height, hsize, vsize, pad); }
+	Widget *UnpackAtIndex(int index) { HWND widget = dw_box_unpack_at_index(hwnd, index);
+		void *classptr = widget ? dw_window_get_data(widget, "_dw_classptr") : nullptr;
+		return reinterpret_cast<Widget *>(classptr);
+	}
 };
-	
+
+// TODO: Find a way to implement this cross platform...
+// That way we can skip adding unused signal handlers
+#define IsOverridden(a, b) true
+
 // Top-level window class is packable
-template <class Derived>
 class Window : public Box
 {
 private:
 	void Setup() {	
-		if(&Derived::OnDelete != &Window::OnDelete) {
+		if(IsOverridden(Window::OnConfigure, this))
 			dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this);
-			dw_debug("DW_SIGNAL_DELETE\n");
-		}
-		if(&Derived::OnConfigure != &Window::OnConfigure) {
+		if(IsOverridden(Window::OnConfigure, this))
 			dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
-			dw_debug("DW_SIGNAL_CONFIGURE\n");
-		}
 	}
 	static int _OnDelete(HWND window, void *data) { return reinterpret_cast<Window *>(data)->OnDelete(); }
 	static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Window *>(data)->OnConfigure(width, height); }
 public:
+	// Constructors
 	Window(HWND owner, const char *title, unsigned long style) { SetHWND(dw_window_new(owner, title, style)); Setup(); }
 	Window(const char *title, unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, title, style)); Setup(); }
 	Window(unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, "", style)); Setup(); }
@@ -61,14 +80,36 @@
 	Window() { SetHWND(dw_window_new(HWND_DESKTOP, "", DW_FCF_SYSMENU | DW_FCF_TITLEBAR |
                         DW_FCF_TASKLIST | DW_FCF_SIZEBORDER | DW_FCF_MINMAX)); Setup(); }
 
+	// User functions
 	void SetText(const char *text) { dw_window_set_text(hwnd, text); }
 	void SetSize(unsigned long width, unsigned long height) { dw_window_set_size(hwnd, width, height); }
-	void Show() { dw_window_show(hwnd); }
-	// Our signal handler functions to be overriden
-	virtual int OnDelete() { return FALSE; }
-	virtual int OnConfigure(int width, int height) { return FALSE; };
+	int Show() { return dw_window_show(hwnd); }
+	int Hide() { return dw_window_hide(hwnd); }
+	void SetGravity(int horz, int vert) { dw_window_set_gravity(hwnd, horz, vert); }
+	int Minimize() { return dw_window_minimize(hwnd); }
+	int Raise() { return dw_window_raise(hwnd); }
+	int Lower() { return dw_window_lower(hwnd); }
+protected:
+	// Our signal handler functions to be overriden...
+	// If they are not overridden and an event is generated, remove the unused handler
+	virtual int OnDelete() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_DELETE); return FALSE; }
+	virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; };
 };
 
+// Class for handling static text widget
+class Text : public Widget
+{
+public:
+	Text(char *text, unsigned long id) { SetHWND(dw_text_new(text, id)); }
+	Text(char *text) { SetHWND(dw_text_new(text, 0)); }
+	Text(unsigned long id) { SetHWND(dw_text_new("", id)); }
+	Text() { SetHWND(dw_text_new("", 0)); }
+	void SetText(const char *text) { dw_window_set_text(hwnd, text); }
+	int SetFont(const char *font) { return dw_window_set_font(hwnd, font); }
+	char *GetFont() { return dw_window_get_font(hwnd); }
+};
+
+
 class App
 {
 protected:
--- a/dwtestoo.cpp	Sat Dec 17 21:39:00 2022 +0000
+++ b/dwtestoo.cpp	Sun Dec 18 11:40:22 2022 +0000
@@ -1,6 +1,6 @@
 #include <dw.hpp>
 
-class MyWindow : public DW::Window<MyWindow>
+class MyWindow : public DW::Window
 {
 public:
   MyWindow() {