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