1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  Steve Baker
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21      $Id: puButton.cxx 2064 2006-01-05 21:32:59Z fayjf $
22 */
23 
24 
25 #include "puLocal.h"
26 
UL_RTTI_DEF1(puButton,puObject)27 UL_RTTI_DEF1(puButton,puObject)
28 
29 
30 void puButton::draw ( int dx, int dy )
31 {
32   if ( !visible || ( window != puGetWindow () ) ) return ;
33 
34   if ( button_type == PUBUTTON_NORMAL )
35   {
36     /* If button is pushed or highlighted - use inverse style */
37 
38     if ( getIntegerValue() ^ highlighted )
39     {
40       if ( parent && ( ( parent->getType() & PUCLASS_POPUPMENU ) ||
41                        ( parent->getType() & PUCLASS_MENUBAR   ) ) )
42         abox.draw ( dx, dy, active ? PUSTYLE_SMALL_SHADED : PUSTYLE_PLAIN, colour,
43                     isReturnDefault(), active ? 2 : 0 ) ;
44       else
45         abox.draw ( dx, dy, -style, colour, isReturnDefault(), border_thickness ) ;
46     }
47     else
48       abox.draw ( dx, dy, style, colour, isReturnDefault(), border_thickness ) ;
49   }
50   else if ( ( button_type == PUBUTTON_VCHECK ) ||
51             ( button_type == PUBUTTON_XCHECK ) )
52     abox.draw ( dx, dy, PUSTYLE_BOXED, colour, isReturnDefault(), 1 ) ;
53 
54   if ( r_cb )
55     r_cb ( this, dx, dy, render_data ) ;
56   else
57   {
58     switch ( button_type )
59     {
60       case PUBUTTON_NORMAL :
61         draw_legend ( dx, dy ) ;
62         break ;
63 
64       case PUBUTTON_RADIO :
65       {
66         int btn_width  = abox.max[0] - abox.min[0],
67             btn_height = abox.max[1] - abox.min[1] ;
68 
69         glColor4fv ( ( getIntegerValue () ^ highlighted ) ?
70                      colour [ PUCOL_BACKGROUND ] : colour [ PUCOL_LEGEND ] ) ;
71 
72         glBegin    ( GL_LINE_LOOP ) ;
73         glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1]                ) ;
74         glVertex2i ( dx+abox.min[0] + btn_width,   dy+abox.min[1] + btn_height/2 ) ;
75         glVertex2i ( dx+abox.min[0] + btn_width/2, dy+abox.min[1] + btn_height   ) ;
76 	glVertex2i ( dx+abox.min[0],               dy+abox.min[1] + btn_height/2 ) ;
77         glEnd () ;
78 
79         if ( getIntegerValue () ^ highlighted )
80         {
81           /* If greyed out then halve the opacity when drawing the widget */
82 
83           if ( active )
84             glColor4fv ( colour [ PUCOL_HIGHLIGHT ] ) ;
85           else
86             glColor4f ( colour [ PUCOL_HIGHLIGHT ][0],
87                         colour [ PUCOL_HIGHLIGHT ][1],
88                         colour [ PUCOL_HIGHLIGHT ][2],
89                         colour [ PUCOL_HIGHLIGHT ][3] / 2.0f ) ; /* 50% more transparent */
90 
91           glBegin    ( GL_QUADS ) ;
92           glVertex2i ( dx+abox.min[0] + btn_width/2,
93                        dy+abox.min[1] + 2 ) ;
94           glVertex2i ( dx+abox.min[0] + btn_width - 2,
95                        dy+abox.min[1] + btn_height/2 ) ;
96           glVertex2i ( dx+abox.min[0] + btn_width/2,
97                        dy+abox.min[1] + btn_height - 2 ) ;
98           glVertex2i ( dx+abox.min[0] + 2,
99                        dy+abox.min[1] + btn_height/2 ) ;
100           glEnd () ;
101         }
102 
103         break ;
104       }
105 
106       case PUBUTTON_CIRCLE :
107       {
108         float rad = ( (abox.max[0]-abox.min[0]) < (abox.max[1]-abox.min[1]) ) ?
109                     (abox.max[0]-abox.min[0])/2.0f : (abox.max[1]-abox.min[1])/2.0f ;
110         float dtheta = 2.0f / rad ;
111         float theta ;
112 
113         /* Draw the outer circle */
114 
115         glColor4fv ( colour [ PUCOL_FOREGROUND ] ) ;
116 
117         glBegin ( GL_POLYGON ) ;
118         for ( theta = -SG_PI ; theta <= SG_PI ; theta += dtheta )
119           glVertex2f ( dx + abox.min[0] + rad + (rad * float(cos ( theta ))),
120                        dy + abox.min[1] + rad + (rad * float(sin ( theta ))) ) ;
121         glEnd () ;
122 
123         if ( getIntegerValue () ^ highlighted )
124         /* If clicked, draw the inner circle with half the radius */
125         {
126           rad /= 2 ;
127           dtheta = 2.0f / rad ;
128 
129           /* If greyed out then halve the opacity when drawing the widget */
130 
131           if ( active )
132             glColor4fv ( colour [ PUCOL_MISC ] ) ;
133           else
134             glColor4f ( colour [ PUCOL_MISC ][0],
135                         colour [ PUCOL_MISC ][1],
136                         colour [ PUCOL_MISC ][2],
137                         colour [ PUCOL_MISC ][3] / 2.0f ) ; /* 50% more transparent */
138 
139           glBegin ( GL_POLYGON ) ;
140           for ( theta = -SG_PI ; theta <= SG_PI ; theta += dtheta )
141             glVertex2f ( dx + abox.min[0] + rad*2 + (rad * float(cos ( theta ))),
142                          dy + abox.min[1] + rad*2 + (rad * float(sin ( theta ))) ) ;
143           glEnd () ;
144         }
145 
146         break ;
147       }
148 
149       case PUBUTTON_VCHECK :
150       case PUBUTTON_XCHECK :
151         if ( getIntegerValue () ^ highlighted )
152         {
153           /* If greyed out then halve the opacity when drawing the widget */
154 
155           if ( active )
156             glColor4fv ( colour [ PUCOL_MISC ] ) ;
157           else
158             glColor4f ( colour [ PUCOL_MISC ][0],
159                         colour [ PUCOL_MISC ][1],
160                         colour [ PUCOL_MISC ][2],
161                         colour [ PUCOL_MISC ][3] / 2.0f ) ; /* 50% more transparent */
162 
163           glPushAttrib ( GL_LINE_BIT ) ;
164 
165           glLineWidth ( 2.0f ) ;
166 
167           if ( button_type == PUBUTTON_VCHECK )
168           {
169             glBegin ( GL_LINE_STRIP ) ;
170             glVertex2i ( dx + abox.min[0],
171                          dy + abox.min[1] + (abox.max[1] - abox.min[1])/2 ) ;
172             glVertex2i ( dx + abox.min[0] + (abox.max[0] - abox.min[0])/3,
173                          dy + abox.min[1] ) ;
174             glVertex2i ( dx + abox.max[0],
175                          dy + abox.max[1] ) ;
176             glEnd () ;
177           }
178           else if ( button_type == PUBUTTON_XCHECK )
179           {
180             glBegin ( GL_LINES ) ;
181             glVertex2i ( dx + abox.min[0] + 1, dy + abox.min[1] + 1 ) ;
182             glVertex2i ( dx + abox.max[0] - 1, dy + abox.max[1] - 1 ) ;
183             glVertex2i ( dx + abox.max[0] - 1, dy + abox.min[1] + 1 ) ;
184             glVertex2i ( dx + abox.min[0] + 1, dy + abox.max[1] - 1 ) ;
185             glEnd () ;
186           }
187 
188           glPopAttrib () ;
189         }
190 
191         break ;
192 
193       default :
194         ulSetError ( UL_WARNING, "PUI: Unrecognised 'button_type' %d", button_type ) ;
195         break;
196     }
197   }
198 
199   draw_label ( dx, dy ) ;
200 }
201 
202 
doHit(int button,int updown,int x,int y)203 void puButton::doHit ( int button, int updown, int x, int y )
204 {
205   if ( puActiveWidget() && ( this != puActiveWidget() ) )
206   {
207     puActiveWidget() -> invokeDownCallback () ;
208     puDeactivateWidget () ;
209   }
210 
211   if ( updown != PU_DRAG )
212     puMoveToLast ( this );
213 
214   if ( button == active_mouse_button )
215   {
216     if ( ( updown == active_mouse_edge ) || ( active_mouse_edge == PU_UP_AND_DOWN ) )
217     {
218       lowlight () ;
219       setValue ( (int) ! getIntegerValue () ) ;
220       puSetActiveWidget ( this, x, y ) ;
221       invokeCallback () ;
222     }
223     else
224     {
225       /* If the mouse is over the widget, highlight it; otherwise lowlight it */
226       if ( ( abox.min[0] <= x ) && ( abox.max[0] >= x ) && ( abox.min[1] <= y ) && ( abox.max[1] >= y ) )
227         highlight () ;
228       else
229         lowlight () ;
230     }
231   }
232   else
233     lowlight () ;
234 }
235 
236 
237