changeset 2874:585d0053b766

C++: Implement buttons, images, render, pixmap and boxes.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 19 Dec 2022 13:57:43 +0000
parents 0bbfb19022e7
children d15517b49638
files dw.hpp
diffstat 1 files changed, 226 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/dw.hpp	Mon Dec 19 07:42:12 2022 +0000
+++ b/dw.hpp	Mon Dec 19 13:57:43 2022 +0000
@@ -49,12 +49,14 @@
     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); }
+    int SetColor(unsigned long fore, unsigned long back) { return dw_window_set_color(hwnd, fore, back); }
 };
 
 // Box class is a packable object
-class Box : public Widget
+class Boxes : public Widget
 {
 public:
+    // User functions
     void PackStart(Widget *item, int width, int height, int hsize, int vsize, int pad) { 
         dw_box_pack_start(hwnd, item ? item->GetHWND() : DW_NOHWND, width, height, hsize, vsize, pad); }
     void PackEnd(Widget *item, int width, int height, int hsize, int vsize, int pad) { 
@@ -67,16 +69,36 @@
     }
 };
 
+class Box : public Boxes
+{
+    // Constructors
+    Box(int type, int pad) { SetHWND(dw_box_new(type, pad)); }
+    Box(int type) { SetHWND(dw_box_new(type, 0)); }
+};
+
+// Special scrollable box
+class ScrollBox : public Boxes
+{
+public:
+    // Constructors
+    ScrollBox(int type, int pad) { SetHWND(dw_scrollbox_new(type, pad)); }
+    ScrollBox(int type) { SetHWND(dw_scrollbox_new(type, 0)); }
+
+    // User functions
+    int GetRange(int orient) { return dw_scrollbox_get_range(hwnd, orient); }
+    int GetPos(int orient) { return dw_scrollbox_get_pos(hwnd, orient); }
+};
+
 // 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
-class Window : public Box
+class Window : public Boxes
 {
 private:
     void Setup() {	
-        if(IsOverridden(Window::OnConfigure, this))
+        if(IsOverridden(Window::OnDelete, this))
             dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this);
         if(IsOverridden(Window::OnConfigure, this))
             dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
@@ -95,6 +117,7 @@
 
     // User functions
     void SetText(const char *text) { dw_window_set_text(hwnd, text); }
+    char *GetText() { return dw_window_get_text(hwnd); }
     void SetSize(unsigned long width, unsigned long height) { dw_window_set_size(hwnd, width, height); }
     int Show() { return dw_window_show(hwnd); }
     int Hide() { return dw_window_hide(hwnd); }
@@ -109,19 +132,219 @@
     virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; };
 };
 
+// Base class for several types of buttons
+class Buttons : public Widget
+{
+private:
+    static int _OnClicked(HWND window, void *data) { return reinterpret_cast<Buttons *>(data)->OnClicked(); }
+protected:
+    void Setup() {	
+        if(IsOverridden(Window::OnClicked, this))
+            dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this);
+    }
+    // Our signal handler functions to be overriden...
+    // If they are not overridden and an event is generated, remove the unused handler
+    virtual int OnClicked() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED); return FALSE; }
+};
+
+// Text based button
+class TextButton : public Buttons
+{
+public:
+    // User functions
+    void SetText(const char *text) { dw_window_set_text(hwnd, text); }
+    char *GetText() { return dw_window_get_text(hwnd); }
+};
+
+class Button : public TextButton
+{
+public:
+    // Constructors
+    Button(const char *text, unsigned long id) { SetHWND(dw_button_new(text, id)); Setup(); }
+    Button(unsigned long id) { SetHWND(dw_button_new("", id)); Setup(); }
+    Button(const char *text) { SetHWND(dw_button_new(text, 0)); Setup(); }
+    Button() { SetHWND(dw_button_new("", 0)); Setup(); }
+};
+
+// Image based button
+class BitmapButton : public Buttons
+{
+public:
+    // Constructors
+    BitmapButton(const char *text, unsigned long id) { SetHWND(dw_bitmapbutton_new(text, id)); Setup(); }
+    BitmapButton(unsigned long id) { SetHWND(dw_bitmapbutton_new("", id)); Setup(); }
+    BitmapButton(const char *text, unsigned long id, const char *file) { SetHWND(dw_bitmapbutton_new_from_file(text, id, file)); Setup(); }
+    BitmapButton(const char *text, const char *file) { SetHWND(dw_bitmapbutton_new_from_file(text, 0, file)); Setup(); }
+    BitmapButton(const char *text, unsigned long id, const char *data, int len) { SetHWND(dw_bitmapbutton_new_from_data(text, id, data, len)); Setup(); }
+    BitmapButton(const char *text, const char *data, int len) { SetHWND(dw_bitmapbutton_new_from_data(text, 0, data, len)); Setup(); }
+};
+
+class CheckBoxes : public TextButton
+{
+    // User functions
+    void Set(int value) { dw_checkbox_set(hwnd, value); }
+    int Get() { return dw_checkbox_get(hwnd); }
+};
+
+class CheckBox : public CheckBoxes
+{
+    // Constructors
+    CheckBox(const char *text, unsigned long id) { SetHWND(dw_checkbox_new(text, id)); Setup(); }
+    CheckBox(unsigned long id) { SetHWND(dw_checkbox_new("", id)); Setup(); }
+    CheckBox(const char *text) { SetHWND(dw_checkbox_new(text, 0)); Setup(); }
+    CheckBox() { SetHWND(dw_checkbox_new("", 0)); Setup(); }
+};
+
+class RadioButton : public CheckBoxes
+{
+    // Constructors
+    RadioButton(const char *text, unsigned long id) { SetHWND(dw_radiobutton_new(text, id)); Setup(); }
+    RadioButton(unsigned long id) { SetHWND(dw_radiobutton_new("", id)); Setup(); }
+    RadioButton(const char *text) { SetHWND(dw_radiobutton_new(text, 0)); Setup(); }
+    RadioButton() { SetHWND(dw_radiobutton_new("", 0)); Setup(); }
+};
+
 // Class for handling static text widget
 class Text : public Widget
 {
 public:
+    // Constructors
     Text(const char *text, unsigned long id) { SetHWND(dw_text_new(text, id)); }
     Text(const char *text) { SetHWND(dw_text_new(text, 0)); }
     Text(unsigned long id) { SetHWND(dw_text_new("", id)); }
     Text() { SetHWND(dw_text_new("", 0)); }
+
+    // User functions
     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 for handing static image widget
+class Bitmap : public Widget
+{
+public:
+    // Constructors
+    Bitmap(const char *data, int len) { SetHWND(dw_bitmap_new(0)); dw_window_set_bitmap_from_data(hwnd, 0, data, len); }
+    Bitmap(const char *file) { SetHWND(dw_bitmap_new(0)); dw_window_set_bitmap(hwnd, 0, file); }
+    Bitmap(unsigned long id) { SetHWND(dw_bitmap_new(id)); }
+    Bitmap() { SetHWND(dw_bitmap_new(0)); }
+
+    // User functions
+    void Set(unsigned long id) { dw_window_set_bitmap(hwnd, id, DW_NULL); }
+    void Set(const char *file) { dw_window_set_bitmap(hwnd, 0, file); }
+    void Set(const char *data, int len) { dw_window_set_bitmap_from_data(hwnd, 0, data, len); }
+};
+
+// Forward declare these so our Drawable abstract class can reference
+class Render;
+class Pixmap;
+
+// Abstract class that defines drawing, either to screen or picture (pixmap)
+class Drawable
+{
+public:
+    virtual void DrawPoint(int x, int y) = 0;
+    virtual void DrawLine(int x1, int y1, int x2, int y2) = 0;
+    virtual void DrawPolygon(int flags, int npoints, int x[], int y[]) = 0;
+    virtual void DrawRect(int fill, int x, int y, int width, int height) = 0;
+    virtual void DrawArc(int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) = 0;
+    virtual void DrawText(int x, int y, const char *text) = 0;
+    virtual int BitBltStretch(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc, int srcwidth, int srcheight) = 0;
+    virtual int BitBltStretch(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc, int srcwidth, int srcheight) = 0;
+    virtual void BitBlt(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc) = 0;
+    virtual void BitBlt(int xdest, int ydest, int width, int height, Pixmap *srcp, int xsrc, int ysrc) = 0;
+    void SetColor(unsigned long fore, unsigned long back) { dw_color_foreground_set(fore); dw_color_background_set(back); }    
+    void SetBackgroundColor(unsigned long back) { dw_color_background_set(back); }  
+    void SetForegroundColor(unsigned long fore) { dw_color_foreground_set(fore); }      
+};
+
+class Render : public Drawable, public Widget
+{
+private:
+    void Setup() {	
+        if(IsOverridden(Window::OnExpose, this))
+            dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this);
+        if(IsOverridden(Window::OnConfigure, this))
+            dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
+    }
+    static int _OnExpose(HWND window, DWExpose *exp, void *data) { return reinterpret_cast<Render *>(data)->OnExpose(exp); }
+    static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Render *>(data)->OnConfigure(width, height); }
+public:
+    // Constructors
+    Render(unsigned long id) { SetHWND(dw_render_new(id)); Setup(); }
+    Render() { SetHWND(dw_render_new(0)); Setup(); }
+
+    // User functions
+    void DrawPoint(int x, int y) { dw_draw_point(hwnd, DW_NULL, x, y); }
+    void DrawLine(int x1, int y1, int x2, int y2) { dw_draw_line(hwnd, DW_NULL, x1, y1, x2, y2); }
+    void DrawPolygon(int flags, int npoints, int x[], int y[]) { dw_draw_polygon(hwnd, DW_NULL, flags, npoints, x, y); }
+    void DrawRect(int fill, int x, int y, int width, int height) { dw_draw_rect(hwnd, DW_NULL, fill, x, y, width, height); }
+    void DrawArc(int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) { dw_draw_arc(hwnd, DW_NULL, flags, xorigin, yorigin, x1, y1, x2, y2); }
+    void DrawText(int x, int y, const char *text) { dw_draw_text(hwnd, DW_NULL, x, y, text); }
+    int BitBltStretch(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc, int srcwidth, int srcheight) {
+        return dw_pixmap_stretch_bitblt(hwnd, DW_NULL, xdest, ydest, width, height, src ? src->GetHWND() : DW_NOHWND, DW_NULL, xsrc, ysrc, srcwidth, srcheight);
+    }
+    int BitBltStretch(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc, int srcwidth, int srcheight);
+    void BitBlt(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc) {
+        return dw_pixmap_bitblt(hwnd, DW_NULL, xdest, ydest, width, height, src ? src->GetHWND() : DW_NOHWND, DW_NULL, xsrc, ysrc);
+    }
+    void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc);
+    int SetFont(const char *fontname) { return dw_window_set_font(hwnd, fontname); }
+    char *GetFont() { return dw_window_get_font(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 OnExpose(DWExpose *exp) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_EXPOSE); return FALSE; }
+    virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; };
+};
+
+class Pixmap : public Drawable, public Handle
+{
+protected:
+    void SetHPIXMAP(HPIXMAP newpixmap) { 
+        hpixmap = newpixmap; 
+        SetHandle(reinterpret_cast<void *>(newpixmap));
+    }
+    HPIXMAP hpixmap; 
+public:
+    // Constructors
+    Pixmap(HWND window, unsigned long width, unsigned long height, int depth) { SetHPIXMAP(dw_pixmap_new(window, width, height, depth)); }
+    Pixmap(HWND window, unsigned long width, unsigned long height) { SetHPIXMAP(dw_pixmap_new(window, width, height, 32)); }
+
+    // User functions
+    HPIXMAP GetHPIXMAP() { return hpixmap; }
+    void DrawPoint(int x, int y) { dw_draw_point(DW_NOHWND, hpixmap, x, y); }
+    void DrawLine(int x1, int y1, int x2, int y2) { dw_draw_line(DW_NOHWND, hpixmap, x1, y1, x2, y2); }
+    void DrawPolygon(int flags, int npoints, int x[], int y[]) { dw_draw_polygon(DW_NOHWND, hpixmap, flags, npoints, x, y); }
+    void DrawRect(int fill, int x, int y, int width, int height) { dw_draw_rect(DW_NOHWND, hpixmap, fill, x, y, width, height); }
+    void DrawArc(int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) { dw_draw_arc(DW_NOHWND, hpixmap, flags, xorigin, yorigin, x1, y1, x2, y2); }
+    void DrawText(int x, int y, const char *text) { dw_draw_text(DW_NOHWND, hpixmap, x, y, text); }
+    int BitBltStretch(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc, int srcwidth, int srcheight) {
+        return dw_pixmap_stretch_bitblt(DW_NOHWND, hpixmap, xdest, ydest, width, height, src ? src->GetHWND() : DW_NOHWND, DW_NULL, xsrc, ysrc, srcwidth, srcheight);
+    }
+    int BitBltStretch(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc, int srcwidth, int srcheight) {
+        return dw_pixmap_stretch_bitblt(DW_NOHWND, hpixmap, xdest, ydest, width, height, DW_NOHWND, src ? src->GetHPIXMAP() : DW_NULL, xsrc, ysrc, srcwidth, srcheight);
+    }
+    void BitBlt(int xdest, int ydest, int width, int height, Render *src, int xsrc, int ysrc) {
+        dw_pixmap_bitblt(DW_NOHWND, hpixmap, xdest, ydest, width, height, src ? src->GetHWND() : DW_NOHWND, DW_NULL, xsrc, ysrc);
+    }
+    void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc) {
+        dw_pixmap_bitblt(DW_NOHWND, hpixmap, xdest, ydest, width, height, DW_NOHWND, src ? src->GetHPIXMAP() : DW_NULL, xsrc, ysrc);
+    }
+    int SetFont(const char *fontname) { return dw_pixmap_set_font(hpixmap, fontname); }
+};
+
+// Need to declare these here after Pixmap is defined
+int Render::BitBltStretch(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc, int srcwidth, int srcheight)
+{
+    return dw_pixmap_stretch_bitblt(hwnd, DW_NULL, xdest, ydest, width, height, DW_NOHWND, src ? src->GetHPIXMAP() : DW_NULL, xsrc, ysrc, srcwidth, srcheight);
+}
+
+void Render::BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc)
+{
+    dw_pixmap_bitblt(hwnd, DW_NULL, xdest, ydest, width, height, DW_NOHWND, src ? src->GetHPIXMAP() : DW_NULL, xsrc, ysrc);
+}
 
 class App
 {
@@ -153,30 +376,5 @@
 // Static singleton reference declared outside of the class
 App* App::_app = DW_NULL;
 
-#if 0
-// Class that allows drawing, either to screen or picture (pixmap)
-class Drawable
-{
-    void DrawPoint(int x, int y);
-    void DrawLine(int x1, int y1, int x2, int y2);
-    void DrawPolygon(int flags, int x[], int y[]);
-    void DrawRect(int fill, int x, int y, int width, int height);
-    void DrawArc(int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2);
-    void DrawText(int x, int y, std::string text);
-    int BitBltStretch(int xdest, int ydest, int width, int height, HWND src, int xsrc, int ysrc, int srcwidth, int srcheight);
-    int BitBltStretch(int xdest, int ydest, int width, int height, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight);
-    void BitBlt(int xdest, int ydest, int width, int height, HWND src, int xsrc, int ysrc);
-    void BitBlt(int xdest, int ydest, int width, int height, HPIXMAP srcp, int xsrc, int ysrc);
-};
-
-class Render : public Drawable, public Widget
-{
-};
-
-class Pixmap : public Drawable, public Handle
-{
-};
-#endif
-
 } /* namespace DW */
 #endif
\ No newline at end of file