1 /* button.cc
2  * This file belongs to Worker, a file manager for UN*X/X11.
3  * Copyright (C) 2001-2019 Ralf Hoffmann.
4  * You can contact me at: ralf@boomerangsworld.de
5  *   or http://www.boomerangsworld.de/worker
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #include "button.h"
23 #include "awindow.h"
24 #include "guielement.h"
25 #include "drawablecont.hh"
26 #include "aicon.hh"
27 
28 const char *Button::type="Button";
29 
~Button()30 Button::~Button()
31 {
32   if(text[0]!=NULL) _freesafe(text[0]);
33   if(text[1]!=NULL) _freesafe(text[1]);
34 }
35 
Button(AGUIX * taguix,int tx,int ty,int width,const char * ttext,int tdata)36 Button::Button( AGUIX *taguix, int tx, int ty, int width,
37                 const char *ttext, int tdata ) : GUIElement( taguix )
38 {
39     int bw;
40 
41     init_class();
42 
43     bw = 2;
44 
45     _x = tx;
46     _y = ty;
47     if ( width > 0 ) _w = width;
48     _h = taguix->getCharHeight() + 2 * bw;
49 
50     applyFaces();
51 
52     data = tdata;
53     _freesafe( text[0] );
54     text[0] = dupstring( ttext );
55 }
56 
Button(AGUIX * taguix,int tx,int ty,const char * ttext,int tfg,int tbg,int tdata)57 Button::Button(AGUIX *taguix,int tx,int ty,
58                const char *ttext,int tfg,int tbg,int tdata):GUIElement(taguix)
59 {
60   int bw;
61 
62   init_class();
63 
64   bw = 2;
65 
66   _x = tx;
67   _y = ty;
68   _w = taguix->getTextWidth( ttext ) + taguix->getTextWidth( "  " );
69   _h = taguix->getCharHeight() + 2 * bw;
70 
71   data = tdata;
72   _freesafe( text[0] );
73   text[0] = dupstring( ttext );
74   fg[0] = tfg;
75   fg[1] = 0;
76   bg[0] = tbg;
77   bg[1] = 0;
78 
79   applyFaces();
80 }
81 
Button(AGUIX * taguix,int tx,int ty,const char * ttext,const std::string & tfg_name,const std::string & tbg_name,int tdata)82 Button::Button( AGUIX *taguix, int tx, int ty,
83                 const char *ttext,
84                 const std::string &tfg_name,
85                 const std::string &tbg_name,
86                 int tdata ) : GUIElement( taguix )
87 {
88     int bw;
89 
90     init_class();
91 
92     bw = 2;
93 
94     _x = tx;
95     _y = ty;
96     _w = taguix->getTextWidth( ttext ) + taguix->getTextWidth( "  " );
97     _h = taguix->getCharHeight() + 2 * bw;
98 
99     data = tdata;
100     _freesafe( text[0] );
101     text[0] = dupstring( ttext );
102     fg[0] = _aguix->getFaces().getColor( tfg_name );
103     fg[1] = 0;
104     bg[0] = _aguix->getFaces().getColor( tbg_name );
105     bg[1] = 0;
106 
107     applyFaces();
108 }
109 
110 
Button(AGUIX * taguix,int tx,int ty,const char * ttext,int tdata)111 Button::Button(AGUIX *taguix,int tx,int ty,
112                const char *ttext, int tdata ) : GUIElement( taguix )
113 {
114     int bw;
115 
116     init_class();
117 
118     bw = 2;
119 
120     _x = tx;
121     _y = ty;
122     _w = taguix->getTextWidth( ttext ) + taguix->getTextWidth( "  " );
123     _h = taguix->getCharHeight() + 2 * bw;
124 
125     data = tdata;
126     _freesafe( text[0] );
127     text[0] = dupstring( ttext );
128 
129     applyFaces();
130 }
131 
Button(AGUIX * taguix,int tx,int ty,int width,int height,const char * ttext,int tfg,int tbg,int tdata)132 Button::Button(AGUIX *taguix,int tx,int ty,int width,int height,
133                const char *ttext,int tfg,int tbg,int tdata):GUIElement(taguix)
134 {
135   init_class();
136 
137   _x = tx;
138   _y = ty;
139   if ( width > 0 ) _w = width;
140   if ( height > 0 ) _h = height;
141 
142   data = tdata;
143   _freesafe( text[0] );
144   text[0] = dupstring( ttext );
145   fg[0] = tfg;
146   fg[1] = 0;
147   bg[0] = tbg;
148   bg[1] = 0;
149 
150   applyFaces();
151 }
152 
Button(AGUIX * taguix,int tx,int ty,int width,int height,const char * ttext,int tdata)153 Button::Button(AGUIX *taguix,int tx,int ty,int width,int height,
154                const char *ttext, int tdata ) : GUIElement( taguix )
155 {
156     init_class();
157 
158     _x = tx;
159     _y = ty;
160     if ( width > 0 ) _w = width;
161     if ( height > 0 ) _h = height;
162 
163     data = tdata;
164     _freesafe( text[0] );
165     text[0] = dupstring( ttext );
166 
167     applyFaces();
168 }
169 
Button(AGUIX * taguix,int tx,int ty,int width,const char * text_normal,const char * text_high,int fg_normal,int fg_high,int bg_normal,int bg_high,int tdata)170 Button::Button(AGUIX *taguix,int tx,int ty,int width,
171                const char *text_normal,const char *text_high,
172                int fg_normal,int fg_high,
173                int bg_normal,int bg_high,int tdata):GUIElement(taguix)
174 {
175   int bw;
176 
177   init_class();
178 
179   bw = 2;
180 
181   _x = tx;
182   _y = ty;
183   if ( width > 0 ) _w = width;
184   _h = taguix->getCharHeight() + 2 * bw;
185 
186   dual = true;
187   data = tdata;
188   _freesafe( text[0] );
189   _freesafe( text[1] );
190   text[0] = dupstring( text_normal );
191   text[1] = dupstring( text_high );
192   fg[0] = fg_normal;
193   fg[1] = fg_high;
194   bg[0] = bg_normal;
195   bg[1] = bg_high;
196 
197   applyFaces();
198 }
199 
Button(AGUIX * taguix,int tx,int ty,int width,const char * text_normal,const char * text_high,int tdata)200 Button::Button(AGUIX *taguix,int tx,int ty,int width,
201                const char *text_normal,const char *text_high,
202                int tdata ) : GUIElement( taguix )
203 {
204     int bw;
205 
206     init_class();
207 
208     bw = 2;
209 
210     _x = tx;
211     _y = ty;
212     if ( width > 0 ) _w = width;
213     _h = taguix->getCharHeight() + 2 * bw;
214 
215     dual = true;
216     data = tdata;
217     _freesafe( text[0] );
218     _freesafe( text[1] );
219     text[0] = dupstring( text_normal );
220     text[1] = dupstring( text_high );
221 
222     applyFaces();
223 }
224 
Button(AGUIX * taguix,int tx,int ty,const char * text_normal,const char * text_high,int fg_normal,int fg_high,int bg_normal,int bg_high,int tdata)225 Button::Button( AGUIX *taguix, int tx, int ty,
226                 const char *text_normal, const char *text_high,
227                 int fg_normal, int fg_high,
228                 int bg_normal, int bg_high, int tdata ) : GUIElement( taguix )
229 {
230     int bw;
231 
232     init_class();
233 
234     bw = 2;
235 
236     _x = tx;
237     _y = ty;
238 
239     _w = taguix->getTextWidth( text_normal ) + taguix->getTextWidth( "  " );
240     int tw = taguix->getTextWidth( text_high ) + taguix->getTextWidth( "  " );
241     if ( tw > _w ) _w = tw;
242 
243     _h = taguix->getCharHeight() + 2 * bw;
244 
245     dual = true;
246     data = tdata;
247     _freesafe( text[0] );
248     _freesafe( text[1] );
249     text[0] = dupstring( text_normal );
250     text[1] = dupstring( text_high );
251     fg[0] = fg_normal;
252     fg[1] = fg_high;
253     bg[0] = bg_normal;
254     bg[1] = bg_high;
255 
256     applyFaces();
257 }
258 
Button(AGUIX * taguix,int tx,int ty,const char * text_normal,const char * text_high,int tdata)259 Button::Button( AGUIX *taguix, int tx, int ty,
260                 const char *text_normal, const char *text_high,
261                 int tdata ) : GUIElement( taguix )
262 {
263     int bw;
264 
265     init_class();
266 
267     bw = 2;
268 
269     _x = tx;
270     _y = ty;
271 
272     _w = taguix->getTextWidth( text_normal ) + taguix->getTextWidth( "  " );
273     int tw = taguix->getTextWidth( text_high ) + taguix->getTextWidth( "  " );
274     if ( tw > _w ) _w = tw;
275 
276     _h = taguix->getCharHeight() + 2 * bw;
277 
278     dual = true;
279     data = tdata;
280     _freesafe( text[0] );
281     _freesafe( text[1] );
282     text[0] = dupstring( text_normal );
283     text[1] = dupstring( text_high );
284 
285     applyFaces();
286 }
287 
getText(int index2) const288 const char *Button::getText(int index2) const
289 {
290   if((index2<0)||(index2>1)) return NULL;
291   return text[index2];
292 }
293 
setText(int index2,const char * new_text)294 void Button::setText(int index2,const char *new_text)
295 {
296   if((index2<0)||(index2>1)) return;
297   if(text[index2]!=NULL) _freesafe(text[index2]);
298   text[index2]=dupstring(new_text);
299   redraw();
300 }
301 
getDualState() const302 bool Button::getDualState() const
303 {
304   return dual;
305 }
306 
setDualState(bool new_dual)307 void Button::setDualState(bool new_dual)
308 {
309   dual=new_dual;
310   redraw();
311 }
312 
setFG(int index2,int tfg)313 void Button::setFG(int index2,int tfg)
314 {
315     if ( index2 < 0 || index2 > 1 ) return;
316     if ( tfg < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tfg >= 0 ) {
317         this->fg[index2] = tfg;
318     }
319     redraw();
320 }
321 
setFG(int index2,const std::string & fg_name)322 void Button::setFG( int index2, const std::string &fg_name)
323 {
324     if ( index2 < 0 || index2 > 1 ) return;
325 
326     int tfg = _aguix->getFaces().getColor( fg_name );
327     if ( tfg < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tfg >= 0 ) {
328         this->fg[index2] = tfg;
329     }
330     redraw();
331 }
332 
getFG(int index2) const333 int Button::getFG(int index2) const
334 {
335   if((index2<0)||(index2>1)) return 0;
336   return fg[index2];
337 }
338 
setBG(int index2,int tbg)339 void Button::setBG(int index2,int tbg)
340 {
341     if ( index2 < 0 || index2 > 1 ) return;
342     if ( tbg < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tbg >= 0 ) {
343         this->bg[index2] = tbg;
344     }
345     redraw();
346 }
347 
setBG(int index2,const std::string & bg_name)348 void Button::setBG( int index2, const std::string &bg_name)
349 {
350     if ( index2 < 0 || index2 > 1 ) return;
351 
352     int tbg = _aguix->getFaces().getColor( bg_name );
353     if ( tbg < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tbg >= 0 ) {
354         this->bg[index2] = tbg;
355     }
356     redraw();
357 }
358 
getBG(int index2) const359 int Button::getBG(int index2) const
360 {
361   if((index2<0)||(index2>1)) return 0;
362   return bg[index2];
363 }
364 
getData() const365 int Button::getData() const
366 {
367   return data;
368 }
369 
setData(int tdata)370 void Button::setData(int tdata)
371 {
372   this->data=tdata;
373 }
374 
redraw()375 void Button::redraw()
376 {
377   bool showe=false;
378   int px1 = 0,
379       py1 = 0,
380       px2 = 0,
381       py2 = 0,
382       px3 = 0,
383       py3 = 0;
384   int dw,dw2;
385   int dy;
386   char *tstr;
387   int ch;
388   int len, strwidth;
389   unsigned int ear_width = 0 ;
390   int bw;
391   int text_color;
392   int background;
393 
394   if ( isCreated() == false ) return;
395   if ( win == 0 ) return;
396 
397   // prepare window background depending on current state
398   prepareBG();
399 
400   /* Clear the window */
401   _aguix->ClearWin(win);
402 
403   /* calculate dimension of the turned-down corner */
404 
405   if ( ( dual == true ) && ( showdual == true ) && ( state != 2 ) ) {
406     showe = true;
407 
408     dw=_w/4;
409     dw2=(int)((double)(_h/3)*1.3);
410     if( dw2 < dw ) dw = dw2;
411 
412     ear_width = dw;
413 
414     px1 = _w-dw;
415     py1 = 0;
416     px2 = _w-dw;
417     py2 = dw-1;
418     px3 = _w-1;
419     py3 = dw-1;
420   }
421 
422   /* draw the text */
423 
424   if ( ( dual == false ) || ( state != 2 ) ) {
425     text_color = fg[0];
426     background = bg[0];
427   } else {
428     text_color = fg[1];
429     background = bg[1];
430   }
431   if(font==NULL) {
432     ch=_aguix->getCharHeight();
433   } else {
434     ch=font->getCharHeight();
435   }
436 
437   dy=_h/2-ch/2;
438 
439   if ( ( dual == false ) || ( state != 2 ) ) {
440     tstr=dupstring(text[0]);
441   } else {
442     tstr=dupstring(text[1]);
443   }
444 
445   bw = 2;
446 
447   int icon_width = 0;
448   int icon_height = 0;
449   int icon_space = 0;
450 
451   if ( m_icon ) {
452       m_icon->update( win, text_color, background, false );
453 
454       icon_width = m_icon->w();
455       icon_height = m_icon->h();
456       icon_space = 5;
457   }
458 
459   len = _aguix->getStrlen4Width( tstr, _w - 2 * bw - icon_width - icon_space, &strwidth, font );
460   if ( len > 0 ) {
461     if ( len >= (int)strlen( tstr ) ) len = (int)strlen( tstr );
462     tstr[len] = '\0';
463 
464     int dx = _w / 2 - ( icon_width + icon_space + strwidth ) / 2;
465 
466     DrawableCont dc( _aguix, win );
467 
468     if ( m_icon_pos == ICON_RIGHT ) {
469         _aguix->DrawText( dc, font, tstr, dx, dy, text_color );
470     } else {
471         _aguix->DrawText( dc, font, tstr, dx + icon_width + icon_space, dy, text_color );
472     }
473 
474     if ( m_strike_out ) {
475         _aguix->setFG( text_color );
476         _aguix->DrawLine( win,
477                           dx,
478                           _h / 2,
479                           dx + strwidth,
480                           _h / 2);
481     }
482 
483     if ( m_icon ) {
484         if ( m_icon_pos == ICON_RIGHT ) {
485             m_icon->draw( win,
486                           dx + strwidth + icon_space,
487                           _h / 2 - icon_height / 2 );
488         } else {
489             m_icon->draw( win,
490                           dx, _h / 2 - icon_height / 2 );
491         }
492     }
493   } else {
494       if ( m_icon ) {
495           int dx = _w / 2 - icon_width / 2;
496 
497           m_icon->draw( win, dx, _h / 2 - icon_height / 2 );
498       }
499   }
500   _freesafe( tstr );
501 
502   // draw the focus
503   if ( ( getHasFocus() == true ) && ( getAcceptFocus() == true ) ) {
504     _aguix->setDottedFG( 1 );
505     _aguix->DrawDottedRectangle( win, bw, bw, _w - 2 * bw, _h - 2 * bw );
506   }
507 
508   /* now draw the button */
509 
510   if( showe == true ) {
511     _aguix->setFG( _aguix->getFaceCol_3d_bright() );
512     _aguix->DrawTriangleFilled( win, px1, py1, px2, py2, px3, py3 );
513     _aguix->setFG( _aguix->getFaceCol_default_bg() );
514     _aguix->DrawTriangleFilled( win, px1, py1, _w-1, 0, px3, py3 );
515   }
516 
517   if ( ! m_disabled ) {
518       _aguix->drawBorder( win, ( state == 0 ) ? false : true, 0, 0, _w, _h, ear_width - 1 );
519   }
520 
521   if( showe == true ) {
522     _aguix->setFG( _aguix->getFaceCol_3d_dark() );
523     _aguix->DrawLine( win, px1, py1, px2, py2 );
524     _aguix->DrawLine( win, px2, py2, px3, py3 );
525     _aguix->DrawLine( win, px1, py1, px3, py3 );
526   }
527 
528   _aguix->Flush();
529 }
530 
flush()531 void Button::flush()
532 {
533 }
534 
setState(int tstate)535 void Button::setState(int tstate)
536 {
537   if((dual==false)&&(tstate==2)) {
538     this->state=1;
539   } else {
540     this->state=tstate;
541   }
542   redraw();
543 }
544 
getState() const545 int Button::getState() const
546 {
547   return state;
548 }
549 
isInside(int px,int py) const550 bool Button::isInside(int px,int py) const
551 {
552   if((px>0)&&(px<=_w)) {
553     if((py>0)&&(py<=_h)) return true;
554   }
555   return false;
556 }
557 
handleMessage(XEvent * E,Message * msg)558 bool Button::handleMessage(XEvent *E,Message *msg)
559 {
560     bool returnvalue;
561 
562     if ( isCreated() == false ) return false;
563 
564     returnvalue = GUIElement::handleMessage( E, msg );
565 
566     returnvalue=false;
567     if((msg->type==ButtonPress)||(msg->type==ButtonRelease)) {
568         if ( msg->window == win ) {
569             if ( ( msg->button == Button3 ) ||
570                  ( msg->button == Button1 ) ||
571                  ( ( msg->button == Button4 ) && ( allowWheel == true ) ) ||
572                  ( ( msg->button == Button5 ) && ( allowWheel == true ) ) ) {
573                 if(msg->type==ButtonPress) {
574                     takeFocus();
575                     if(msg->window==win) {
576                         if( ( ( ( msg->button == Button1 ) || ( msg->button == Button4 ) || ( msg->button == Button5 ) ) && ( active[0] == true ) ) ||
577                             ( ( msg->button == Button3 ) && ( active[1] == true ) ) ) {
578                             AGMessage *agmsg = AGUIX_allocAGMessage();
579                             agmsg->type=AG_BUTTONPRESSED;
580                             agmsg->button.button=this;
581                             if((msg->button==Button3)&&(dual==true)) {
582                                 setState(2);
583                                 instate=2;
584                                 agmsg->button.state=2;
585                             } else {
586                                 switch ( msg->button ) {
587                                     case Button4:
588                                         instate = 3;
589                                         break;
590                                     case Button5:
591                                         instate = 4;
592                                         break;
593                                     default:
594                                         instate=1;
595                                         break;
596                                 }
597                                 setState( instate );
598                                 agmsg->button.state = instate;
599                             }
600 
601                             agmsg->button.keystate = KEYSTATEMASK( msg->keystate );
602 
603                             if ( ! m_disabled ) {
604                                 msgAndCB( std::unique_ptr<AGMessage>( agmsg ) );
605                             } else {
606                                 delete agmsg;
607                             }
608                             returnvalue=true;
609                         }
610                     }
611                 } else {
612                     if ( state != 0 && instate != 0 && ! m_disabled ) {
613                         AGMessage *agmsg = AGUIX_allocAGMessage();
614                         agmsg->type=AG_BUTTONRELEASED;
615                         agmsg->button.button=this;
616                         agmsg->button.state=instate;
617                         agmsg->button.keystate = KEYSTATEMASK( msg->keystate );
618                         msgAndCB( std::unique_ptr<AGMessage>( agmsg ) );
619                         agmsg = AGUIX_allocAGMessage();
620                         agmsg->type=AG_BUTTONCLICKED;
621                         agmsg->button.button=this;
622                         agmsg->button.state=instate;
623                         agmsg->button.keystate = KEYSTATEMASK( msg->keystate );
624                         msgAndCB( std::unique_ptr<AGMessage>( agmsg ) );
625                     }
626                     if(instate!=0) {
627                         setState(0);
628                         instate=0;
629                         returnvalue=true;
630                     }
631                 }
632             }
633         }
634     } else if(msg->type==EnterNotify) {
635         // alles hier und alles mit instate wird benutzt, damit Button sich anpa�t, wenn
636         // Mauszeiger im Button oder au�erhalb des Buttons ist
637         if ( msg->window == win ) {
638             if(instate!=0) {
639                 if(state!=instate) {
640                     setState(instate);
641                 }
642             }
643         }
644     } else if(msg->type==LeaveNotify) {
645         // alles hier und alles mit instate wird benutzt, damit Button sich anpa�t, wenn
646         // Mauszeiger im Button oder au�erhalb des Buttons ist
647         if ( msg->window == win ) {
648             if(instate!=0) {
649                 setState(0);
650             }
651         }
652     } else if(msg->type==Expose) {
653         if ( msg->window == win ) {
654             redraw();
655         }
656     } else if ( msg->type == KeyPress ) {
657         if ( ( getAcceptFocus() == true ) && ( getHasFocus() == true ) ) {
658             if ( msg->key == XK_space ) {
659                 if ( isVisible() == true ) {
660                     if ( _parent->isTopParent( msg->window ) == true ) {
661                         AGMessage *agmsg;
662 
663                         agmsg = AGUIX_allocAGMessage();
664                         agmsg->type=AG_BUTTONCLICKED;
665                         agmsg->button.button=this;
666                         agmsg->button.state=1;
667                         agmsg->button.keystate = KEYSTATEMASK( msg->keystate );
668 
669                         if ( ! m_disabled ) {
670                             msgAndCB( std::unique_ptr<AGMessage>( agmsg ) );
671                         } else {
672                             delete agmsg;
673                         }
674                         if(instate!=0) {
675                             setState(0);
676                             instate=0;
677                             returnvalue=true;
678                         }
679                     }
680                 }
681             }
682         }
683     }
684     if(returnvalue==true) {
685         // jetzt noch die Message mit den Werten f�llen
686         msg->gadget=this;
687         msg->gadgettype=BUTTON_GADGET;
688     }
689     //  return returnvalue;
690     return false; // see cyclebutton.cc
691 }
692 
getShowDual() const693 bool Button::getShowDual() const
694 {
695   return showdual;
696 }
697 
setShowDual(bool new_val)698 void Button::setShowDual(bool new_val)
699 {
700   if(showdual!=new_val) {
701     showdual=new_val;
702     redraw();
703   } else showdual=new_val;
704 }
705 
setFont(const char * fontname)706 int Button::setFont( const char *fontname )
707 {
708   font=_aguix->getFont(fontname);
709   if(font==NULL) return -1;
710   return 0;
711 }
712 
getType() const713 const char *Button::getType() const
714 {
715   return type;
716 }
717 
isType(const char * qtype) const718 bool Button::isType(const char *qtype) const
719 {
720   if(strcmp(type,qtype)==0) return true;
721   return false;
722 }
723 
deactivate()724 void Button::deactivate()
725 {
726   deactivate(0);
727   deactivate(1);
728 }
729 
activate()730 void Button::activate()
731 {
732   activate(0);
733   activate(1);
734 }
735 
deactivate(int mode)736 void Button::deactivate(int mode)
737 {
738   if( ( mode == 0 ) || ( mode == 1 ) ) {
739     active[mode]=false;
740     if ( mode == 0 ) setAcceptFocus( false );
741   }
742 }
743 
activate(int mode)744 void Button::activate(int mode)
745 {
746   if( ( mode == 0 ) || ( mode == 1 ) ) {
747     active[mode]=true;
748   }
749 }
750 
getAllowWheel() const751 bool Button::getAllowWheel() const
752 {
753   return allowWheel;
754 }
755 
setAllowWheel(bool nv)756 void Button::setAllowWheel( bool nv )
757 {
758   allowWheel = nv;
759 }
760 
init_class()761 void Button::init_class()
762 {
763   dual = false;
764   data = 0;
765   state = 0;
766   instate = 0;
767 
768   showdual = true;
769   font = NULL;
770   active[0] = true;
771   active[1] = true;
772   fg[0] = -1;
773   fg[1] = -1;
774   bg[0] = -1;
775   bg[1] = -1;
776   text[0] = dupstring( "" );
777   text[1] = dupstring( "" );
778   allowWheel = false;
779 
780   setCanHandleFocus();
781   setAcceptFocus( true );
782 }
783 
prepareBG(bool force)784 void Button::prepareBG( bool force )
785 {
786   int newbg;
787 
788   if ( isCreated() == false ) return;
789   if ( win == 0 ) return;
790 
791   if ( ( dual == false ) || ( state != 2 ) ) {
792     newbg = bg[0];
793   } else {
794     newbg = bg[1];
795   }
796 
797   _aguix->SetWindowBG( win, newbg );
798 }
799 
getMaximumWidth()800 int Button::getMaximumWidth()
801 {
802     int max_w = _aguix->getTextWidth( text[0], font ) + _aguix->getTextWidth( "  ", font );
803 
804     if ( dual ) {
805         int t_max_w = _aguix->getTextWidth( text[1], font ) + _aguix->getTextWidth( "  ", font );
806         if ( t_max_w > max_w ) max_w = t_max_w;
807     }
808 
809     return max_w;
810 }
811 
applyFaces()812 void Button::applyFaces()
813 {
814     if ( fg[0] < 0 ) {
815         fg[0] = _aguix->getFaces().getColor( "button-fg" );
816     }
817 
818     if ( bg[0] < 0 ) {
819         bg[0] = _aguix->getFaces().getColor( "button-bg" );
820     }
821 
822     if ( fg[1] < 0 ) {
823         fg[1] = _aguix->getFaces().getColor( "button-alt-fg" );
824     }
825 
826     if ( bg[1] < 0 ) {
827         bg[1] = _aguix->getFaces().getColor( "button-alt-bg" );
828     }
829 }
830 
setIcon(const int * pixels,size_t pixels_length,icon_position pos)831 void Button::setIcon( const int *pixels,
832                       size_t pixels_length,
833                       icon_position pos )
834 {
835     m_icon = std::make_shared< AIcon >( _aguix,
836                                         win,
837                                         pixels,
838                                         pixels_length );
839     m_icon_pos = pos;
840 }
841 
getPreferredHeight()842 int Button::getPreferredHeight()
843 {
844     int bw = 2;
845 
846     if ( font == NULL ) {
847         return _aguix->getCharHeight() + 2 * bw;
848     } else {
849         return font->getCharHeight() + 2 * bw;
850     }
851 }
852 
setDisabled(bool nv)853 void Button::setDisabled( bool nv )
854 {
855     m_disabled = nv;
856 }
857 
getDisabled() const858 bool Button::getDisabled() const
859 {
860     return m_disabled;
861 }
862 
setStrikeOut(bool nv)863 void Button::setStrikeOut( bool nv )
864 {
865     m_strike_out = nv;
866 }
867 
getStrikeOut() const868 bool Button::getStrikeOut() const
869 {
870     return m_strike_out;
871 }
872