diff --git a/examples/basic/tab.c b/examples/basic/tab.c
index 8b0ad4a..8ae16c0 100644
--- a/examples/basic/tab.c
+++ b/examples/basic/tab.c
@@ -31,6 +31,10 @@ int main() {
MwTabAdd(tab, buf);
}
+ MwVaApply(MwTabGetFrame(tab, "Tab 1"),
+ MwNiconPixmap, MwLoadIcon(tab, MwIconWarning),
+ NULL);
+
MwAddUserHandler(w, MwNresizeHandler, resize, NULL);
resize(w, NULL, NULL);
diff --git a/include/Mw/Widget/Tab.h b/include/Mw/Widget/Tab.h
index ea30023..9f80a0d 100644
--- a/include/Mw/Widget/Tab.h
+++ b/include/Mw/Widget/Tab.h
@@ -42,6 +42,16 @@ MwInline MwWidget MwTabGetFrame(MwWidget handle, const char* name) {
return out;
}
+/*!
+ * @brief Focus on a tab frame
+ * @param handle Widget
+ * @param name Tab name
+ * @return Frame
+ */
+MwInline void MwTabFocus(MwWidget handle, const char* name) {
+ MwVaWidgetExecute(handle, "mwTabFocus", NULL, name);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/milsko.xml b/milsko.xml
index 837934e..a94c847 100644
--- a/milsko.xml
+++ b/milsko.xml
@@ -668,6 +668,7 @@
+
@@ -961,6 +962,11 @@
+
+
+
+
+
diff --git a/src/core.c b/src/core.c
index 0db801f..c081950 100644
--- a/src/core.c
+++ b/src/core.c
@@ -569,10 +569,13 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
arrput(keys, NULL);
MwDispatch3(handle, props_change, keys);
arrfree(keys);
+ }
+ if(handle->parent != NULL && handle->parent->prop_event) {
MwDispatch3(handle, prop_change, key);
if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key);
}
+
if(strcmp(key, MwNforceInverted) == 0) {
MwForceRender(handle);
}
@@ -614,10 +617,13 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
arrput(keys, NULL);
MwDispatch3(handle, props_change, keys);
arrfree(keys);
+ }
+ if(handle->parent != NULL && handle->parent->prop_event) {
MwDispatch3(handle, prop_change, key);
if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key);
}
+
if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) {
MwForceRender(handle);
}
@@ -642,7 +648,9 @@ void MwSetVoid(MwWidget handle, const char* key, void* value) {
arrput(keys, NULL);
MwDispatch3(handle, props_change, keys);
arrfree(keys);
+ }
+ if(handle->parent != NULL && handle->parent->prop_event) {
MwDispatch3(handle, prop_change, key);
if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key);
}
diff --git a/src/widget/tab.c b/src/widget/tab.c
index e779bd5..f8eda14 100644
--- a/src/widget/tab.c
+++ b/src/widget/tab.c
@@ -39,6 +39,23 @@ static int tab_height(MwWidget handle) {
return MwTextHeight(handle, NULL, "M") + 10;
}
+static int icon_width(MwWidget handle, const char* text) {
+ MwTab t = handle->internal;
+ int i;
+
+ for(i = 0; i < arrlen(t->names); i++) {
+ if(strcmp(t->names[i], text) == 0) {
+ MwLLPixmap px = MwGetVoid(t->frames[i], MwNiconPixmap);
+
+ if(px == NULL) return 0;
+
+ return px->common.width * tab_height(handle) / px->common.height;
+ }
+ }
+
+ return 0;
+}
+
static void draw(MwWidget handle) {
MwTab t = handle->internal;
MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground));
@@ -60,6 +77,7 @@ static void draw(MwWidget handle) {
x = 0;
for(i = 0; i < arrlen(t->names); i++) {
int render = 0;
+ int iw = icon_width(handle, t->names[i]);
if(i == MwGetInteger(handle, MwNvalue) && n == 1) {
r.y += h;
@@ -73,11 +91,26 @@ static void draw(MwWidget handle) {
r2.x = x;
r2.y = 0;
- r2.width = tab_width(handle, t->names[i]);
+ r2.width = tab_width(handle, t->names[i]) + iw;
r2.height = tab_height(handle) + MwDefaultBorderWidth(handle);
x += r2.width;
+ if(iw > 0) {
+ MwLLPixmap px = MwGetVoid(t->frames[i], MwNiconPixmap);
+ MwRect rp;
+
+ rp = r2;
+
+ rp.x += 5;
+ rp.y += 5;
+
+ rp.width = iw - 10;
+ rp.height = rp.height * (iw - 10) / iw;
+
+ MwLLDrawPixmap(handle->lowlevel, &rp, px);
+ }
+
if(render) {
MwPoint p;
@@ -151,7 +184,7 @@ static void draw(MwWidget handle) {
MwDrawRect(handle, &r3, c);
}
- p.x = r2.x + r2.width / 2;
+ p.x = r2.x + (r2.width + iw / 2) / 2;
p.y = r2.y + r2.height / 2;
MwDrawText(handle, NULL, &p, t->names[i], MwALIGNMENT_CENTER, ct);
}
@@ -177,7 +210,10 @@ static void click(MwWidget handle) {
int h = tab_height(handle);
for(i = 0; i < arrlen(t->names); i++) {
- int w = tab_width(handle, t->names[i]);
+ int w = tab_width(handle, t->names[i]);
+ int iw = icon_width(handle, t->names[i]);
+
+ w += iw;
if(MwGetInteger(handle, MwNvalue) != i && x <= handle->mouse_point.x && handle->mouse_point.x <= (x + w) && 0 <= handle->mouse_point.y && handle->mouse_point.y <= h) {
MwSetInteger(handle, MwNvalue, i);
@@ -188,6 +224,12 @@ static void click(MwWidget handle) {
}
}
+static void prop_change(MwWidget handle, const char* key) {
+ if(strcmp(key, MwNvalue) == 0) {
+ show_frame(handle);
+ }
+}
+
static MwWidget mwTabAddImpl(MwWidget handle, const char* name) {
MwTab t = handle->internal;
MwWidget f = MwCreateWidget(MwFrameClass, "tabframe", handle, MwDefaultBorderWidth(handle), tab_height(handle) + MwDefaultBorderWidth(handle), MwGetInteger(handle, MwNwidth) - MwDefaultBorderWidth(handle) * 2, MwGetInteger(handle, MwNheight) - tab_height(handle) - MwDefaultBorderWidth(handle) * 2);
@@ -219,6 +261,19 @@ static MwWidget mwTabGetFrameImpl(MwWidget handle, const char* name) {
return NULL;
}
+static void mwTabFocusImpl(MwWidget handle, const char* name) {
+ MwTab t = handle->internal;
+ int i;
+
+ for(i = 0; i < arrlen(t->names); i++) {
+ if(strcmp(t->names[i], name) == 0) {
+ MwSetInteger(handle, MwNvalue, i);
+ show_frame(handle);
+ break;
+ }
+ }
+}
+
static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
if(strcmp(name, "mwTabAdd") == 0) {
const char* name = va_arg(va, const char*);
@@ -228,6 +283,10 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
const char* name = va_arg(va, const char*);
*(MwWidget*)out = mwTabGetFrameImpl(handle, name);
+ } else if(strcmp(name, "mwTabFocus") == 0) {
+ const char* name = va_arg(va, const char*);
+
+ mwTabFocusImpl(handle, name);
}
}
@@ -251,24 +310,64 @@ static void resize(MwWidget handle) {
}
}
+static void children_update(MwWidget handle, MwWidget child, int new_child) {
+ MwTab t = handle->internal;
+ int v = MwGetInteger(handle, MwNvalue);
+ int c = v;
+ int n;
+ int i;
+
+ if(new_child) return;
+
+ for(i = 0; i < arrlen(t->frames); i++) {
+ if(t->frames[i] == child) {
+ n = i;
+ break;
+ }
+ }
+
+ free(t->names[n]);
+
+ arrdel(t->frames, n);
+ arrdel(t->names, n);
+
+ if(n <= v) {
+ if(v > 0) v--;
+
+ MwSetInteger(handle, MwNvalue, v);
+ show_frame(handle);
+ } else {
+ MwSetInteger(handle, MwNvalue, v);
+ show_frame(handle);
+ }
+
+ MwForceRender(handle);
+}
+
+static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
+ if(strcmp(key, MwNiconPixmap) == 0) {
+ MwForceRender(handle);
+ }
+}
+
MwClassRec MwTabClassRec = {
- wcreate, /* create */
- destroy, /* destroy */
- draw, /* draw */
- click, /* click */
- NULL, /* parent_resize */
- NULL, /* prop_change */
- NULL, /* mouse_move */
- NULL, /* mouse_up */
- NULL, /* mouse_down */
- NULL, /* key */
- func_handler, /* execute */
- NULL, /* tick */
- resize, /* resize */
- NULL, /* children_update */
- NULL, /* children_prop_change */
- NULL, /* clipboard */
- NULL, /* props_change */
+ wcreate, /* create */
+ destroy, /* destroy */
+ draw, /* draw */
+ click, /* click */
+ NULL, /* parent_resize */
+ prop_change, /* prop_change */
+ NULL, /* mouse_move */
+ NULL, /* mouse_up */
+ NULL, /* mouse_down */
+ NULL, /* key */
+ func_handler, /* execute */
+ NULL, /* tick */
+ resize, /* resize */
+ children_update, /* children_update */
+ children_prop_change, /* children_prop_change */
+ NULL, /* clipboard */
+ NULL, /* props_change */
NULL,
NULL,
NULL};