1 /********************************************************************************
2 *                                                                               *
3 *                   T o g g l e    B u t t o n    O b j e c t                   *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1998,2006 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or                 *
9 * modify it under the terms of the GNU Lesser General Public                    *
10 * License as published by the Free Software Foundation; either                  *
11 * version 2.1 of the License, or (at your option) any later version.            *
12 *                                                                               *
13 * This library is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
16 * Lesser General Public License for more details.                               *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public              *
19 * License along with this library; if not, write to the Free Software           *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
21 *********************************************************************************
22 * $Id: FXToggleButton.cpp 3297 2015-12-14 20:30:04Z arthurcnorman $                  *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "fxkeys.h"
28 #include "FXHash.h"
29 #include "FXThread.h"
30 #include "FXStream.h"
31 #include "FXString.h"
32 #include "FXSize.h"
33 #include "FXPoint.h"
34 #include "FXRectangle.h"
35 #include "FXRegistry.h"
36 #include "FXApp.h"
37 #include "FXAccelTable.h"
38 #include "FXDCWindow.h"
39 #include "FXIcon.h"
40 #include "FXToggleButton.h"
41 
42 
43 /*
44   Notes:
45   - If the altlabel is empty, the normal label will be used;
46     likewise for the icon.
47   - Setting the alt label will also change the alt hotkey.
48   - The fallback logic needs to be properly adhered to in the size computation.
49 */
50 
51 
52 // ToggleButton styles
53 #define TOGGLEBUTTON_MASK (TOGGLEBUTTON_AUTOGRAY|TOGGLEBUTTON_AUTOHIDE|TOGGLEBUTTON_TOOLBAR|TOGGLEBUTTON_KEEPSTATE)
54 
55 using namespace FX;
56 
57 /*******************************************************************************/
58 
59 namespace FX {
60 
61 // Map
62 FXDEFMAP(FXToggleButton) FXToggleButtonMap[]={
63   FXMAPFUNC(SEL_PAINT,0,FXToggleButton::onPaint),
64   FXMAPFUNC(SEL_UPDATE,0,FXToggleButton::onUpdate),
65   FXMAPFUNC(SEL_ENTER,0,FXToggleButton::onEnter),
66   FXMAPFUNC(SEL_LEAVE,0,FXToggleButton::onLeave),
67   FXMAPFUNC(SEL_FOCUSIN,0,FXToggleButton::onFocusIn),
68   FXMAPFUNC(SEL_FOCUSOUT,0,FXToggleButton::onFocusOut),
69   FXMAPFUNC(SEL_UNGRABBED,0,FXToggleButton::onUngrabbed),
70   FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,FXToggleButton::onLeftBtnPress),
71   FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,FXToggleButton::onLeftBtnRelease),
72   FXMAPFUNC(SEL_KEYPRESS,0,FXToggleButton::onKeyPress),
73   FXMAPFUNC(SEL_KEYRELEASE,0,FXToggleButton::onKeyRelease),
74   FXMAPFUNC(SEL_KEYPRESS,FXToggleButton::ID_HOTKEY,FXToggleButton::onHotKeyPress),
75   FXMAPFUNC(SEL_KEYRELEASE,FXToggleButton::ID_HOTKEY,FXToggleButton::onHotKeyRelease),
76   FXMAPFUNC(SEL_QUERY_TIP,0,FXToggleButton::onQueryTip),
77   FXMAPFUNC(SEL_QUERY_HELP,0,FXToggleButton::onQueryHelp),
78   FXMAPFUNC(SEL_COMMAND,FXToggleButton::ID_CHECK,FXToggleButton::onCheck),
79   FXMAPFUNC(SEL_COMMAND,FXToggleButton::ID_UNCHECK,FXToggleButton::onUncheck),
80   FXMAPFUNC(SEL_COMMAND,FXToggleButton::ID_SETVALUE,FXToggleButton::onCmdSetValue),
81   FXMAPFUNC(SEL_COMMAND,FXToggleButton::ID_SETINTVALUE,FXToggleButton::onCmdSetIntValue),
82   FXMAPFUNC(SEL_COMMAND,FXToggleButton::ID_GETINTVALUE,FXToggleButton::onCmdGetIntValue),
83   };
84 
85 
86 // Object implementation
FXIMPLEMENT(FXToggleButton,FXLabel,FXToggleButtonMap,ARRAYNUMBER (FXToggleButtonMap))87 FXIMPLEMENT(FXToggleButton,FXLabel,FXToggleButtonMap,ARRAYNUMBER(FXToggleButtonMap))
88 
89 
90 // Deserialization
91 FXToggleButton::FXToggleButton(){
92   alticon=(FXIcon*)-1L;
93   state=FALSE;
94   down=FALSE;
95   }
96 
97 
98 // Construct and init
FXToggleButton(FXComposite * p,const FXString & text1,const FXString & text2,FXIcon * icon1,FXIcon * icon2,FXObject * tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)99 FXToggleButton::FXToggleButton(FXComposite* p,const FXString& text1,const FXString& text2,FXIcon* icon1,FXIcon* icon2,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb):
100   FXLabel(p,text1,icon1,opts,x,y,w,h,pl,pr,pt,pb){
101   FXString string=text2.section('\t',0);
102   target=tgt;
103   message=sel;
104   altlabel=stripHotKey(string);
105   alttip=text2.section('\t',1);
106   althelp=text2.section('\t',2);
107   alticon=icon2;
108   althotkey=parseHotKey(string);
109   althotoff=findHotKey(string);
110   addHotKey(althotkey);
111   state=FALSE;
112   down=FALSE;
113   }
114 
115 
116 // Create window
create()117 void FXToggleButton::create(){
118   FXLabel::create();
119   if(alticon) alticon->create();
120   }
121 
122 
123 // Detach window
detach()124 void FXToggleButton::detach(){
125   FXLabel::detach();
126   if(alticon) alticon->detach();
127   }
128 
129 
130 // Get default width
getDefaultWidth()131 FXint FXToggleButton::getDefaultWidth(){
132   FXint tw,iw,s,w1,w2;
133 
134   tw=iw=s=0;
135   if(!label.empty()) tw=labelWidth(label);
136   if(icon) iw=icon->getWidth();
137   if(iw && tw) s=4;
138   if(!(options&(ICON_AFTER_TEXT|ICON_BEFORE_TEXT))) w1=FXMAX(tw,iw); else w1=tw+iw+s;
139 
140   if(!altlabel.empty()) tw=labelWidth(altlabel);
141   if(alticon) iw=alticon->getWidth();
142   if(iw && tw) s=4;
143   if(!(options&(ICON_AFTER_TEXT|ICON_BEFORE_TEXT))) w2=FXMAX(tw,iw); else w2=tw+iw+s;
144 
145   return FXMAX(w1,w2)+padleft+padright+(border<<1);
146   }
147 
148 
149 // Get default height
getDefaultHeight()150 FXint FXToggleButton::getDefaultHeight(){
151   FXint th,ih,h1,h2;
152 
153   th=ih=0;
154   if(!label.empty()) th=labelHeight(label);
155   if(icon) ih=icon->getHeight();
156   if(!(options&(ICON_ABOVE_TEXT|ICON_BELOW_TEXT))) h1=FXMAX(th,ih); else h1=th+ih;
157 
158   if(!altlabel.empty()) th=labelHeight(altlabel);
159   if(alticon) ih=alticon->getHeight();
160   if(!(options&(ICON_ABOVE_TEXT|ICON_BELOW_TEXT))) h2=FXMAX(th,ih); else h2=th+ih;
161 
162   return FXMAX(h1,h2)+padtop+padbottom+(border<<1);
163   }
164 
165 
166 // Set button state
setState(FXbool s,FXbool notify)167 void FXToggleButton::setState(FXbool s,FXbool notify){
168   if(state!=s){
169     state=s;
170     update();
171     if(notify && target){target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)state);}
172     }
173   }
174 
175 
176 // Press button
press(FXbool dn)177 void FXToggleButton::press(FXbool dn){
178   if(down!=dn){
179     down=dn;
180     update();
181     }
182   }
183 
184 
185 // If window can have focus
canFocus() const186 bool FXToggleButton::canFocus() const { return true; }
187 
188 
189 // Update value from a message
onCmdSetValue(FXObject *,FXSelector,void * ptr)190 long FXToggleButton::onCmdSetValue(FXObject*,FXSelector,void* ptr){
191   setState((FXint)(FXuval)ptr);
192   return 1;
193   }
194 
195 
196 // Update value from a message
onCmdSetIntValue(FXObject *,FXSelector,void * ptr)197 long FXToggleButton::onCmdSetIntValue(FXObject*,FXSelector,void* ptr){
198   setState(*((FXint*)ptr));
199   return 1;
200   }
201 
202 
203 // Obtain value from text field
onCmdGetIntValue(FXObject *,FXSelector,void * ptr)204 long FXToggleButton::onCmdGetIntValue(FXObject*,FXSelector,void* ptr){
205   *((FXint*)ptr)=getState();
206   return 1;
207   }
208 
209 
210 // Check the menu button
onCheck(FXObject *,FXSelector,void *)211 long FXToggleButton::onCheck(FXObject*,FXSelector,void*){
212   setState(TRUE);
213   return 1;
214   }
215 
216 
217 // Check the menu button
onUncheck(FXObject *,FXSelector,void *)218 long FXToggleButton::onUncheck(FXObject*,FXSelector,void*){
219   setState(FALSE);
220   return 1;
221   }
222 
223 
224 // Implement auto-hide or auto-gray modes
onUpdate(FXObject * sender,FXSelector sel,void * ptr)225 long FXToggleButton::onUpdate(FXObject* sender,FXSelector sel,void* ptr){
226   if(!FXLabel::onUpdate(sender,sel,ptr)){
227     if(options&TOGGLEBUTTON_AUTOHIDE){if(shown()){hide();recalc();}}
228     if(options&TOGGLEBUTTON_AUTOGRAY){disable();}
229     }
230   return 1;
231   }
232 
233 
234 // Gained focus
onFocusIn(FXObject * sender,FXSelector sel,void * ptr)235 long FXToggleButton::onFocusIn(FXObject* sender,FXSelector sel,void* ptr){
236   FXLabel::onFocusIn(sender,sel,ptr);
237   update(border,border,width-(border<<1),height-(border<<1));
238   return 1;
239   }
240 
241 
242 // Lost focus
onFocusOut(FXObject * sender,FXSelector sel,void * ptr)243 long FXToggleButton::onFocusOut(FXObject* sender,FXSelector sel,void* ptr){
244   FXLabel::onFocusOut(sender,sel,ptr);
245   update(border,border,width-(border<<1),height-(border<<1));
246   return 1;
247   }
248 
249 
250 // Entered button
onEnter(FXObject * sender,FXSelector sel,void * ptr)251 long FXToggleButton::onEnter(FXObject* sender,FXSelector sel,void* ptr){
252   FXLabel::onEnter(sender,sel,ptr);
253   if(isEnabled()){
254     if(flags&FLAG_PRESSED) press(TRUE);
255     if(options&TOGGLEBUTTON_TOOLBAR) update();
256     }
257   return 1;
258   }
259 
260 
261 // Left button
onLeave(FXObject * sender,FXSelector sel,void * ptr)262 long FXToggleButton::onLeave(FXObject* sender,FXSelector sel,void* ptr){
263   FXLabel::onLeave(sender,sel,ptr);
264   if(isEnabled()){
265     if(flags&FLAG_PRESSED) press(FALSE);
266     if(options&TOGGLEBUTTON_TOOLBAR) update();
267     }
268   return 1;
269   }
270 
271 
272 // Pressed mouse button
onLeftBtnPress(FXObject *,FXSelector,void * ptr)273 long FXToggleButton::onLeftBtnPress(FXObject*,FXSelector,void* ptr){
274   handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr);
275   flags&=~FLAG_TIP;
276   if(isEnabled() && !(flags&FLAG_PRESSED)){
277     grab();
278     if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) return 1;
279     press(TRUE);
280     flags|=FLAG_PRESSED;
281     flags&=~FLAG_UPDATE;
282     return 1;
283     }
284   return 0;
285   }
286 
287 
288 // Released mouse button
onLeftBtnRelease(FXObject *,FXSelector,void * ptr)289 long FXToggleButton::onLeftBtnRelease(FXObject*,FXSelector,void* ptr){
290   FXbool click=down;
291   if(isEnabled() && (flags&FLAG_PRESSED)){
292     ungrab();
293     flags|=FLAG_UPDATE;
294     flags&=~FLAG_PRESSED;
295     if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) return 1;
296     press(FALSE);
297     if(click){
298       setState(!state);
299       if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)state);
300       }
301     return 1;
302     }
303   return 0;
304   }
305 
306 
307 // The widget lost the grab for some reason
onUngrabbed(FXObject * sender,FXSelector sel,void * ptr)308 long FXToggleButton::onUngrabbed(FXObject* sender,FXSelector sel,void* ptr){
309   FXLabel::onUngrabbed(sender,sel,ptr);
310   press(FALSE);
311   flags&=~FLAG_PRESSED;
312   flags|=FLAG_UPDATE;
313   return 1;
314   }
315 
316 
317 // Key Press
onKeyPress(FXObject *,FXSelector,void * ptr)318 long FXToggleButton::onKeyPress(FXObject*,FXSelector,void* ptr){
319   FXEvent* event=(FXEvent*)ptr;
320   flags&=~FLAG_TIP;
321   if(isEnabled() && !(flags&FLAG_PRESSED)){
322     if(target && target->tryHandle(this,FXSEL(SEL_KEYPRESS,message),ptr)) return 1;
323     if(event->code==KEY_space || event->code==KEY_KP_Space){
324       press(TRUE);
325       flags|=FLAG_PRESSED;
326       flags&=~FLAG_UPDATE;
327       return 1;
328       }
329     }
330   return 0;
331   }
332 
333 
334 // Key Release
onKeyRelease(FXObject *,FXSelector,void * ptr)335 long FXToggleButton::onKeyRelease(FXObject*,FXSelector,void* ptr){
336   FXEvent* event=(FXEvent*)ptr;
337   if(isEnabled() && (flags&FLAG_PRESSED)){
338     if(target && target->tryHandle(this,FXSEL(SEL_KEYRELEASE,message),ptr)) return 1;
339     if(event->code==KEY_space || event->code==KEY_KP_Space){
340       press(FALSE);
341       setState(!state);
342       flags|=FLAG_UPDATE;
343       flags&=~FLAG_PRESSED;
344       if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)state);
345       return 1;
346       }
347     }
348   return 0;
349   }
350 
351 
352 // Hot key combination pressed
onHotKeyPress(FXObject *,FXSelector,void * ptr)353 long FXToggleButton::onHotKeyPress(FXObject*,FXSelector,void* ptr){
354   handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr);
355   flags&=~FLAG_TIP;
356   FXTRACE((100,"FXToggleButton::onHotKeyPress\n"));
357   if(isEnabled() && !(flags&FLAG_PRESSED)){
358     press(TRUE);
359     flags|=FLAG_PRESSED;
360     flags&=~FLAG_UPDATE;
361     }
362   return 1;
363   }
364 
365 
366 // Hot key combination released
onHotKeyRelease(FXObject *,FXSelector,void *)367 long FXToggleButton::onHotKeyRelease(FXObject*,FXSelector,void*){
368   FXTRACE((100,"FXToggleButton::onHotKeyRelease\n"));
369   if(isEnabled() && (flags&FLAG_PRESSED)){
370     flags|=FLAG_UPDATE;
371     flags&=~FLAG_PRESSED;
372     press(FALSE);
373     setState(!state);
374     if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)state);
375     }
376   return 1;
377   }
378 
379 
380 // We were asked about status text
onQueryHelp(FXObject * sender,FXSelector sel,void * ptr)381 long FXToggleButton::onQueryHelp(FXObject* sender,FXSelector sel,void* ptr){
382   if(FXWindow::onQueryHelp(sender,sel,ptr)) return 1;
383   if(flags&FLAG_HELP){
384     if(state){
385       if(!althelp.empty()){
386         sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&althelp);
387         return 1;
388         }
389       }
390     if(!help.empty()){
391       sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&help);
392       return 1;
393       }
394     }
395   return 0;
396   }
397 
398 
399 // We were asked about tip text
onQueryTip(FXObject * sender,FXSelector sel,void * ptr)400 long FXToggleButton::onQueryTip(FXObject* sender,FXSelector sel,void* ptr){
401   if(FXWindow::onQueryTip(sender,sel,ptr)) return 1;
402   if(flags&FLAG_TIP){
403     if(state){
404       if(!alttip.empty()){
405         sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&alttip);
406         return 1;
407         }
408       }
409     if(!tip.empty()){
410       sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&tip);
411       return 1;
412       }
413     }
414   return 0;
415   }
416 
417 
418 // Handle repaint
onPaint(FXObject *,FXSelector,void * ptr)419 long FXToggleButton::onPaint(FXObject*,FXSelector,void* ptr){
420   FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
421   FXEvent *ev=(FXEvent*)ptr;
422   FXDCWindow dc(this,ev);
423 
424   // Got a border at all?
425   if(options&(FRAME_RAISED|FRAME_SUNKEN)){
426 
427     // Toolbar style
428     if(options&TOGGLEBUTTON_TOOLBAR){
429 
430       // Enabled and cursor inside and down
431       if(down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)){
432         dc.setForeground(hiliteColor);
433         dc.fillRectangle(border,border,width-border*2,height-border*2);
434         if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height);
435         else drawSunkenRectangle(dc,0,0,width,height);
436         }
437 
438       // Enabled and cursor inside, and up
439       else if(isEnabled() && underCursor()){
440         dc.setForeground(backColor);
441         dc.fillRectangle(border,border,width-border*2,height-border*2);
442         if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
443         else drawRaisedRectangle(dc,0,0,width,height);
444         }
445 
446       // Disabled or unchecked or not under cursor
447       else{
448         dc.setForeground(backColor);
449         dc.fillRectangle(0,0,width,height);
450         }
451       }
452 
453     // Normal style
454     else{
455 
456       // Draw sunken if pressed
457       if(down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)){
458         dc.setForeground(hiliteColor);
459         dc.fillRectangle(border,border,width-border*2,height-border*2);
460         if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height);
461         else drawSunkenRectangle(dc,0,0,width,height);
462         }
463 
464       // Draw raised if not currently pressed down
465       else{
466         dc.setForeground(backColor);
467         dc.fillRectangle(border,border,width-border*2,height-border*2);
468         if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
469         else drawRaisedRectangle(dc,0,0,width,height);
470         }
471 
472       }
473     }
474 
475   // No borders
476   else{
477     dc.setForeground(backColor);
478     dc.fillRectangle(0,0,width,height);
479     }
480 
481   // Place text & icon
482   if(state && !altlabel.empty()){
483     tw=labelWidth(altlabel);
484     th=labelHeight(altlabel);
485     }
486   else if(!label.empty()){
487     tw=labelWidth(label);
488     th=labelHeight(label);
489     }
490   if(state && alticon){
491     iw=alticon->getWidth();
492     ih=alticon->getHeight();
493     }
494   else if(icon){
495     iw=icon->getWidth();
496     ih=icon->getHeight();
497     }
498 
499   just_x(tx,ix,tw,iw);
500   just_y(ty,iy,th,ih);
501 
502   // Shift a bit when pressed
503   if((down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)) && (options&(FRAME_RAISED|FRAME_SUNKEN))){ ++tx; ++ty; ++ix; ++iy; }
504 
505   // Draw enabled state
506   if(isEnabled()){
507     if(state && alticon){
508       dc.drawIcon(alticon,ix,iy);
509       }
510     else if(icon){
511       dc.drawIcon(icon,ix,iy);
512       }
513     if(state && !altlabel.empty()){
514       dc.setFont(font);
515       dc.setForeground(textColor);
516       drawLabel(dc,altlabel,althotoff,tx,ty,tw,th);
517       }
518     else if(!label.empty()){
519       dc.setFont(font);
520       dc.setForeground(textColor);
521       drawLabel(dc,label,hotoff,tx,ty,tw,th);
522       }
523     if(hasFocus()){
524       dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2);
525       }
526     }
527 
528   // Draw grayed-out state
529   else{
530     if(state && alticon){
531       dc.drawIconSunken(alticon,ix,iy);
532       }
533     else if(icon){
534       dc.drawIconSunken(icon,ix,iy);
535       }
536     if(state && !altlabel.empty()){
537       dc.setFont(font);
538       dc.setForeground(hiliteColor);
539       drawLabel(dc,altlabel,althotoff,tx+1,ty+1,tw,th);
540       dc.setForeground(shadowColor);
541       drawLabel(dc,altlabel,althotoff,tx,ty,tw,th);
542       }
543     else if(!label.empty()){
544       dc.setFont(font);
545       dc.setForeground(hiliteColor);
546       drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
547       dc.setForeground(shadowColor);
548       drawLabel(dc,label,hotoff,tx,ty,tw,th);
549       }
550     }
551   return 1;
552   }
553 
554 
555 // Change text
setAltText(const FXString & text)556 void FXToggleButton::setAltText(const FXString& text){
557   FXString string=stripHotKey(text);
558   FXHotKey hkey=parseHotKey(text);
559   FXint hoff=findHotKey(text);
560   if(altlabel!=string || althotkey!=hkey || althotoff!=hoff){
561     altlabel.adopt(string);
562     remHotKey(althotkey);
563     althotkey=hkey;
564     althotoff=hoff;
565     addHotKey(althotkey);
566     recalc();
567     update();
568     }
569   }
570 
571 
572 // Change icon
setAltIcon(FXIcon * ic)573 void FXToggleButton::setAltIcon(FXIcon* ic){
574   if(alticon!=ic){
575     alticon=ic;
576     recalc();
577     update();
578     }
579   }
580 
581 
582 // Change help text
setAltHelpText(const FXString & text)583 void FXToggleButton::setAltHelpText(const FXString& text){
584   althelp=text;
585   }
586 
587 
588 // Change tip text
setAltTipText(const FXString & text)589 void FXToggleButton::setAltTipText(const FXString& text){
590   alttip=text;
591   }
592 
593 
594 // Set icon positioning
setToggleStyle(FXuint style)595 void FXToggleButton::setToggleStyle(FXuint style){
596   FXuint opts=(options&~TOGGLEBUTTON_MASK) | (style&TOGGLEBUTTON_MASK);
597   if(options!=opts){
598     options=opts;
599     update();
600     }
601   }
602 
603 
604 // Get icon positioning
getToggleStyle() const605 FXuint FXToggleButton::getToggleStyle() const {
606   return (options&TOGGLEBUTTON_MASK);
607   }
608 
609 
610 // Save object to stream
save(FXStream & store) const611 void FXToggleButton::save(FXStream& store) const {
612   FXLabel::save(store);
613   store << altlabel;
614   store << alticon;
615   store << althotkey;
616   store << althotoff;
617   store << alttip;
618   store << althelp;
619   store << state;
620   }
621 
622 
623 
624 // Load object from stream
load(FXStream & store)625 void FXToggleButton::load(FXStream& store){
626   FXLabel::load(store);
627   store >> altlabel;
628   store >> alticon;
629   store >> althotkey;
630   store >> althotoff;
631   store >> alttip;
632   store >> althelp;
633   store >> state;
634   }
635 
636 
637 // Destruct
~FXToggleButton()638 FXToggleButton::~FXToggleButton(){
639   remHotKey(althotkey);
640   alticon=(FXIcon*)-1L;
641   }
642 
643 }
644