Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wscrollview.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 +00004typedef struct W_ScrollView {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02005 W_Class widgetClass;
6 WMView *view;
9d2e6ef9 scottc1998-09-29 22:36:29 +00007
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02008 WMView *contentView;
9 WMView *viewport;
6830b057 dan2004-10-12 21:28:27 +000010
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020011 WMScroller *vScroller;
12 WMScroller *hScroller;
6830b057 dan2004-10-12 21:28:27 +000013
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020014 short lineScroll;
15 short pageScroll;
6830b057 dan2004-10-12 21:28:27 +000016
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020017 struct {
18 WMReliefType relief:3;
19 unsigned int hasVScroller:1;
20 unsigned int hasHScroller:1;
6830b057 dan2004-10-12 21:28:27 +000021
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020022 } flags;
6830b057 dan2004-10-12 21:28:27 +000023
9d2e6ef9 scottc1998-09-29 22:36:29 +000024} ScrollView;
25
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020026static void destroyScrollView(ScrollView * sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000027
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020028static void paintScrollView(ScrollView * sPtr);
29static void handleEvents(XEvent * event, void *data);
30static void handleViewportEvents(XEvent * event, void *data);
9d2e6ef9 scottc1998-09-29 22:36:29 +000031static void resizeScrollView();
e99511b0 kojima2001-01-02 14:17:26 +000032static void updateScrollerProportion();
9d2e6ef9 scottc1998-09-29 22:36:29 +000033
5e4625da kojima1999-05-29 21:41:25 +000034W_ViewDelegate _ScrollViewViewDelegate = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020035 NULL,
36 NULL,
37 resizeScrollView,
38 NULL,
39 NULL
9d2e6ef9 scottc1998-09-29 22:36:29 +000040};
41
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020042WMScrollView *WMCreateScrollView(WMWidget * parent)
9d2e6ef9 scottc1998-09-29 22:36:29 +000043{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020044 ScrollView *sPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +000045
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020046 sPtr = wmalloc(sizeof(ScrollView));
47 memset(sPtr, 0, sizeof(ScrollView));
9d2e6ef9 scottc1998-09-29 22:36:29 +000048
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020049 sPtr->widgetClass = WC_ScrollView;
6830b057 dan2004-10-12 21:28:27 +000050
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020051 sPtr->view = W_CreateView(W_VIEW(parent));
52 if (!sPtr->view) {
53 wfree(sPtr);
54 return NULL;
55 }
56 sPtr->viewport = W_CreateView(sPtr->view);
57 if (!sPtr->viewport) {
58 W_DestroyView(sPtr->view);
59 wfree(sPtr);
60 return NULL;
61 }
62 sPtr->view->self = sPtr;
63 sPtr->viewport->self = sPtr;
6830b057 dan2004-10-12 21:28:27 +000064
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020065 sPtr->view->delegate = &_ScrollViewViewDelegate;
5e4625da kojima1999-05-29 21:41:25 +000066
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020067 sPtr->viewport->flags.mapWhenRealized = 1;
9d2e6ef9 scottc1998-09-29 22:36:29 +000068
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020069 WMCreateEventHandler(sPtr->view, StructureNotifyMask | ExposureMask, handleEvents, sPtr);
70 WMCreateEventHandler(sPtr->viewport, SubstructureNotifyMask, handleViewportEvents, sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +000071
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020072 sPtr->lineScroll = 4;
9d2e6ef9 scottc1998-09-29 22:36:29 +000073
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020074 sPtr->pageScroll = 0;
9d2e6ef9 scottc1998-09-29 22:36:29 +000075
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020076 return sPtr;
9d2e6ef9 scottc1998-09-29 22:36:29 +000077}
78
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020079static void applyScrollerValues(WMScrollView * sPtr)
e99511b0 kojima2001-01-02 14:17:26 +000080{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020081 int x, y;
e99511b0 kojima2001-01-02 14:17:26 +000082
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020083 if (sPtr->contentView == NULL)
84 return;
6830b057 dan2004-10-12 21:28:27 +000085
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020086 if (sPtr->flags.hasHScroller) {
87 float v = WMGetScrollerValue(sPtr->hScroller);
88 int size;
6830b057 dan2004-10-12 21:28:27 +000089
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020090 size = sPtr->contentView->size.width - sPtr->viewport->size.width;
e99511b0 kojima2001-01-02 14:17:26 +000091
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020092 x = v * size;
93 } else {
94 x = 0;
95 }
e99511b0 kojima2001-01-02 14:17:26 +000096
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020097 if (sPtr->flags.hasVScroller) {
98 float v = WMGetScrollerValue(sPtr->vScroller);
6830b057 dan2004-10-12 21:28:27 +000099
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200100 int size;
6830b057 dan2004-10-12 21:28:27 +0000101
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200102 size = sPtr->contentView->size.height - sPtr->viewport->size.height;
6830b057 dan2004-10-12 21:28:27 +0000103
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200104 y = v * size;
105 } else {
106 y = 0;
107 }
6830b057 dan2004-10-12 21:28:27 +0000108
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200109 x = WMAX(0, x);
110 y = WMAX(0, y);
6830b057 dan2004-10-12 21:28:27 +0000111
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200112 W_MoveView(sPtr->contentView, -x, -y);
6830b057 dan2004-10-12 21:28:27 +0000113
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200114 W_RaiseView(sPtr->viewport);
e99511b0 kojima2001-01-02 14:17:26 +0000115}
116
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200117static void reorganizeInterior(WMScrollView * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000118{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200119 int hx, hy, hw;
120 int vx, vy, vh;
121 int cx, cy, cw, ch;
122
123 cw = hw = sPtr->view->size.width;
124 vh = ch = sPtr->view->size.height;
125
126 if (sPtr->flags.relief == WRSimple) {
127 cw -= 2;
128 ch -= 2;
129 cx = 1;
130 cy = 1;
131 } else if (sPtr->flags.relief != WRFlat) {
132 cw -= 3;
133 ch -= 3;
134 cx = 2;
135 cy = 2;
136 } else {
137 cx = 0;
138 cy = 0;
139 }
140
141 if (sPtr->flags.hasHScroller) {
142 int h = 20;
143
144 ch -= h;
145
146 if (sPtr->flags.relief == WRSimple) {
147 hx = 0;
148 hy = sPtr->view->size.height - h;
149 } else if (sPtr->flags.relief != WRFlat) {
150 hx = 1;
151 hy = sPtr->view->size.height - h - 1;
152 hw -= 2;
153 } else {
154 hx = 0;
155 hy = sPtr->view->size.height - h;
156 }
157 } else {
158 /* make compiler shutup */
159 hx = 0;
160 hy = 0;
161 }
162
163 if (sPtr->flags.hasVScroller) {
164 int w = 20;
165 cw -= w;
166 cx += w;
167 hx += w - 1;
168 hw -= w - 1;
169
170 if (sPtr->flags.relief == WRSimple) {
171 vx = 0;
172 vy = 0;
173 } else if (sPtr->flags.relief != WRFlat) {
174 vx = 1;
175 vy = 1;
176 vh -= 2;
177 } else {
178 vx = 0;
179 vy = 0;
180 }
181 } else {
182 /* make compiler shutup */
183 vx = 0;
184 vy = 0;
185 }
186
187 W_ResizeView(sPtr->viewport, cw, ch);
188 W_MoveView(sPtr->viewport, cx, cy);
189
190 if (sPtr->flags.hasHScroller) {
191 WMResizeWidget(sPtr->hScroller, hw, 20);
192 WMMoveWidget(sPtr->hScroller, hx, hy);
193 }
194 if (sPtr->flags.hasVScroller) {
195 WMResizeWidget(sPtr->vScroller, 20, vh);
196 WMMoveWidget(sPtr->vScroller, vx, vy);
197 }
198
199 applyScrollerValues(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000200}
201
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200202static void resizeScrollView(W_ViewDelegate * self, WMView * view)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000203{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200204 reorganizeInterior(view->self);
205 updateScrollerProportion(view->self);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000206}
207
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200208void WMResizeScrollViewContent(WMScrollView * sPtr, unsigned int width, unsigned int height)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000209{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200210 int w, h, x;
211
212 w = width;
213 h = height;
214
215 x = 0;
216 if (sPtr->flags.relief == WRSimple) {
217 w += 2;
218 h += 2;
219 } else if (sPtr->flags.relief != WRFlat) {
220 w += 4;
221 h += 4;
222 x = 1;
223 }
224
225 if (sPtr->flags.hasVScroller) {
226 WMResizeWidget(sPtr->vScroller, 20, h);
227 width -= W_VIEW(sPtr->vScroller)->size.width;
228 }
229
230 if (sPtr->flags.hasHScroller) {
231 WMResizeWidget(sPtr->hScroller, w, 20);
232 WMMoveWidget(sPtr->hScroller, x, h);
233 height -= W_VIEW(sPtr->hScroller)->size.height;
234 }
235
236 W_ResizeView(sPtr->view, w, h);
237
238 W_ResizeView(sPtr->viewport, width, height);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000239}
240
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200241void WMSetScrollViewLineScroll(WMScrollView * sPtr, int amount)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000242{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200243 assert(amount > 0);
6830b057 dan2004-10-12 21:28:27 +0000244
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200245 sPtr->lineScroll = amount;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000246}
247
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200248void WMSetScrollViewPageScroll(WMScrollView * sPtr, int amount)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000249{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200250 assert(amount >= 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000251
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200252 sPtr->pageScroll = amount;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000253}
254
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200255WMRect WMGetScrollViewVisibleRect(WMScrollView * sPtr)
275a2a37 kojima2000-10-11 16:21:50 +0000256{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200257 WMRect rect;
e99511b0 kojima2001-01-02 14:17:26 +0000258
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200259 rect.pos.x = -sPtr->contentView->pos.x;
260 rect.pos.y = -sPtr->contentView->pos.y;
261 rect.size = sPtr->viewport->size;
e99511b0 kojima2001-01-02 14:17:26 +0000262
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200263 return rect;
275a2a37 kojima2000-10-11 16:21:50 +0000264}
265
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200266void WMScrollViewScrollPoint(WMScrollView * sPtr, WMPoint point)
e99511b0 kojima2001-01-02 14:17:26 +0000267{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200268 float xsize, ysize;
269 float xpos, ypos;
6830b057 dan2004-10-12 21:28:27 +0000270
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200271 xsize = sPtr->contentView->size.width - sPtr->viewport->size.width;
272 ysize = sPtr->contentView->size.height - sPtr->viewport->size.height;
6830b057 dan2004-10-12 21:28:27 +0000273
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200274 xpos = point.x / xsize;
275 ypos = point.y / ysize;
e99511b0 kojima2001-01-02 14:17:26 +0000276
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200277 if (sPtr->hScroller)
278 WMSetScrollerParameters(sPtr->hScroller, xpos, WMGetScrollerKnobProportion(sPtr->hScroller));
279 if (sPtr->vScroller)
280 WMSetScrollerParameters(sPtr->vScroller, ypos, WMGetScrollerKnobProportion(sPtr->vScroller));
6830b057 dan2004-10-12 21:28:27 +0000281
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200282 W_MoveView(sPtr->contentView, -point.x, -point.y);
e99511b0 kojima2001-01-02 14:17:26 +0000283}
284
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200285static void doScrolling(WMWidget * self, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000286{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200287 ScrollView *sPtr = (ScrollView *) data;
288 float value;
289 int pos;
290 int vpsize;
291 float size;
292
293 if (sPtr->hScroller == (WMScroller *) self) {
294 pos = -sPtr->contentView->pos.x;
295 size = sPtr->contentView->size.width - sPtr->viewport->size.width;
296 vpsize = sPtr->viewport->size.width - sPtr->pageScroll;
297 } else {
298 pos = -sPtr->contentView->pos.y;
299 size = sPtr->contentView->size.height - sPtr->viewport->size.height;
300 vpsize = sPtr->viewport->size.height - sPtr->pageScroll;
301 }
302 if (vpsize <= 0)
303 vpsize = 1;
304
305 switch (WMGetScrollerHitPart(self)) {
306 case WSDecrementLine:
307 if (pos > 0) {
308 pos -= sPtr->lineScroll;
309 if (pos < 0)
310 pos = 0;
311 value = (float)pos / size;
312 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
313 }
314 break;
315 case WSIncrementLine:
316 if (pos < size) {
317 pos += sPtr->lineScroll;
318 if (pos > size)
319 pos = size;
320 value = (float)pos / size;
321 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
322 }
323 break;
324
325 case WSKnob:
326 value = WMGetScrollerValue(self);
327 pos = value * size;
328 break;
329
330 case WSDecrementPage:
331 if (pos > 0) {
332 pos -= vpsize;
333 if (pos < 0)
334 pos = 0;
335 value = (float)pos / size;
336 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
337 }
338 break;
339
340 case WSDecrementWheel:
341 if (pos > 0) {
342 pos -= vpsize / 3;
343 if (pos < 0)
344 pos = 0;
345 value = (float)pos / size;
346 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
347 }
348 break;
349
350 case WSIncrementPage:
351 if (pos < size) {
352 pos += vpsize;
353 if (pos > size)
354 pos = size;
355 value = (float)pos / size;
356 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
357 }
358 break;
359
360 case WSIncrementWheel:
361 if (pos < size) {
362 pos += vpsize / 3;
363 if (pos > size)
364 pos = size;
365 value = (float)pos / size;
366 WMSetScrollerParameters(self, value, WMGetScrollerKnobProportion(self));
367 }
368 break;
369
370 case WSNoPart:
371 case WSKnobSlot:
372 break;
373 }
374
375 if (sPtr->hScroller == (WMScroller *) self) {
376 W_MoveView(sPtr->contentView, -pos, sPtr->contentView->pos.y);
377 } else {
378 W_MoveView(sPtr->contentView, sPtr->contentView->pos.x, -pos);
379 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000380}
381
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200382WMScroller *WMGetScrollViewHorizontalScroller(WMScrollView * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000383{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200384 return sPtr->hScroller;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000385}
386
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200387WMScroller *WMGetScrollViewVerticalScroller(WMScrollView * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000388{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200389 return sPtr->vScroller;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000390}
391
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200392void WMSetScrollViewHasHorizontalScroller(WMScrollView * sPtr, Bool flag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000393{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200394 if (flag) {
395 if (sPtr->flags.hasHScroller)
396 return;
397 sPtr->flags.hasHScroller = 1;
398
399 sPtr->hScroller = WMCreateScroller(sPtr);
400 WMSetScrollerAction(sPtr->hScroller, doScrolling, sPtr);
401 /* make it a horiz. scroller */
402 WMResizeWidget(sPtr->hScroller, 2, 1);
403
404 if (W_VIEW_REALIZED(sPtr->view)) {
405 WMRealizeWidget(sPtr->hScroller);
406 }
407
408 reorganizeInterior(sPtr);
409
410 WMMapWidget(sPtr->hScroller);
411 } else {
412 if (!sPtr->flags.hasHScroller)
413 return;
414
415 WMUnmapWidget(sPtr->hScroller);
416 WMDestroyWidget(sPtr->hScroller);
417 sPtr->hScroller = NULL;
418 sPtr->flags.hasHScroller = 0;
419
420 reorganizeInterior(sPtr);
421 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000422}
423
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200424void WMSetScrollViewHasVerticalScroller(WMScrollView * sPtr, Bool flag)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000425{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200426 if (flag) {
427 if (sPtr->flags.hasVScroller)
428 return;
429 sPtr->flags.hasVScroller = 1;
430
431 sPtr->vScroller = WMCreateScroller(sPtr);
432 WMSetScrollerAction(sPtr->vScroller, doScrolling, sPtr);
433 WMSetScrollerArrowsPosition(sPtr->vScroller, WSAMaxEnd);
434 /* make it a vert. scroller */
435 WMResizeWidget(sPtr->vScroller, 1, 2);
436
437 if (W_VIEW_REALIZED(sPtr->view)) {
438 WMRealizeWidget(sPtr->vScroller);
439 }
440
441 reorganizeInterior(sPtr);
442
443 WMMapWidget(sPtr->vScroller);
444 } else {
445 if (!sPtr->flags.hasVScroller)
446 return;
447 sPtr->flags.hasVScroller = 0;
448
449 WMUnmapWidget(sPtr->vScroller);
450 WMDestroyWidget(sPtr->vScroller);
451 sPtr->vScroller = NULL;
452
453 reorganizeInterior(sPtr);
454 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000455}
456
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200457void WMSetScrollViewContentView(WMScrollView * sPtr, WMView * view)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000458{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200459 assert(sPtr->contentView == NULL);
6830b057 dan2004-10-12 21:28:27 +0000460
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200461 sPtr->contentView = view;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000462
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200463 W_ReparentView(sPtr->contentView, sPtr->viewport, 0, 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000464
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200465 if (sPtr->flags.hasHScroller) {
466 float prop;
6830b057 dan2004-10-12 21:28:27 +0000467
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200468 prop = (float)sPtr->viewport->size.width / sPtr->contentView->size.width;
469 WMSetScrollerParameters(sPtr->hScroller, 0, prop);
470 }
471 if (sPtr->flags.hasVScroller) {
472 float prop;
6830b057 dan2004-10-12 21:28:27 +0000473
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200474 prop = (float)sPtr->viewport->size.height / sPtr->contentView->size.height;
6830b057 dan2004-10-12 21:28:27 +0000475
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200476 WMSetScrollerParameters(sPtr->vScroller, 0, prop);
477 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000478}
479
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200480void WMSetScrollViewRelief(WMScrollView * sPtr, WMReliefType type)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000481{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200482 sPtr->flags.relief = type;
6830b057 dan2004-10-12 21:28:27 +0000483
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200484 reorganizeInterior(sPtr);
6830b057 dan2004-10-12 21:28:27 +0000485
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200486 if (sPtr->view->flags.mapped)
487 paintScrollView(sPtr);
6830b057 dan2004-10-12 21:28:27 +0000488
9d2e6ef9 scottc1998-09-29 22:36:29 +0000489}
490
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200491static void paintScrollView(ScrollView * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000492{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200493 W_DrawRelief(sPtr->view->screen, sPtr->view->window, 0, 0,
494 sPtr->view->size.width, sPtr->view->size.height, sPtr->flags.relief);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000495}
496
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200497static void updateScrollerProportion(ScrollView * sPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000498{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200499 float prop, value;
500 float oldV, oldP;
501
502 if (sPtr->flags.hasHScroller) {
503 oldV = WMGetScrollerValue(sPtr->hScroller);
504 oldP = WMGetScrollerKnobProportion(sPtr->hScroller);
505
506 prop = (float)sPtr->viewport->size.width / (float)sPtr->contentView->size.width;
507
508 if (oldP == 1.0)
509 value = 0;
510 else
511 value = (prop * oldV) / oldP;
512 WMSetScrollerParameters(sPtr->hScroller, value, prop);
513 }
514 if (sPtr->flags.hasVScroller) {
515 oldV = WMGetScrollerValue(sPtr->vScroller);
516 oldP = WMGetScrollerKnobProportion(sPtr->vScroller);
517
518 prop = (float)sPtr->viewport->size.height / (float)sPtr->contentView->size.height;
519
520 if (oldP == 1.0)
521 value = 0;
522 else
523 value = (prop * oldV) / oldP;
524 WMSetScrollerParameters(sPtr->vScroller, value, prop);
525 }
526 applyScrollerValues(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000527}
528
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200529static void handleViewportEvents(XEvent * event, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000530{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200531 ScrollView *sPtr = (ScrollView *) data;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000532
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200533 if (sPtr->contentView && event->xconfigure.window == sPtr->contentView->window)
534 updateScrollerProportion(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000535}
536
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200537static void handleEvents(XEvent * event, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000538{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200539 ScrollView *sPtr = (ScrollView *) data;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000540
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200541 CHECK_CLASS(data, WC_ScrollView);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000542
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200543 switch (event->type) {
544 case Expose:
545 if (event->xexpose.count != 0)
546 break;
547 if (event->xexpose.serial == 0) /* means it's artificial */
548 W_RedisplayView(sPtr->contentView);
549 else
550 paintScrollView(sPtr);
551 break;
6830b057 dan2004-10-12 21:28:27 +0000552
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200553 case DestroyNotify:
554 destroyScrollView(sPtr);
555 break;
6830b057 dan2004-10-12 21:28:27 +0000556
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200557 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000558}
559
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200560static void destroyScrollView(ScrollView * sPtr)
6830b057 dan2004-10-12 21:28:27 +0000561{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200562 wfree(sPtr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000563}