Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wslider.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001
9d2e6ef9 scottc1998-09-29 22:36:29 +00002#include "WINGsP.h"
3
9d2e6ef9 scottc1998-09-29 22:36:29 +00004#undef STRICT_NEXT_BEHAVIOUR
5
9d2e6ef9 scottc1998-09-29 22:36:29 +00006typedef struct W_Slider {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02007 W_Class widgetClass;
8 WMView *view;
9d2e6ef9 scottc1998-09-29 22:36:29 +00009
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020010 int minValue;
11 int maxValue;
6830b057 dan2004-10-12 21:28:27 +000012
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020013 int value;
9d2e6ef9 scottc1998-09-29 22:36:29 +000014
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020015 Pixmap knobPixmap;
16 WMPixmap *backPixmap;
9d2e6ef9 scottc1998-09-29 22:36:29 +000017
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020018 WMAction *action;
19 void *clientData;
9d2e6ef9 scottc1998-09-29 22:36:29 +000020
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020021 int knobThickness;
0261c326 dan1999-01-06 15:22:33 +000022
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020023 struct {
24 unsigned int continuous:1;
6830b057 dan2004-10-12 21:28:27 +000025
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020026 unsigned int vertical:1;
27 unsigned int dragging:1;
28 } flags;
6830b057 dan2004-10-12 21:28:27 +000029
9d2e6ef9 scottc1998-09-29 22:36:29 +000030} Slider;
31
5e4625da kojima1999-05-29 21:41:25 +000032static void didResizeSlider();
9d2e6ef9 scottc1998-09-29 22:36:29 +000033
5e4625da kojima1999-05-29 21:41:25 +000034W_ViewDelegate _SliderViewDelegate = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020035 NULL,
36 NULL,
37 didResizeSlider,
38 NULL,
39 NULL
9d2e6ef9 scottc1998-09-29 22:36:29 +000040};
41
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020042static void destroySlider(Slider * sPtr);
43static void paintSlider(Slider * sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000044
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020045static void handleEvents(XEvent * event, void *data);
46static void handleActionEvents(XEvent * event, void *data);
9d2e6ef9 scottc1998-09-29 22:36:29 +000047
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020048static void makeKnobPixmap(Slider * sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000049
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020050static void realizeObserver(void *self, WMNotification * not)
9d2e6ef9 scottc1998-09-29 22:36:29 +000051{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020052 makeKnobPixmap(self);
9d2e6ef9 scottc1998-09-29 22:36:29 +000053}
54
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020055WMSlider *WMCreateSlider(WMWidget * parent)
9d2e6ef9 scottc1998-09-29 22:36:29 +000056{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020057 Slider *sPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +000058
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020059 sPtr = wmalloc(sizeof(Slider));
60 memset(sPtr, 0, sizeof(Slider));
9d2e6ef9 scottc1998-09-29 22:36:29 +000061
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020062 sPtr->widgetClass = WC_Slider;
6830b057 dan2004-10-12 21:28:27 +000063
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020064 sPtr->view = W_CreateView(W_VIEW(parent));
65 if (!sPtr->view) {
66 wfree(sPtr);
67 return NULL;
68 }
69 sPtr->view->self = sPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +000070
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020071 sPtr->view->delegate = &_SliderViewDelegate;
5e4625da kojima1999-05-29 21:41:25 +000072
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020073 WMCreateEventHandler(sPtr->view, ExposureMask | StructureNotifyMask, handleEvents, sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000074
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020075 WMCreateEventHandler(sPtr->view, ButtonPressMask | ButtonReleaseMask
76 | EnterWindowMask | LeaveWindowMask | ButtonMotionMask, handleActionEvents, sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000077
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020078 W_ResizeView(sPtr->view, 100, 16);
79 sPtr->flags.vertical = 0;
80 sPtr->minValue = 0;
81 sPtr->maxValue = 100;
82 sPtr->value = 50;
9d2e6ef9 scottc1998-09-29 22:36:29 +000083
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020084 sPtr->knobThickness = 20;
0261c326 dan1999-01-06 15:22:33 +000085
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020086 sPtr->flags.continuous = 1;
0261c326 dan1999-01-06 15:22:33 +000087
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020088 WMAddNotificationObserver(realizeObserver, sPtr, WMViewRealizedNotification, sPtr->view);
1e922744 dan2002-10-16 04:05:45 +000089
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020090 return sPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +000091}
92
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020093void WMSetSliderImage(WMSlider * sPtr, WMPixmap * pixmap)
0261c326 dan1999-01-06 15:22:33 +000094{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020095 if (sPtr->backPixmap)
96 WMReleasePixmap(sPtr->backPixmap);
0261c326 dan1999-01-06 15:22:33 +000097
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020098 sPtr->backPixmap = WMRetainPixmap(pixmap);
6830b057 dan2004-10-12 21:28:27 +000099
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200100 if (sPtr->view->flags.mapped) {
101 paintSlider(sPtr);
102 }
0261c326 dan1999-01-06 15:22:33 +0000103}
104
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200105void WMSetSliderKnobThickness(WMSlider * sPtr, int thickness)
0261c326 dan1999-01-06 15:22:33 +0000106{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200107 assert(thickness > 0);
0261c326 dan1999-01-06 15:22:33 +0000108
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200109 sPtr->knobThickness = thickness;
0261c326 dan1999-01-06 15:22:33 +0000110
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200111 if (sPtr->knobPixmap) {
112 makeKnobPixmap(sPtr);
113 }
0261c326 dan1999-01-06 15:22:33 +0000114
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200115 if (sPtr->view->flags.mapped) {
116 paintSlider(sPtr);
117 }
0261c326 dan1999-01-06 15:22:33 +0000118}
119
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200120int WMGetSliderMinValue(WMSlider * slider)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000121{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200122 CHECK_CLASS(slider, WC_Slider);
6830b057 dan2004-10-12 21:28:27 +0000123
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200124 return slider->minValue;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000125}
126
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200127int WMGetSliderMaxValue(WMSlider * slider)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000128{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200129 CHECK_CLASS(slider, WC_Slider);
6830b057 dan2004-10-12 21:28:27 +0000130
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200131 return slider->maxValue;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000132}
133
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200134int WMGetSliderValue(WMSlider * slider)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000135{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200136 CHECK_CLASS(slider, WC_Slider);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000137
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200138 return slider->value;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000139}
140
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200141void WMSetSliderMinValue(WMSlider * slider, int value)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000142{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200143 CHECK_CLASS(slider, WC_Slider);
144
145 slider->minValue = value;
146 if (slider->value < value) {
147 slider->value = value;
148 if (slider->view->flags.mapped)
149 paintSlider(slider);
150 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000151}
152
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200153void WMSetSliderMaxValue(WMSlider * slider, int value)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000154{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200155 CHECK_CLASS(slider, WC_Slider);
156
157 slider->maxValue = value;
158 if (slider->value > value) {
159 slider->value = value;
160 if (slider->view->flags.mapped)
161 paintSlider(slider);
162 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000163}
164
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200165void WMSetSliderValue(WMSlider * slider, int value)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000166{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200167 CHECK_CLASS(slider, WC_Slider);
6830b057 dan2004-10-12 21:28:27 +0000168
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200169 if (value < slider->minValue)
170 slider->value = slider->minValue;
171 else if (value > slider->maxValue)
172 slider->value = slider->maxValue;
173 else
174 slider->value = value;
6830b057 dan2004-10-12 21:28:27 +0000175
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200176 if (slider->view->flags.mapped)
177 paintSlider(slider);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000178}
179
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200180void WMSetSliderContinuous(WMSlider * slider, Bool flag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000181{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200182 CHECK_CLASS(slider, WC_Slider);
6830b057 dan2004-10-12 21:28:27 +0000183
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200184 slider->flags.continuous = ((flag == 0) ? 0 : 1);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000185}
186
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200187void WMSetSliderAction(WMSlider * slider, WMAction * action, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000188{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200189 CHECK_CLASS(slider, WC_Slider);
6830b057 dan2004-10-12 21:28:27 +0000190
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200191 slider->action = action;
192 slider->clientData = data;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000193}
194
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200195static void makeKnobPixmap(Slider * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000196{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200197 Pixmap pix;
198 WMScreen *scr = sPtr->view->screen;
199 int w, h;
200
201 if (sPtr->flags.vertical) {
202 w = sPtr->view->size.width - 2;
203 h = sPtr->knobThickness;
204 } else {
205 w = sPtr->knobThickness;
206 h = sPtr->view->size.height - 2;
207 }
208
209 pix = XCreatePixmap(scr->display, sPtr->view->window, w, h, scr->depth);
210 XFillRectangle(scr->display, pix, WMColorGC(scr->gray), 0, 0, w, h);
211
212 if (sPtr->knobThickness < 10) {
213 W_DrawRelief(scr, pix, 0, 0, w, h, WRRaised);
214 } else if (sPtr->flags.vertical) {
215 XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, 0, h - 3);
216 XDrawLine(scr->display, pix, WMColorGC(scr->white), 1, 0, 1, h - 3);
217 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w - 2, 1, w - 2, h / 2 - 2);
218 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w - 2, h / 2, w - 2, h - 2);
219
220 XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, w - 2, 0);
221 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 1, h / 2 - 2, w - 3, h / 2 - 2);
222 XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, h / 2 - 1, w - 3, h / 2 - 1);
223
224 XDrawLine(scr->display, pix, WMColorGC(scr->black), w - 1, 0, w - 1, h - 2);
225
226 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 0, h - 3, w - 2, h - 3);
227 XDrawLine(scr->display, pix, WMColorGC(scr->black), 0, h - 2, w - 1, h - 2);
228 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 0, h - 1, w - 1, h - 1);
229 } else {
230 XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, w - 3, 0);
231
232 XDrawLine(scr->display, pix, WMColorGC(scr->white), 0, 0, 0, h - 2);
233
234 XDrawLine(scr->display, pix, WMColorGC(scr->white), 1, 0, 1, h - 3);
235 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w / 2 - 2, 1, w / 2 - 2, h - 3);
236 XDrawLine(scr->display, pix, WMColorGC(scr->white), w / 2 - 1, 0, w / 2 - 1, h - 3);
237
238 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w - 3, 0, w - 3, h - 2);
239 XDrawLine(scr->display, pix, WMColorGC(scr->black), w - 2, 0, w - 2, h - 2);
240 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w - 1, 0, w - 1, h - 1);
241
242 XDrawLine(scr->display, pix, WMColorGC(scr->black), 1, h - 1, w / 2 + 1, h - 1);
243 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), 1, h - 2, w / 2 - 2, h - 2);
244 XDrawLine(scr->display, pix, WMColorGC(scr->darkGray), w / 2, h - 2, w - 3, h - 2);
245
246 XDrawLine(scr->display, pix, WMColorGC(scr->black), 0, h - 1, w - 2, h - 1);
247 }
248
249 if (sPtr->knobPixmap)
250 XFreePixmap(scr->display, sPtr->knobPixmap);
251 sPtr->knobPixmap = pix;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000252}
253
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200254static void didResizeSlider(W_ViewDelegate * self, WMView * view)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000255{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200256 Slider *sPtr = (Slider *) view->self;
257 int width = sPtr->view->size.width;
258 int height = sPtr->view->size.height;
259
260 assert(width > 0);
261 assert(height > 0);
262
263 if (width > height) {
264 if (sPtr->flags.vertical) {
265 sPtr->flags.vertical = 0;
266 if (sPtr->view->flags.realized)
267 makeKnobPixmap(sPtr);
268 }
269 } else {
270 if (!sPtr->flags.vertical) {
271 sPtr->flags.vertical = 1;
272 if (sPtr->view->flags.realized)
273 makeKnobPixmap(sPtr);
274 }
275 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000276}
277
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200278static void paintSlider(Slider * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000279{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200280 W_Screen *scr = sPtr->view->screen;
281 GC bgc;
282 GC wgc;
283 GC lgc;
284 WMSize size = sPtr->view->size;
285 int pos;
286 Pixmap buffer;
6830b057 dan2004-10-12 21:28:27 +0000287
9d2e6ef9 scottc1998-09-29 22:36:29 +0000288#define MINV sPtr->minValue
289#define MAXV sPtr->maxValue
290#define POSV sPtr->value
6830b057 dan2004-10-12 21:28:27 +0000291
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200292 bgc = WMColorGC(scr->black);
293 wgc = WMColorGC(scr->white);
294 lgc = WMColorGC(scr->gray);
295
296 buffer = XCreatePixmap(scr->display, sPtr->view->window, size.width, size.height, scr->depth);
297
298 if (sPtr->backPixmap) {
299 WMSize size = WMGetPixmapSize(sPtr->backPixmap);
300
301 XCopyArea(scr->display, WMGetPixmapXID(sPtr->backPixmap),
302 buffer, scr->copyGC, 0, 0, size.width, size.height, 1, 1);
303 } else {
304 XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width, size.height);
305 XFillRectangle(scr->display, buffer, scr->stippleGC, 0, 0, size.width, size.height);
306 }
307
308 if (sPtr->flags.vertical) {
309 pos = (size.height - 2 - sPtr->knobThickness) * (POSV - MINV) / (MAXV - MINV) + 1;
310 /* draw knob */
311 XCopyArea(scr->display, sPtr->knobPixmap, buffer,
312 scr->copyGC, 0, 0, size.width - 2, sPtr->knobThickness, 1, pos);
313 } else {
314 pos = (size.width - 2 - sPtr->knobThickness) * (POSV - MINV) / (MAXV - MINV) + 1;
315 /* draw knob */
316 XCopyArea(scr->display, sPtr->knobPixmap, buffer,
317 scr->copyGC, 0, 0, sPtr->knobThickness, size.height, pos, 1);
318 }
319
320 XDrawLine(scr->display, buffer, bgc, 0, 0, 0, size.height - 1);
321 XDrawLine(scr->display, buffer, bgc, 0, 0, size.width, 0);
322
323 XDrawLine(scr->display, buffer, wgc, size.width - 1, 0, size.width - 1, size.height - 1);
324 XDrawLine(scr->display, buffer, wgc, 0, size.height - 1, size.width - 1, size.height - 1);
325
326 XCopyArea(scr->display, buffer, sPtr->view->window, scr->copyGC, 0, 0, size.width, size.height, 0, 0);
327 XFreePixmap(scr->display, buffer);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000328}
329
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200330static void handleEvents(XEvent * event, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000331{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200332 Slider *sPtr = (Slider *) data;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000333
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200334 CHECK_CLASS(data, WC_Slider);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000335
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200336 switch (event->type) {
337 case Expose:
338 if (event->xexpose.count != 0)
339 break;
340 paintSlider(sPtr);
341 break;
6830b057 dan2004-10-12 21:28:27 +0000342
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200343 case DestroyNotify:
344 destroySlider(sPtr);
345 break;
6830b057 dan2004-10-12 21:28:27 +0000346
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200347 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000348}
349
9d2e6ef9 scottc1998-09-29 22:36:29 +0000350#define DECR_PART 1
351#define KNOB_PART 2
352#define INCR_PART 3
353
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200354static int getSliderPart(Slider * sPtr, int x, int y)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000355{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200356 int p;
357 int pos;
358 WMSize size = sPtr->view->size;
359
360 if (sPtr->flags.vertical) {
361 p = y;
362 pos = (size.height - 2 - sPtr->knobThickness) * (POSV - MINV) / (MAXV - MINV);
363 if (p < pos)
364 return INCR_PART;
365 if (p > pos + sPtr->knobThickness)
366 return DECR_PART;
367 return KNOB_PART;
368 } else {
369 p = x;
370 pos = (size.width - 2 - sPtr->knobThickness) * (POSV - MINV) / (MAXV - MINV);
371 if (p < pos)
372 return DECR_PART;
373 if (p > pos + sPtr->knobThickness)
374 return INCR_PART;
375 return KNOB_PART;
376 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000377}
378
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200379static int valueForMousePoint(Slider * sPtr, int x, int y)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000380{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200381 WMSize size = sPtr->view->size;
382 int f;
383
384 if (sPtr->flags.vertical) {
385 f = (y - sPtr->knobThickness / 2) * (MAXV - MINV)
386 / ((int)size.height - 2 - sPtr->knobThickness);
387 } else {
388 f = (x - sPtr->knobThickness / 2) * (MAXV - MINV)
389 / ((int)size.width - 2 - sPtr->knobThickness);
390 }
391
392 f += sPtr->minValue;
393 if (f < sPtr->minValue)
394 f = sPtr->minValue;
395 else if (f > sPtr->maxValue)
396 f = sPtr->maxValue;
397
398 return f;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000399}
400
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200401static void handleActionEvents(XEvent * event, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000402{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200403 WMSlider *sPtr = (Slider *) data;
404
405 CHECK_CLASS(data, WC_Slider);
406
407 switch (event->type) {
408 case ButtonPress:
409 if (event->xbutton.button == WINGsConfiguration.mouseWheelUp && !sPtr->flags.dragging) {
410 /* Wheel up */
411 if (sPtr->value + 1 <= sPtr->maxValue) {
412 WMSetSliderValue(sPtr, sPtr->value + 1);
413 if (sPtr->flags.continuous && sPtr->action) {
414 (*sPtr->action) (sPtr, sPtr->clientData);
415 }
416 }
417 } else if (event->xbutton.button == WINGsConfiguration.mouseWheelDown && !sPtr->flags.dragging) {
418 /* Wheel down */
419 if (sPtr->value - 1 >= sPtr->minValue) {
420 WMSetSliderValue(sPtr, sPtr->value - 1);
421 if (sPtr->flags.continuous && sPtr->action) {
422 (*sPtr->action) (sPtr, sPtr->clientData);
423 }
424 }
425 } else if (getSliderPart(sPtr, event->xbutton.x, event->xbutton.y)
426 == KNOB_PART)
427 sPtr->flags.dragging = 1;
428 else {
9d2e6ef9 scottc1998-09-29 22:36:29 +0000429#ifdef STRICT_NEXT_BEHAVIOUR
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200430 sPtr->flags.dragging = 1;
0261c326 dan1999-01-06 15:22:33 +0000431
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200432 sPtr->value = valueForMousePoint(sPtr, event->xmotion.x, event->xmotion.y);
433 paintSlider(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000434#else
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200435 int tmp;
436
437 if (event->xbutton.button == Button2) {
438 sPtr->flags.dragging = 1;
439
440 sPtr->value = valueForMousePoint(sPtr, event->xmotion.x, event->xmotion.y);
441 paintSlider(sPtr);
442 } else {
443 tmp = valueForMousePoint(sPtr, event->xmotion.x, event->xmotion.y);
444 if (tmp < sPtr->value)
445 tmp = sPtr->value - 1;
446 else
447 tmp = sPtr->value + 1;
448 WMSetSliderValue(sPtr, tmp);
449 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000450#endif
451
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200452 if (sPtr->flags.continuous && sPtr->action) {
453 (*sPtr->action) (sPtr, sPtr->clientData);
454 }
455 }
456 break;
457
458 case ButtonRelease:
459 if (!sPtr->flags.continuous && sPtr->action) {
460 (*sPtr->action) (sPtr, sPtr->clientData);
461 }
462 sPtr->flags.dragging = 0;
463 break;
464
465 case MotionNotify:
466 if (sPtr->flags.dragging) {
467 sPtr->value = valueForMousePoint(sPtr, event->xmotion.x, event->xmotion.y);
468 paintSlider(sPtr);
469
470 if (sPtr->flags.continuous && sPtr->action) {
471 (*sPtr->action) (sPtr, sPtr->clientData);
472 }
473 }
474 break;
475 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000476}
477
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200478static void destroySlider(Slider * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000479{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200480 if (sPtr->knobPixmap)
481 XFreePixmap(sPtr->view->screen->display, sPtr->knobPixmap);
0261c326 dan1999-01-06 15:22:33 +0000482
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200483 if (sPtr->backPixmap)
484 WMReleasePixmap(sPtr->backPixmap);
0261c326 dan1999-01-06 15:22:33 +0000485
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200486 WMRemoveNotificationObserver(sPtr);
e7495baf dan1999-02-17 11:06:40 +0000487
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200488 wfree(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000489}