diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c index efc1da55c..58f5c2e5e 100644 --- a/examples/basic/periodic.c +++ b/examples/basic/periodic.c @@ -312,7 +312,7 @@ int main() { NULL); w = child(f); MwViewportSetSize(w, 512, 512); - MwVaCreateWidget(MwSubWindowClass, "swnd", MwViewportGetViewport(w), 32, 32, 128, 128, + MwVaCreateWidget(MwSubWindowClass, "swnd", MwViewportGetViewport(w), 32, 32, 256, 128, MwNtitle, "Sub window", NULL); add(f); diff --git a/include/Mw/Default.h b/include/Mw/Default.h index 8e3c0b25b..f20a60c68 100644 --- a/include/Mw/Default.h +++ b/include/Mw/Default.h @@ -32,6 +32,16 @@ MWDECL const char* MwDefaultSubBackground; */ MWDECL const char* MwDefaultSubForeground; +/*! + * @brief Default title background color + */ +MWDECL const char* MwDefaultTitleBackground; + +/*! + * @brief Default title foreground color + */ +MWDECL const char* MwDefaultTitleForeground; + /*! * @brief Default dark theme background color */ @@ -52,6 +62,16 @@ MWDECL const char* MwDefaultDarkSubBackground; */ MWDECL const char* MwDefaultDarkSubForeground; +/*! + * @brief Default dark theme title background color + */ +MWDECL const char* MwDefaultDarkTitleBackground; + +/*! + * @brief Default dark theme title foreground color + */ +MWDECL const char* MwDefaultDarkTitleForeground; + /*! * @brief Default shadow difference */ diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index d8e01b100..67a53a42c 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -48,9 +48,10 @@ #define MwNtext "Stext" #define MwNbackground "Sbackground" #define MwNsubBackground "SsubBackground" +#define MwNtitleBackground "StitleBackground" #define MwNforeground "Sforeground" #define MwNsubForeground "SsubForeground" -#define MwNtitleBackground "StitleBackground" +#define MwNtitleForeground "StitleForeground" #define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanLayer "SEvulkanLayer" diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index c3b86e08d..f0b8cb84c 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -27,6 +27,7 @@ typedef struct _MwListBoxEntry MwListBoxEntry; typedef struct _MwTreeViewEntry MwTreeViewEntry; typedef struct _MwDirectoryEntry MwDirectoryEntry; typedef struct _MwBox* MwBox; +typedef struct _MwSubWindow* MwSubWindow; typedef struct _MwMouse MwMouse; #ifdef _MILSKO typedef struct _MwWidget* MwWidget; @@ -207,6 +208,13 @@ struct _MwBox { int layout; }; +struct _MwSubWindow { + MwWidget frame; + MwWidget minimize; + MwWidget maximize; + MwWidget close; +}; + struct _MwMouse { MwPoint point; int button; diff --git a/milsko.xml b/milsko.xml index e5165a4fb..94a68ac39 100644 --- a/milsko.xml +++ b/milsko.xml @@ -105,8 +105,10 @@ + + @@ -876,6 +878,12 @@ + + + + + + diff --git a/src/core.c b/src/core.c index cc0cdc4f9..b6343b909 100644 --- a/src/core.c +++ b/src/core.c @@ -591,7 +591,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) { } void MwSetText(MwWidget handle, const char* key, const char* value) { - if(strcmp(key, MwNtitle) == 0) { + if(handle->widget_class == MwWindowClass && strcmp(key, MwNtitle) == 0) { MwLLSetTitle(handle->lowlevel, value); } else { char* v = value == NULL ? NULL : MwStringDuplicate(value); @@ -686,12 +686,14 @@ int MwGetInteger(MwWidget handle, const char* key) { } const char* MwGetText(MwWidget handle, const char* key) { - if(shgeti(handle->text, key) == -1 && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0)) { + if((shgeti(handle->text, key) == -1 || strcmp(shget(handle->text, key), "DEFAULT") == 0) && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0 || strcmp(key, MwNtitleBackground) == 0 || strcmp(key, MwNtitleForeground) == 0)) { const char* v = NULL; - MwWidget h = handle->parent; - while(h != NULL) { - if((v = MwGetText(h, key)) != NULL) break; - h = h->parent; + if(shgeti(handle->text, key) != -1 && strcmp(shget(handle->text, key), "DEFAULT") != 0) { + MwWidget h = handle->parent; + while(h != NULL) { + if((v = MwGetText(h, key)) != NULL) break; + h = h->parent; + } } if(v == NULL) { if(MwGetInteger(handle, MwNdarkTheme)) { @@ -699,11 +701,15 @@ const char* MwGetText(MwWidget handle, const char* key) { if(strcmp(key, MwNforeground) == 0) return MwDefaultDarkForeground; if(strcmp(key, MwNsubBackground) == 0) return MwDefaultDarkSubBackground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultDarkSubForeground; + if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultDarkTitleBackground; + if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultDarkTitleForeground; } else { if(strcmp(key, MwNbackground) == 0) return MwDefaultBackground; if(strcmp(key, MwNforeground) == 0) return MwDefaultForeground; if(strcmp(key, MwNsubBackground) == 0) return MwDefaultSubBackground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultSubForeground; + if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultTitleBackground; + if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultTitleForeground; } } return v; diff --git a/src/default.c b/src/default.c index 36537a183..a1acbd09e 100644 --- a/src/default.c +++ b/src/default.c @@ -1,14 +1,18 @@ #include -const char* MwDefaultBackground = "#d2d2d2"; -const char* MwDefaultForeground = "#000"; -const char* MwDefaultSubBackground = "#fff"; -const char* MwDefaultSubForeground = "#000"; +const char* MwDefaultBackground = "#d2d2d2"; +const char* MwDefaultForeground = "#000"; +const char* MwDefaultSubBackground = "#fff"; +const char* MwDefaultSubForeground = "#000"; +const char* MwDefaultTitleBackground = "#008"; +const char* MwDefaultTitleForeground = "#fff"; -const char* MwDefaultDarkBackground = "#333"; -const char* MwDefaultDarkForeground = "#ddd"; -const char* MwDefaultDarkSubBackground = "#333"; -const char* MwDefaultDarkSubForeground = "#ddd"; +const char* MwDefaultDarkBackground = "#333"; +const char* MwDefaultDarkForeground = "#ddd"; +const char* MwDefaultDarkSubBackground = "#333"; +const char* MwDefaultDarkSubForeground = "#ddd"; +const char* MwDefaultDarkTitleBackground = "#008"; +const char* MwDefaultDarkTitleForeground = "#fff"; const int MwDefaultShadow = -32; diff --git a/src/widget/subwindow.c b/src/widget/subwindow.c index 16594987d..61cc9f8b7 100644 --- a/src/widget/subwindow.c +++ b/src/widget/subwindow.c @@ -1,19 +1,82 @@ #include #define TitleHeight 20 +#define ButtonSize 18 + +static void resize(MwWidget handle){ + MwSubWindow sw = handle->internal; + int x, y, w, h; + int ww = MwGetInteger(handle, MwNwidth); + int wh = MwGetInteger(handle, MwNheight); + int bw = MwDefaultBorderWidth(handle); + int p; + + x = bw * 2; + y = bw * 2 + TitleHeight; + w = ww - bw * 4; + h = wh - bw * 4 - TitleHeight; + if(sw->frame == NULL){ + sw->frame = MwCreateWidget(MwFrameClass, "frame", handle, x, y, w, h); + }else{ + MwVaApply(sw->frame, + MwNx, x, + MwNy, y, + MwNwidth, w, + MwNheight, h, + NULL); + } + + p = (TitleHeight - ButtonSize) / 2; + x = ww - bw - p; + y = bw + p; + w = ButtonSize; + h = ButtonSize; + +#define BUTTON(name) \ + x -= ButtonSize; \ + if(sw->name == NULL){ \ + sw->name = MwCreateWidget(MwButtonClass, #name, handle, x, y, w, h); \ + }else{ \ + MwVaApply(sw->name, \ + MwNx, x, \ + MwNy, y, \ + MwNwidth, w, \ + MwNheight, h, \ + NULL); \ + } \ + x -= p; + + BUTTON(close); + BUTTON(maximize); + BUTTON(minimize); + + MwSetText(sw->frame, MwNbackground, "#f00"); +} static int wcreate(MwWidget handle) { - MwSetDefault(handle); + MwSubWindow sw = malloc(sizeof(*sw)); + memset(sw, 0, sizeof(*sw)); - MwSetText(handle, MwNtitleBackground, "#008"); + handle->internal = sw; + + resize(handle); + + MwSetDefault(handle); return 0; } +static void destroy(MwWidget handle) { + MwSubWindow sw = handle->internal; + free(handle->internal); +} + static void draw(MwWidget handle) { MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor c2 = MwParseColor(handle, MwGetText(handle, MwNtitleBackground)); + MwLLColor tb = MwParseColor(handle, MwGetText(handle, MwNtitleBackground)); + MwLLColor tf = MwParseColor(handle, MwGetText(handle, MwNtitleForeground)); MwRect r, r2; + const char* title = MwGetText(handle, MwNtitle); r.x = 0; r.y = 0; @@ -25,13 +88,23 @@ static void draw(MwWidget handle) { r2 = r; r2.height = TitleHeight; - MwDrawRect(handle, &r2, c2); + MwDrawRect(handle, &r2, tb); + + if(title != NULL){ + MwPoint p; + p.x = r2.x + (TitleHeight - ButtonSize); + p.y = r2.y + TitleHeight / 2; + handle->bgcolor = tb; + MwDrawText(handle, NULL, &p, title, MwALIGNMENT_BEGINNING, tf); + handle->bgcolor = NULL; + } r.y += TitleHeight; r.height -= TitleHeight; MwDrawFrame(handle, &r, c, 1); - MwLLFreeColor(c2); + MwLLFreeColor(tf); + MwLLFreeColor(tb); MwLLFreeColor(c); } @@ -45,7 +118,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v MwClassRec MwSubWindowClassRec = { wcreate, /* create */ - NULL, /* destroy */ + destroy, /* destroy */ draw, /* draw */ NULL, /* click */ NULL, /* parent_resize */