diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h index 47981744..5235c20f 100644 --- a/WINGs/WINGs/WINGs.h +++ b/WINGs/WINGs/WINGs.h @@ -26,7 +26,7 @@ #include #include -#define WINGS_H_VERSION 20141205 +#define WINGS_H_VERSION 20150508 #ifdef __cplusplus @@ -127,7 +127,8 @@ typedef enum { WBTRadio = 5, WBTMomentaryChange = 6, WBTOnOff = 7, - WBTMomentaryLight = 8 + WBTMomentaryLight = 8, + WBTTriState = 9 } WMButtonType; /* button behaviour masks */ diff --git a/WINGs/WINGs/WINGsP.h b/WINGs/WINGs/WINGsP.h index fc18b1cb..4cbe0fc2 100644 --- a/WINGs/WINGs/WINGsP.h +++ b/WINGs/WINGs/WINGsP.h @@ -268,6 +268,16 @@ typedef struct W_Screen { struct W_View *modalView; unsigned modalLoop:1; unsigned ignoreNextDoubleClick:1; + + /* + * New stuff in Window Maker 0.95.7 + * Added at the end of the structure to avoid breaking binary compatibility + * with previous versions of the toolkit + */ + W_Pixmap *tristateButtonImageOn; + W_Pixmap *tristateButtonImageOff; + W_Pixmap *tristateButtonImageTri; + } W_Screen; #define W_DRAWABLE(scr) (scr)->rcontext->drawable diff --git a/WINGs/wbutton.c b/WINGs/wbutton.c index 8c8e4dce..c8d78d97 100644 --- a/WINGs/wbutton.c +++ b/WINGs/wbutton.c @@ -17,6 +17,7 @@ typedef struct W_Button { W_Pixmap *image; W_Pixmap *altImage; + W_Pixmap *tsImage; W_Pixmap *dimage; @@ -37,7 +38,7 @@ typedef struct W_Button { WMImagePosition imagePosition:4; WMAlignment alignment:2; - unsigned int selected:1; + unsigned int selected:2; unsigned int enabled:1; @@ -183,6 +184,14 @@ WMButton *WMCreateButton(WMWidget * parent, WMButtonType type) bPtr->altImage = WMRetainPixmap(scrPtr->radioButtonImageOn); break; + case WBTTriState: + bPtr = WMCreateCustomButton(parent, WBBStateChangeMask); + bPtr->flags.bordered = 0; + bPtr->image = WMRetainPixmap(scrPtr->tristateButtonImageOff); + bPtr->altImage = WMRetainPixmap(scrPtr->tristateButtonImageOn); + bPtr->tsImage = WMRetainPixmap(scrPtr->tristateButtonImageTri); + break; + default: case WBTMomentaryLight: bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask | WBBPushLightMask); @@ -197,7 +206,7 @@ WMButton *WMCreateButton(WMWidget * parent, WMButtonType type) WMSetButtonText(bPtr, DEFAULT_RADIO_TEXT); bPtr->flags.alignment = DEFAULT_RADIO_ALIGNMENT; bPtr->flags.imagePosition = DEFAULT_RADIO_IMAGE_POSITION; - } else if (type == WBTSwitch) { + } else if (type == WBTSwitch || type == WBTTriState) { W_ResizeView(bPtr->view, DEFAULT_SWITCH_WIDTH, DEFAULT_SWITCH_HEIGHT); WMSetButtonText(bPtr, DEFAULT_SWITCH_TEXT); bPtr->flags.alignment = DEFAULT_SWITCH_ALIGNMENT; @@ -371,7 +380,10 @@ void WMSetButtonDisabledTextColor(WMButton * bPtr, WMColor * color) void WMSetButtonSelected(WMButton * bPtr, int isSelected) { - bPtr->flags.selected = isSelected ? 1 : 0; + if ((bPtr->flags.type == WBTTriState) && (isSelected < 0)) + bPtr->flags.selected = 2; + else + bPtr->flags.selected = isSelected ? 1 : 0; if (bPtr->view->flags.realized) { paintButton(bPtr); @@ -384,6 +396,9 @@ int WMGetButtonSelected(WMButton * bPtr) { CHECK_CLASS(bPtr, WC_Button); + if ((bPtr->flags.type == WBTTriState) && (bPtr->flags.selected == 2)) + return -1; + return bPtr->flags.selected; } @@ -558,7 +573,9 @@ static void paintButton(Button * bPtr) if (bPtr->flags.stateChange) { if (bPtr->altCaption) caption = bPtr->altCaption; - if (bPtr->altImage) + if (bPtr->flags.selected == 2) + image = bPtr->tsImage; + else if (bPtr->altImage) image = bPtr->altImage; if (bPtr->altTextColor) textColor = bPtr->altTextColor; @@ -659,6 +676,8 @@ static void handleActionEvents(XEvent * event, void *data) case ButtonPress: if (event->xbutton.button == Button1) { + static const unsigned int next_state[4] = { [0] = 1, [1] = 2, [2] = 0 }; + bPtr->flags.prevSelected = bPtr->flags.selected; bPtr->flags.wasPushed = 0; bPtr->flags.pushed = 1; @@ -667,7 +686,10 @@ static void handleActionEvents(XEvent * event, void *data) dopaint = 1; break; } - bPtr->flags.selected = !bPtr->flags.selected; + if (bPtr->flags.type == WBTTriState) + bPtr->flags.selected = next_state[bPtr->flags.selected]; + else + bPtr->flags.selected = !bPtr->flags.selected; dopaint = 1; if (bPtr->flags.continuous && !bPtr->timer) { @@ -748,5 +770,8 @@ static void destroyButton(Button * bPtr) if (bPtr->altImage) WMReleasePixmap(bPtr->altImage); + if (bPtr->tsImage) + WMReleasePixmap(bPtr->tsImage); + wfree(bPtr); } diff --git a/WINGs/widgets.c b/WINGs/widgets.c index 4c9c687f..177ad3ca 100644 --- a/WINGs/widgets.c +++ b/WINGs/widgets.c @@ -97,6 +97,66 @@ static char *RADIO_BUTTON_OFF[] = { "..... .....", }; +#define TRISTATE_BUTTON_ON_WIDTH 15 +#define TRISTATE_BUTTON_ON_HEIGHT 15 +static char *TRISTATE_BUTTON_ON[] = { + "%%%%%%%%%%%%%%.", + "%%%%%%%%%%%%%. ", + "%% . ", + "%% ## ## . ", + "%% ### ### . ", + "%% ### ### . ", + "%% ##### . ", + "%% ### . ", + "%% ##### . ", + "%% ### ### . ", + "%% ### ### . ", + "%% ## ## . ", + "%% . ", + "%............. ", + ". ", +}; + +#define TRISTATE_BUTTON_OFF_WIDTH 15 +#define TRISTATE_BUTTON_OFF_HEIGHT 15 +static char *TRISTATE_BUTTON_OFF[] = { + "%%%%%%%%%%%%%%.", + "%%%%%%%%%%%%%. ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%% . ", + "%............. ", + ". ", +}; + +#define TRISTATE_BUTTON_TRI_WIDTH 15 +#define TRISTATE_BUTTON_TRI_HEIGHT 15 +static char *TRISTATE_BUTTON_TRI[] = { + "%%%%%%%%%%%%%%.", + "%%%%%%%%%%%%%. ", + "%% . ", + "%% # # # # # . ", + "%% # # # # . ", + "%% # # # # # . ", + "%% # # # # . ", + "%% # # # # # . ", + "%% # # # # . ", + "%% # # # # # . ", + "%% # # # # . ", + "%% # # # # # . ", + "%% . ", + "%............. ", + ". ", +}; + static char *BUTTON_ARROW[] = { "..................", "....##....#### ...", @@ -729,6 +789,15 @@ WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * c scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF, RADIO_BUTTON_OFF_WIDTH, RADIO_BUTTON_OFF_HEIGHT, False); + scrPtr->tristateButtonImageOn = makePixmap(scrPtr, TRISTATE_BUTTON_ON, + TRISTATE_BUTTON_ON_WIDTH, TRISTATE_BUTTON_ON_HEIGHT, False); + + scrPtr->tristateButtonImageOff = makePixmap(scrPtr, TRISTATE_BUTTON_OFF, + TRISTATE_BUTTON_OFF_WIDTH, TRISTATE_BUTTON_OFF_HEIGHT, False); + + scrPtr->tristateButtonImageTri = makePixmap(scrPtr, TRISTATE_BUTTON_TRI, + TRISTATE_BUTTON_TRI_WIDTH, TRISTATE_BUTTON_TRI_HEIGHT, False); + scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, False); scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2,