diff --git a/ui.h b/ui.h index 40aea949..b2088a07 100644 --- a/ui.h +++ b/ui.h @@ -305,6 +305,8 @@ typedef struct uiAreaKeyEvent uiAreaKeyEvent; typedef struct uiDrawContext uiDrawContext; +// TO CONSIDER: the uiAreaHandler param there seems useless +// (might use individual callbacks instead of handler struct?) struct uiAreaHandler { void (*Draw)(uiAreaHandler *, uiArea *, uiAreaDrawParams *); // TODO document that resizes cause a full redraw for non-scrolling areas; implementation-defined for scrolling areas @@ -314,6 +316,7 @@ struct uiAreaHandler { void (*MouseCrossed)(uiAreaHandler *, uiArea *, int left); void (*DragBroken)(uiAreaHandler *, uiArea *); int (*KeyEvent)(uiAreaHandler *, uiArea *, uiAreaKeyEvent *); + void (*Resize)(uiAreaHandler *, uiArea *, int, int); }; // TODO RTL layouts? @@ -346,6 +349,7 @@ _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, doub // TODO release capture? _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a); _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge); +_UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b); _UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height); diff --git a/unix/area.c b/unix/area.c index 19b34634..c11e494a 100644 --- a/unix/area.c +++ b/unix/area.c @@ -37,6 +37,7 @@ struct uiArea { GtkWidget *areaWidget; GtkDrawingArea *drawingArea; areaWidget *area; + int bgR, bgG, bgB; uiAreaHandler *ah; @@ -96,6 +97,8 @@ static void areaWidget_size_allocate(GtkWidget *w, GtkAllocation *allocation) // TODO drop this rule; it was stupid and documenting this was stupid — let platforms where it matters do it on their own // TODO or do we not, for parity of performance? gtk_widget_queue_resize(w); + + a->ah->Resize(a->ah, a, allocation->width, allocation->height); } static void loadAreaSize(uiArea *a, double *width, double *height) @@ -133,6 +136,11 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) dp.ClipWidth = clipX1 - clipX0; dp.ClipHeight = clipY1 - clipY0; + if (a->bgR != -1) { + cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0); + cairo_paint(cr); + } + // no need to save or restore the graphics state to reset transformations; GTK+ does that for us (*(a->ah->Draw))(a->ah, a, &dp); @@ -155,6 +163,8 @@ static void areaWidget_get_preferred_height(GtkWidget *w, gint *min, gint *nat) *min = a->scrollHeight; *nat = a->scrollHeight; } + + // TODO: min size } static void areaWidget_get_preferred_width(GtkWidget *w, gint *min, gint *nat) @@ -496,6 +506,13 @@ static void areaWidget_class_init(areaWidgetClass *class) uiUnixControlAllDefaults(uiArea) +void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) +{ + a->bgR = r; + a->bgG = g; + a->bgB = b; +} + void uiAreaSetSize(uiArea *a, int width, int height) { if (!a->scrolling) @@ -603,6 +620,8 @@ uiArea *uiNewArea(uiAreaHandler *ah) a->widget = a->areaWidget; + uiAreaSetBackgroundColor(a, -1, -1, -1); + return a; } @@ -629,6 +648,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) a->widget = a->swidget; + uiAreaSetBackgroundColor(a, -1, -1, -1); + gtk_container_add(a->scontainer, a->areaWidget); // and make the area visible; only the scrolled window's visibility is controlled by libui gtk_widget_show(a->areaWidget); diff --git a/windows/area.cpp b/windows/area.cpp index 0042fccc..908ea5ab 100644 --- a/windows/area.cpp +++ b/windows/area.cpp @@ -11,6 +11,7 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM RECT client; WINDOWPOS *wp = (WINDOWPOS *) lParam; LRESULT lResult; + double w, h; a = (uiArea *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); if (a == NULL) { @@ -37,6 +38,8 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM uiWindowsEnsureGetClientRect(a->hwnd, &client); areaDrawOnResize(a, &client); areaScrollOnResize(a, &client); + loadAreaSize(a, a->rt, &w, &h); + a->ah->Resize(a->ah, a, (int)w, (int)h); return 0; } @@ -160,6 +163,13 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) wParam, 0); } +void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) +{ + a->bgR = r; + a->bgG = g; + a->bgB = b; +} + uiArea *uiNewArea(uiAreaHandler *ah) { uiArea *a; @@ -177,6 +187,8 @@ uiArea *uiNewArea(uiAreaHandler *ah) hInstance, a, FALSE); + uiAreaSetBackgroundColor(a, -1, -1, -1); + return a; } @@ -199,6 +211,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) hInstance, a, FALSE); + uiAreaSetBackgroundColor(a, -1, -1, -1); + // set initial scrolling parameters areaUpdateScroll(a); diff --git a/windows/area.hpp b/windows/area.hpp index dfc2bc58..13a97aaf 100644 --- a/windows/area.hpp +++ b/windows/area.hpp @@ -24,6 +24,8 @@ struct uiArea { BOOL inside; BOOL tracking; + int bgR, bgG, bgB; + ID2D1HwndRenderTarget *rt; }; diff --git a/windows/areadraw.cpp b/windows/areadraw.cpp index 7b3dc696..aa09de39 100644 --- a/windows/areadraw.cpp +++ b/windows/areadraw.cpp @@ -40,14 +40,21 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip) // TODO only clear the clip area // TODO clear with actual background brush - bgcolorref = GetSysColor(COLOR_BTNFACE); - bgcolor.r = ((float) GetRValue(bgcolorref)) / 255.0; - // due to utter apathy on Microsoft's part, GetGValue() does not work with MSVC's Run-Time Error Checks - // it has not worked since 2008 and they have *never* fixed it - // TODO now that -RTCc has just been deprecated entirely, should we switch back? - bgcolor.g = ((float) ((BYTE) ((bgcolorref & 0xFF00) >> 8))) / 255.0; - bgcolor.b = ((float) GetBValue(bgcolorref)) / 255.0; - bgcolor.a = 1.0; + if (a->bgR != -1) { + bgcolor.r = ((float) a->bgR) / 255.0; + bgcolor.g = ((float) a->bgG) / 255.0; + bgcolor.b = ((float) a->bgB) / 255.0; + bgcolor.a = 1.0; + } else { + bgcolorref = GetSysColor(COLOR_BTNFACE); + bgcolor.r = ((float) GetRValue(bgcolorref)) / 255.0; + // due to utter apathy on Microsoft's part, GetGValue() does not work with MSVC's Run-Time Error Checks + // it has not worked since 2008 and they have *never* fixed it + // TODO now that -RTCc has just been deprecated entirely, should we switch back? + bgcolor.g = ((float) ((BYTE) ((bgcolorref & 0xFF00) >> 8))) / 255.0; + bgcolor.b = ((float) GetBValue(bgcolorref)) / 255.0; + bgcolor.a = 1.0; + } rt->Clear(&bgcolor); (*(ah->Draw))(ah, a, &dp);