Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wbutton.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001
9d2e6ef9 scottc1998-09-29 22:36:29 +00002#include "WINGsP.h"
3
4typedef struct W_Button {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02005 W_Class widgetClass;
6 WMView *view;
9d2e6ef9 scottc1998-09-29 22:36:29 +00007
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02008 char *caption;
6830b057 dan2004-10-12 21:28:27 +00009
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020010 char *altCaption;
6830b057 dan2004-10-12 21:28:27 +000011
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020012 WMFont *font;
7f018497 kojima1999-04-24 20:08:20 +000013
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020014 WMColor *textColor;
15 WMColor *altTextColor;
16 WMColor *disTextColor;
dba6e4d2 dan2000-01-05 22:02:22 +000017
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020018 W_Pixmap *image;
19 W_Pixmap *altImage;
9d2e6ef9 scottc1998-09-29 22:36:29 +000020
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020021 W_Pixmap *dimage;
7f018497 kojima1999-04-24 20:08:20 +000022
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020023 void *clientData;
24 WMAction *action;
9d2e6ef9 scottc1998-09-29 22:36:29 +000025
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020026 int tag;
6830b057 dan2004-10-12 21:28:27 +000027
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020028 int groupIndex;
6830b057 dan2004-10-12 21:28:27 +000029
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020030 float periodicDelay;
31 float periodicInterval;
6830b057 dan2004-10-12 21:28:27 +000032
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020033 WMHandlerID *timer; /* for continuous mode */
6830b057 dan2004-10-12 21:28:27 +000034
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020035 struct {
36 WMButtonType type:4;
37 WMImagePosition imagePosition:4;
38 WMAlignment alignment:2;
9d2e6ef9 scottc1998-09-29 22:36:29 +000039
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020040 unsigned int selected:1;
4f84c48c dan2002-01-10 06:03:06 +000041
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020042 unsigned int enabled:1;
9d2e6ef9 scottc1998-09-29 22:36:29 +000043
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020044 unsigned int dimsWhenDisabled:1;
6e72c202 dan2002-03-29 01:24:12 +000045
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020046 unsigned int bordered:1;
9d2e6ef9 scottc1998-09-29 22:36:29 +000047
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020048 unsigned int springLoaded:1;
4f84c48c dan2002-01-10 06:03:06 +000049
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020050 unsigned int pushIn:1; /* change relief while pushed */
4f84c48c dan2002-01-10 06:03:06 +000051
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020052 unsigned int pushLight:1; /* highlight while pushed */
4f84c48c dan2002-01-10 06:03:06 +000053
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020054 unsigned int pushChange:1; /* change caption while pushed */
4f84c48c dan2002-01-10 06:03:06 +000055
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020056 unsigned int stateLight:1; /* state indicated by highlight */
4f84c48c dan2002-01-10 06:03:06 +000057
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020058 unsigned int stateChange:1; /* state indicated by caption change */
9d2e6ef9 scottc1998-09-29 22:36:29 +000059
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020060 unsigned int statePush:1; /* state indicated by relief */
9d2e6ef9 scottc1998-09-29 22:36:29 +000061
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020062 unsigned int continuous:1; /* continually perform action */
4f84c48c dan2002-01-10 06:03:06 +000063
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020064 unsigned int prevSelected:1;
9d2e6ef9 scottc1998-09-29 22:36:29 +000065
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020066 unsigned int pushed:1;
4f84c48c dan2002-01-10 06:03:06 +000067
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020068 unsigned int wasPushed:1;
9d2e6ef9 scottc1998-09-29 22:36:29 +000069
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020070 unsigned int redrawPending:1;
4f84c48c dan2002-01-10 06:03:06 +000071
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020072 unsigned int addedObserver:1;
73 } flags;
9d2e6ef9 scottc1998-09-29 22:36:29 +000074} Button;
75
9d2e6ef9 scottc1998-09-29 22:36:29 +000076#define DEFAULT_BUTTON_WIDTH 60
77#define DEFAULT_BUTTON_HEIGHT 24
78#define DEFAULT_BUTTON_ALIGNMENT WACenter
79#define DEFAULT_BUTTON_IS_BORDERED True
80
9d2e6ef9 scottc1998-09-29 22:36:29 +000081#define DEFAULT_RADIO_WIDTH 100
82#define DEFAULT_RADIO_HEIGHT 20
83#define DEFAULT_RADIO_ALIGNMENT WALeft
84#define DEFAULT_RADIO_IMAGE_POSITION WIPLeft
85#define DEFAULT_RADIO_TEXT "Radio"
86
9d2e6ef9 scottc1998-09-29 22:36:29 +000087#define DEFAULT_SWITCH_WIDTH 100
88#define DEFAULT_SWITCH_HEIGHT 20
89#define DEFAULT_SWITCH_ALIGNMENT WALeft
90#define DEFAULT_SWITCH_IMAGE_POSITION WIPLeft
91#define DEFAULT_SWITCH_TEXT "Switch"
92
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020093static void destroyButton(Button * bPtr);
94static void paintButton(Button * bPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000095
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020096static void handleEvents(XEvent * event, void *data);
97static void handleActionEvents(XEvent * event, void *data);
9d2e6ef9 scottc1998-09-29 22:36:29 +000098
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020099static char *WMPushedRadioNotification = "WMPushedRadioNotification";
9d2e6ef9 scottc1998-09-29 22:36:29 +0000100
101#define NFONT(b) (b)->view->screen->normalFont
102
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200103WMButton *WMCreateCustomButton(WMWidget * parent, int behaviourMask)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000104{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200105 Button *bPtr;
6830b057 dan2004-10-12 21:28:27 +0000106
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200107 bPtr = wmalloc(sizeof(Button));
108 memset(bPtr, 0, sizeof(Button));
9d2e6ef9 scottc1998-09-29 22:36:29 +0000109
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200110 bPtr->widgetClass = WC_Button;
6830b057 dan2004-10-12 21:28:27 +0000111
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200112 bPtr->view = W_CreateView(W_VIEW(parent));
113 if (!bPtr->view) {
114 wfree(bPtr);
115 return NULL;
116 }
117 bPtr->view->self = bPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000118
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200119 bPtr->flags.type = 0;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000120
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200121 bPtr->flags.springLoaded = (behaviourMask & WBBSpringLoadedMask) != 0;
122 bPtr->flags.pushIn = (behaviourMask & WBBPushInMask) != 0;
123 bPtr->flags.pushChange = (behaviourMask & WBBPushChangeMask) != 0;
124 bPtr->flags.pushLight = (behaviourMask & WBBPushLightMask) != 0;
125 bPtr->flags.stateLight = (behaviourMask & WBBStateLightMask) != 0;
126 bPtr->flags.stateChange = (behaviourMask & WBBStateChangeMask) != 0;
127 bPtr->flags.statePush = (behaviourMask & WBBStatePushMask) != 0;
6e72c202 dan2002-03-29 01:24:12 +0000128
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200129 W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
130 bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
131 bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000132
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200133 bPtr->flags.enabled = 1;
134 bPtr->flags.dimsWhenDisabled = 1;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000135
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200136 WMCreateEventHandler(bPtr->view, ExposureMask | StructureNotifyMask, handleEvents, bPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000137
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200138 WMCreateEventHandler(bPtr->view, ButtonPressMask | ButtonReleaseMask
139 | EnterWindowMask | LeaveWindowMask, handleActionEvents, bPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000140
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200141 W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
142 bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
143 bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000144
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200145 return bPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000146}
147
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200148WMButton *WMCreateButton(WMWidget * parent, WMButtonType type)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000149{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200150 W_Screen *scrPtr = W_VIEW(parent)->screen;
151 Button *bPtr;
6830b057 dan2004-10-12 21:28:27 +0000152
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200153 switch (type) {
154 case WBTMomentaryPush:
155 bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask | WBBPushInMask | WBBPushLightMask);
156 break;
6830b057 dan2004-10-12 21:28:27 +0000157
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200158 case WBTMomentaryChange:
159 bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask | WBBPushChangeMask);
160 break;
6830b057 dan2004-10-12 21:28:27 +0000161
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200162 case WBTPushOnPushOff:
163 bPtr = WMCreateCustomButton(parent, WBBPushInMask | WBBStatePushMask | WBBStateLightMask);
164 break;
6830b057 dan2004-10-12 21:28:27 +0000165
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200166 case WBTToggle:
167 bPtr = WMCreateCustomButton(parent, WBBPushInMask | WBBStateChangeMask | WBBStatePushMask);
168 break;
6830b057 dan2004-10-12 21:28:27 +0000169
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200170 case WBTOnOff:
171 bPtr = WMCreateCustomButton(parent, WBBStateLightMask);
172 break;
6830b057 dan2004-10-12 21:28:27 +0000173
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200174 case WBTSwitch:
175 bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
176 bPtr->flags.bordered = 0;
177 bPtr->image = WMRetainPixmap(scrPtr->checkButtonImageOff);
178 bPtr->altImage = WMRetainPixmap(scrPtr->checkButtonImageOn);
179 break;
6830b057 dan2004-10-12 21:28:27 +0000180
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200181 case WBTRadio:
182 bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
183 bPtr->flags.bordered = 0;
184 bPtr->image = WMRetainPixmap(scrPtr->radioButtonImageOff);
185 bPtr->altImage = WMRetainPixmap(scrPtr->radioButtonImageOn);
186 break;
6830b057 dan2004-10-12 21:28:27 +0000187
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200188 default:
189 case WBTMomentaryLight:
190 bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask | WBBPushLightMask);
191 bPtr->flags.bordered = 1;
192 break;
193 }
6830b057 dan2004-10-12 21:28:27 +0000194
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200195 bPtr->flags.type = type;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000196
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200197 if (type == WBTRadio) {
198 W_ResizeView(bPtr->view, DEFAULT_RADIO_WIDTH, DEFAULT_RADIO_HEIGHT);
199 WMSetButtonText(bPtr, DEFAULT_RADIO_TEXT);
200 bPtr->flags.alignment = DEFAULT_RADIO_ALIGNMENT;
201 bPtr->flags.imagePosition = DEFAULT_RADIO_IMAGE_POSITION;
202 } else if (type == WBTSwitch) {
203 W_ResizeView(bPtr->view, DEFAULT_SWITCH_WIDTH, DEFAULT_SWITCH_HEIGHT);
204 WMSetButtonText(bPtr, DEFAULT_SWITCH_TEXT);
205 bPtr->flags.alignment = DEFAULT_SWITCH_ALIGNMENT;
206 bPtr->flags.imagePosition = DEFAULT_SWITCH_IMAGE_POSITION;
207 }
6830b057 dan2004-10-12 21:28:27 +0000208
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200209 return bPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000210}
211
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200212static void updateDisabledMask(WMButton * bPtr)
7f018497 kojima1999-04-24 20:08:20 +0000213{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200214 WMScreen *scr = WMWidgetScreen(bPtr);
215 Display *dpy = scr->display;
7f018497 kojima1999-04-24 20:08:20 +0000216
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200217 if (bPtr->image) {
218 XGCValues gcv;
7f018497 kojima1999-04-24 20:08:20 +0000219
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200220 if (bPtr->dimage->mask) {
221 XFreePixmap(dpy, bPtr->dimage->mask);
222 bPtr->dimage->mask = None;
223 }
6e72c202 dan2002-03-29 01:24:12 +0000224
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200225 if (bPtr->flags.dimsWhenDisabled) {
226 bPtr->dimage->mask = XCreatePixmap(dpy, scr->stipple,
227 bPtr->dimage->width, bPtr->dimage->height, 1);
6e72c202 dan2002-03-29 01:24:12 +0000228
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200229 XSetForeground(dpy, scr->monoGC, 0);
230 XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0,
231 bPtr->dimage->width, bPtr->dimage->height);
6e72c202 dan2002-03-29 01:24:12 +0000232
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200233 gcv.foreground = 1;
234 gcv.background = 0;
235 gcv.stipple = scr->stipple;
236 gcv.fill_style = FillStippled;
237 gcv.clip_mask = bPtr->image->mask;
238 gcv.clip_x_origin = 0;
239 gcv.clip_y_origin = 0;
6e72c202 dan2002-03-29 01:24:12 +0000240
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200241 XChangeGC(dpy, scr->monoGC, GCForeground | GCBackground | GCStipple
242 | GCFillStyle | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
6e72c202 dan2002-03-29 01:24:12 +0000243
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200244 XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0,
245 bPtr->dimage->width, bPtr->dimage->height);
6e72c202 dan2002-03-29 01:24:12 +0000246
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200247 gcv.fill_style = FillSolid;
248 gcv.clip_mask = None;
249 XChangeGC(dpy, scr->monoGC, GCFillStyle | GCClipMask, &gcv);
250 }
251 }
7f018497 kojima1999-04-24 20:08:20 +0000252}
253
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200254void WMSetButtonImageDefault(WMButton * bPtr)
052ab01c kojima1999-09-16 02:55:56 +0000255{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200256 WMSetButtonImage(bPtr, WMWidgetScreen(bPtr)->buttonArrow);
257 WMSetButtonAltImage(bPtr, WMWidgetScreen(bPtr)->pushedButtonArrow);
052ab01c kojima1999-09-16 02:55:56 +0000258}
7f018497 kojima1999-04-24 20:08:20 +0000259
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200260void WMSetButtonImage(WMButton * bPtr, WMPixmap * image)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000261{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200262 if (bPtr->image != NULL)
263 WMReleasePixmap(bPtr->image);
264 bPtr->image = WMRetainPixmap(image);
7f018497 kojima1999-04-24 20:08:20 +0000265
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200266 if (bPtr->dimage) {
267 bPtr->dimage->pixmap = None;
268 WMReleasePixmap(bPtr->dimage);
269 bPtr->dimage = NULL;
270 }
7f018497 kojima1999-04-24 20:08:20 +0000271
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200272 if (image) {
273 bPtr->dimage = WMCreatePixmapFromXPixmaps(WMWidgetScreen(bPtr),
274 image->pixmap, None,
275 image->width, image->height, image->depth);
276 updateDisabledMask(bPtr);
277 }
7f018497 kojima1999-04-24 20:08:20 +0000278
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200279 if (bPtr->view->flags.realized) {
280 paintButton(bPtr);
281 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000282}
283
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200284void WMSetButtonAltImage(WMButton * bPtr, WMPixmap * image)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000285{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200286 if (bPtr->altImage != NULL)
287 WMReleasePixmap(bPtr->altImage);
288 bPtr->altImage = WMRetainPixmap(image);
6830b057 dan2004-10-12 21:28:27 +0000289
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200290 if (bPtr->view->flags.realized) {
291 paintButton(bPtr);
292 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000293}
294
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200295void WMSetButtonImagePosition(WMButton * bPtr, WMImagePosition position)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000296{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200297 bPtr->flags.imagePosition = position;
6830b057 dan2004-10-12 21:28:27 +0000298
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200299 if (bPtr->view->flags.realized) {
300 paintButton(bPtr);
301 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000302}
303
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200304void WMSetButtonTextAlignment(WMButton * bPtr, WMAlignment alignment)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000305{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200306 bPtr->flags.alignment = alignment;
6830b057 dan2004-10-12 21:28:27 +0000307
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200308 if (bPtr->view->flags.realized) {
309 paintButton(bPtr);
310 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000311}
312
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200313void WMSetButtonText(WMButton * bPtr, char *text)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000314{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200315 if (bPtr->caption)
316 wfree(bPtr->caption);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000317
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200318 if (text != NULL) {
319 bPtr->caption = wstrdup(text);
320 } else {
321 bPtr->caption = NULL;
322 }
6830b057 dan2004-10-12 21:28:27 +0000323
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200324 if (bPtr->view->flags.realized) {
325 paintButton(bPtr);
326 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000327}
328
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200329void WMSetButtonAltText(WMButton * bPtr, char *text)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000330{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200331 if (bPtr->altCaption)
332 wfree(bPtr->altCaption);
6830b057 dan2004-10-12 21:28:27 +0000333
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200334 if (text != NULL) {
335 bPtr->altCaption = wstrdup(text);
336 } else {
337 bPtr->altCaption = NULL;
338 }
6830b057 dan2004-10-12 21:28:27 +0000339
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200340 if (bPtr->view->flags.realized) {
341 paintButton(bPtr);
342 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000343}
344
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200345void WMSetButtonTextColor(WMButton * bPtr, WMColor * color)
dba6e4d2 dan2000-01-05 22:02:22 +0000346{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200347 if (bPtr->textColor)
348 WMReleaseColor(bPtr->textColor);
dba6e4d2 dan2000-01-05 22:02:22 +0000349
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200350 bPtr->textColor = WMRetainColor(color);
dba6e4d2 dan2000-01-05 22:02:22 +0000351}
352
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200353void WMSetButtonAltTextColor(WMButton * bPtr, WMColor * color)
dba6e4d2 dan2000-01-05 22:02:22 +0000354{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200355 if (bPtr->altTextColor)
356 WMReleaseColor(bPtr->altTextColor);
dba6e4d2 dan2000-01-05 22:02:22 +0000357
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200358 bPtr->altTextColor = WMRetainColor(color);
dba6e4d2 dan2000-01-05 22:02:22 +0000359}
360
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200361void WMSetButtonDisabledTextColor(WMButton * bPtr, WMColor * color)
dba6e4d2 dan2000-01-05 22:02:22 +0000362{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200363 if (bPtr->disTextColor)
364 WMReleaseColor(bPtr->disTextColor);
dba6e4d2 dan2000-01-05 22:02:22 +0000365
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200366 bPtr->disTextColor = WMRetainColor(color);
dba6e4d2 dan2000-01-05 22:02:22 +0000367}
368
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200369void WMSetButtonSelected(WMButton * bPtr, int isSelected)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000370{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200371 bPtr->flags.selected = isSelected ? 1 : 0;
6830b057 dan2004-10-12 21:28:27 +0000372
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200373 if (bPtr->view->flags.realized) {
374 paintButton(bPtr);
375 }
376 if (bPtr->groupIndex > 0)
377 WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000378}
379
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200380int WMGetButtonSelected(WMButton * bPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000381{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200382 CHECK_CLASS(bPtr, WC_Button);
6830b057 dan2004-10-12 21:28:27 +0000383
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200384 return bPtr->flags.selected;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000385}
386
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200387void WMSetButtonBordered(WMButton * bPtr, int isBordered)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000388{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200389 bPtr->flags.bordered = isBordered;
6830b057 dan2004-10-12 21:28:27 +0000390
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200391 if (bPtr->view->flags.realized) {
392 paintButton(bPtr);
393 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000394}
395
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200396void WMSetButtonFont(WMButton * bPtr, WMFont * font)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000397{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200398 if (bPtr->font)
399 WMReleaseFont(bPtr->font);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000400
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200401 bPtr->font = WMRetainFont(font);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000402}
403
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200404void WMSetButtonEnabled(WMButton * bPtr, Bool flag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000405{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200406 bPtr->flags.enabled = ((flag == 0) ? 0 : 1);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000407
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200408 if (bPtr->view->flags.mapped) {
409 paintButton(bPtr);
410 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000411}
412
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200413int WMGetButtonEnabled(WMButton * bPtr)
6e72c202 dan2002-03-29 01:24:12 +0000414{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200415 CHECK_CLASS(bPtr, WC_Button);
6e72c202 dan2002-03-29 01:24:12 +0000416
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200417 return bPtr->flags.enabled;
6e72c202 dan2002-03-29 01:24:12 +0000418}
419
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200420void WMSetButtonImageDimsWhenDisabled(WMButton * bPtr, Bool flag)
6e72c202 dan2002-03-29 01:24:12 +0000421{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200422 bPtr->flags.dimsWhenDisabled = ((flag == 0) ? 0 : 1);
6e72c202 dan2002-03-29 01:24:12 +0000423
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200424 updateDisabledMask(bPtr);
6e72c202 dan2002-03-29 01:24:12 +0000425}
426
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200427void WMSetButtonTag(WMButton * bPtr, int tag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000428{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200429 bPtr->tag = tag;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000430}
431
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200432void WMPerformButtonClick(WMButton * bPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000433{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200434 CHECK_CLASS(bPtr, WC_Button);
6e72c202 dan2002-03-29 01:24:12 +0000435
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200436 if (!bPtr->flags.enabled)
437 return;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000438
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200439 bPtr->flags.pushed = 1;
440 bPtr->flags.selected = 1;
6830b057 dan2004-10-12 21:28:27 +0000441
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200442 if (bPtr->view->flags.mapped) {
443 paintButton(bPtr);
444 XFlush(WMScreenDisplay(WMWidgetScreen(bPtr)));
445 wusleep(20000);
446 }
6830b057 dan2004-10-12 21:28:27 +0000447
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200448 bPtr->flags.pushed = 0;
6830b057 dan2004-10-12 21:28:27 +0000449
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200450 if (bPtr->groupIndex > 0) {
451 WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
452 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000453
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200454 if (bPtr->action)
455 (*bPtr->action) (bPtr, bPtr->clientData);
6830b057 dan2004-10-12 21:28:27 +0000456
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200457 if (bPtr->view->flags.mapped)
458 paintButton(bPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000459}
460
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200461void WMSetButtonAction(WMButton * bPtr, WMAction * action, void *clientData)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000462{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200463 CHECK_CLASS(bPtr, WC_Button);
6830b057 dan2004-10-12 21:28:27 +0000464
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200465 bPtr->action = action;
6830b057 dan2004-10-12 21:28:27 +0000466
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200467 bPtr->clientData = clientData;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000468}
469
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200470static void radioPushObserver(void *observerData, WMNotification * notification)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000471{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200472 WMButton *bPtr = (WMButton *) observerData;
473 WMButton *pushedButton = (WMButton *) WMGetNotificationObject(notification);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000474
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200475 if (bPtr != pushedButton && pushedButton->groupIndex == bPtr->groupIndex && bPtr->groupIndex != 0) {
476 if (bPtr->flags.selected) {
477 bPtr->flags.selected = 0;
478 paintButton(bPtr);
479 }
480 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000481}
482
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200483void WMGroupButtons(WMButton * bPtr, WMButton * newMember)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000484{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200485 static int tagIndex = 0;
6830b057 dan2004-10-12 21:28:27 +0000486
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200487 CHECK_CLASS(bPtr, WC_Button);
488 CHECK_CLASS(newMember, WC_Button);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000489
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200490 if (!bPtr->flags.addedObserver) {
491 WMAddNotificationObserver(radioPushObserver, bPtr, WMPushedRadioNotification, NULL);
492 bPtr->flags.addedObserver = 1;
493 }
494 if (!newMember->flags.addedObserver) {
495 WMAddNotificationObserver(radioPushObserver, newMember, WMPushedRadioNotification, NULL);
496 newMember->flags.addedObserver = 1;
497 }
6830b057 dan2004-10-12 21:28:27 +0000498
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200499 if (bPtr->groupIndex == 0) {
500 bPtr->groupIndex = ++tagIndex;
501 }
502 newMember->groupIndex = bPtr->groupIndex;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000503}
504
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200505void WMSetButtonContinuous(WMButton * bPtr, Bool flag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000506{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200507 bPtr->flags.continuous = ((flag == 0) ? 0 : 1);
508 if (bPtr->timer) {
509 WMDeleteTimerHandler(bPtr->timer);
510 bPtr->timer = NULL;
511 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000512}
513
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200514void WMSetButtonPeriodicDelay(WMButton * bPtr, float delay, float interval)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000515{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200516 bPtr->periodicInterval = interval;
517 bPtr->periodicDelay = delay;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000518}
519
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200520static void paintButton(Button * bPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000521{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200522 W_Screen *scrPtr = bPtr->view->screen;
523 WMReliefType relief;
524 int offset;
525 char *caption;
526 WMPixmap *image;
527 WMColor *textColor;
528 WMColor *backColor;
dba6e4d2 dan2000-01-05 22:02:22 +0000529
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200530 backColor = NULL;
531 caption = bPtr->caption;
dba6e4d2 dan2000-01-05 22:02:22 +0000532
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200533 if (bPtr->flags.enabled) {
534 textColor = (bPtr->textColor != NULL ? bPtr->textColor : scrPtr->black);
535 } else {
536 textColor = (bPtr->disTextColor != NULL ? bPtr->disTextColor : scrPtr->darkGray);
537 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000538
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200539 if (bPtr->flags.enabled || !bPtr->dimage)
540 image = bPtr->image;
541 else
542 image = bPtr->dimage;
543 offset = 0;
544 if (bPtr->flags.bordered)
545 relief = WRRaised;
546 else
547 relief = WRFlat;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000548
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200549 if (bPtr->flags.selected) {
550 if (bPtr->flags.stateLight) {
551 backColor = scrPtr->white;
552 textColor = scrPtr->black;
553 }
d3609d34 kojima1999-04-25 21:43:50 +0000554
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200555 if (bPtr->flags.stateChange) {
556 if (bPtr->altCaption)
557 caption = bPtr->altCaption;
558 if (bPtr->altImage)
559 image = bPtr->altImage;
560 if (bPtr->altTextColor)
561 textColor = bPtr->altTextColor;
562 }
563
564 if (bPtr->flags.statePush && bPtr->flags.bordered) {
565 relief = WRSunken;
566 offset = 1;
567 }
568 }
569
570 if (bPtr->flags.pushed) {
571 if (bPtr->flags.pushIn) {
572 relief = WRPushed;
573 offset = 1;
574 }
575 if (bPtr->flags.pushLight) {
576 backColor = scrPtr->white;
577 textColor = scrPtr->black;
578 }
579
580 if (bPtr->flags.pushChange) {
581 if (bPtr->altCaption)
582 caption = bPtr->altCaption;
583 if (bPtr->altImage)
584 image = bPtr->altImage;
585 if (bPtr->altTextColor)
586 textColor = bPtr->altTextColor;
587 }
588 }
589
590 W_PaintTextAndImage(bPtr->view, True, textColor,
591 (bPtr->font != NULL ? bPtr->font : scrPtr->normalFont),
592 relief, caption, bPtr->flags.alignment, image,
593 bPtr->flags.imagePosition, backColor, offset);
594}
595
596static void handleEvents(XEvent * event, void *data)
597{
598 Button *bPtr = (Button *) data;
599
600 CHECK_CLASS(data, WC_Button);
601
602 switch (event->type) {
603 case Expose:
604 if (event->xexpose.count != 0)
605 break;
606 paintButton(bPtr);
607 break;
608
609 case DestroyNotify:
610 destroyButton(bPtr);
611 break;
612 }
613}
614
615static void autoRepeat(void *data)
616{
617 Button *bPtr = (Button *) data;
618
619 if (bPtr->action && bPtr->flags.pushed)
620 (*bPtr->action) (bPtr, bPtr->clientData);
621
622 bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicInterval * 1000), autoRepeat, bPtr);
623}
624
625static void handleActionEvents(XEvent * event, void *data)
626{
627 Button *bPtr = (Button *) data;
628 int doclick = 0, dopaint = 0;
629
630 CHECK_CLASS(data, WC_Button);
631
632 if (!bPtr->flags.enabled)
633 return;
634
635 switch (event->type) {
636 case EnterNotify:
637 if (bPtr->groupIndex == 0) {
638 bPtr->flags.pushed = bPtr->flags.wasPushed;
639 if (bPtr->flags.pushed) {
640 bPtr->flags.selected = !bPtr->flags.prevSelected;
641 dopaint = 1;
642 }
643 }
644 break;
645
646 case LeaveNotify:
647 if (bPtr->groupIndex == 0) {
648 bPtr->flags.wasPushed = bPtr->flags.pushed;
649 if (bPtr->flags.pushed) {
650 bPtr->flags.selected = bPtr->flags.prevSelected;
651 dopaint = 1;
652 }
653 bPtr->flags.pushed = 0;
654 }
655 break;
656
657 case ButtonPress:
658 if (event->xbutton.button == Button1) {
659 bPtr->flags.prevSelected = bPtr->flags.selected;
660 bPtr->flags.wasPushed = 0;
661 bPtr->flags.pushed = 1;
662 if (bPtr->groupIndex > 0) {
663 bPtr->flags.selected = 1;
664 dopaint = 1;
665 break;
666 }
667 bPtr->flags.selected = !bPtr->flags.selected;
668 dopaint = 1;
669
670 if (bPtr->flags.continuous && !bPtr->timer) {
671 bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicDelay * 1000),
672 autoRepeat, bPtr);
673 }
674 }
675 break;
676
677 case ButtonRelease:
678 if (event->xbutton.button == Button1) {
679 if (bPtr->flags.pushed) {
680 if (bPtr->groupIndex == 0 || (bPtr->flags.selected && bPtr->groupIndex > 0))
681 doclick = 1;
682 dopaint = 1;
683 if (bPtr->flags.springLoaded) {
684 bPtr->flags.selected = bPtr->flags.prevSelected;
685 }
686 }
687 bPtr->flags.pushed = 0;
688 }
689 if (bPtr->timer) {
690 WMDeleteTimerHandler(bPtr->timer);
691 bPtr->timer = NULL;
692 }
693 break;
694 }
d3609d34 kojima1999-04-25 21:43:50 +0000695
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200696 if (dopaint)
697 paintButton(bPtr);
698
699 if (doclick) {
700 if (bPtr->flags.selected && bPtr->groupIndex > 0) {
701 WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
702 }
703
704 if (bPtr->action)
705 (*bPtr->action) (bPtr, bPtr->clientData);
706 }
707}
708
709static void destroyButton(Button * bPtr)
710{
711 if (bPtr->flags.addedObserver) {
712 WMRemoveNotificationObserver(bPtr);
713 }
714
715 if (bPtr->timer)
716 WMDeleteTimerHandler(bPtr->timer);
717
718 if (bPtr->font)
719 WMReleaseFont(bPtr->font);
720
721 if (bPtr->caption)
722 wfree(bPtr->caption);
723
724 if (bPtr->altCaption)
725 wfree(bPtr->altCaption);
726
727 if (bPtr->textColor)
728 WMReleaseColor(bPtr->textColor);
729
730 if (bPtr->altTextColor)
731 WMReleaseColor(bPtr->altTextColor);
732
733 if (bPtr->disTextColor)
734 WMReleaseColor(bPtr->disTextColor);
735
736 if (bPtr->image)
737 WMReleasePixmap(bPtr->image);
738
739 if (bPtr->dimage) {
740 /* yuck.. kluge */
741 bPtr->dimage->pixmap = None;
742
743 WMReleasePixmap(bPtr->dimage);
744 }
745 if (bPtr->altImage)
746 WMReleasePixmap(bPtr->altImage);
747
748 wfree(bPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000749}