Subversion Repositories Kolibri OS

Rev

Rev 3584 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * Copyright 2010 Vincent Sanders 
3
 *
4
 * Framebuffer windowing toolkit scrollbar widgets
5
 *
6
 * This file is part of NetSurf, http://www.netsurf-browser.org/
7
 *
8
 * NetSurf is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; version 2 of the License.
11
 *
12
 * NetSurf 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, see .
19
 */
20
 
21
 
22
#include 
23
 
24
#include 
25
#include 
26
#include 
27
#include 
28
 
29
#include "utils/log.h"
30
#include "desktop/browser.h"
31
 
32
#include "framebuffer/gui.h"
33
#include "framebuffer/fbtk.h"
34
#include "framebuffer/image_data.h"
35
 
36
 
37
 
38
#include "utils/log.h"
39
#include 
40
 
41
#include "widget.h"
42
 
43
/* Vertical scroll widget */
44
 
45
static int
46
vscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
47
{
48
		LOG(("REDRAW SCROLL"));
49
	//__menuet__debug_out("REDRAW SCROLL");
50
	int vscroll;
51
	int vpos;
52
 
53
	nsfb_bbox_t bbox;
54
	nsfb_bbox_t rect;
55
 
56
			LOG(("REDRAW SCROLL get rooot"));
57
	//__menuet__debug_out("REDRAW SCROLL get root");
58
	fbtk_widget_t *root = fbtk_get_root_widget(widget);
59
 
60
 
61
		LOG(("REDRAW SCROLL get bbox"));
62
	//__menuet__debug_out("REDRAW SCROLL get bbox");
63
	fbtk_get_bbox(widget, &bbox);
64
 
65
		LOG(("REDRAW SCROLL claim"));
66
	//__menuet__debug_out("REDRAW SCROLL claim");
67
	nsfb_claim(root->u.root.fb, &bbox);
68
 
69
	rect = bbox;
70
 
71
	/* background */
72
	//STUB
73
 
74
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
75
 
76
	/* scroll well */
77
	rect.x0 = bbox.x0 + 2;
78
	rect.y0 = bbox.y0 + 1;
79
	rect.x1 = bbox.x1 - 3;
80
	rect.y1 = bbox.y1 - 2;
81
 
82
 
83
	//STUB!!!
84
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
85
	nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
86
 
87
		LOG(("REDRAW SCROLL widg"));
88
	//__menuet__debug_out("REDRAW SCROLL widg");
89
 
90
	/* scroll bar */
91
	if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
92
		vscroll = ((widget->height - 4) * widget->u.scroll.thumb) /
93
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
94
		vpos = ((widget->height - 4) * widget->u.scroll.position) /
95
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
96
	} else {
97
		vscroll = (widget->height - 4);
98
		vpos = 0;
99
	}
100
 
101
	rect.x0 = bbox.x0 + 5;
102
	rect.y0 = bbox.y0 + 3 + vpos;
103
	rect.x1 = bbox.x0 + widget->width - 5;
104
	rect.y1 = bbox.y0 + vscroll + vpos;
105
 
106
	//STUB!!!
107
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
108
 
109
		LOG(("REDRAW SCROLL upd"));
110
	//__menuet__debug_out("RED upd");
111
 
112
//STUB
113
	nsfb_update(root->u.root.fb, &bbox); //&bbox
114
 
115
	return 0;
116
}
117
 
118
static int
119
vscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi)
120
{
121
 
122
		LOG(("REDRAG SCROLL"));
123
	//__menuet__debug_out("REDRAG SCROLL");
124
	int newpos;
125
	fbtk_widget_t *scrollw = cbi->context;
126
 
127
	newpos = ((widget->u.scroll.drag_position +
128
			(cbi->y - widget->u.scroll.drag)) *
129
			(widget->u.scroll.maximum - widget->u.scroll.minimum)) /
130
			(widget->height - 4);
131
 
132
	if (newpos < scrollw->u.scroll.minimum)
133
		newpos = scrollw->u.scroll.minimum;
134
 
135
	if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
136
		newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
137
 
138
	if (newpos == scrollw->u.scroll.position)
139
		return 0;
140
 
141
	return fbtk_post_callback(widget, FBTK_CBT_SCROLLY, newpos);
142
}
143
 
144
static int
145
vscrollu_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
146
{
147
 
148
		LOG(("REDRAW Ck SCROLL"));
149
	//__menuet__debug_out("REDRAW Ck SCROLL");
150
	int newpos;
151
	fbtk_widget_t *scrollw = cbi->context;
152
 
153
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
154
		return 0;
155
 
156
	newpos = scrollw->u.scroll.position - scrollw->u.scroll.page;
157
	if (newpos < scrollw->u.scroll.minimum)
158
		newpos = scrollw->u.scroll.minimum;
159
 
160
	if (newpos ==  scrollw->u.scroll.position)
161
		return 0;
162
 
163
	return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos);
164
}
165
 
166
static int
167
vscrolld_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
168
{
169
 
170
		LOG(("REDRAW SCROLL 2"));
171
	//__menuet__debug_out("REDRAW SCROLL 2");
172
	int newpos;
173
	fbtk_widget_t *scrollw = cbi->context;
174
 
175
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
176
		return 0;
177
 
178
	newpos = scrollw->u.scroll.position + scrollw->u.scroll.page;
179
	if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
180
		newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
181
 
182
	if (newpos == scrollw->u.scroll.position)
183
		return 0;
184
 
185
	return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos);
186
}
187
 
188
static int
189
vscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
190
{
191
		LOG(("REDRAW SCROLL 3"));
192
	//__menuet__debug_out("REDRAW SCROLL 3");
193
	int vscroll;
194
	int vpos;
195
	int newpos;
196
	int ret = 0;
197
 
198
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN) {
199
		/* end all drags, just in case */
200
		if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL)
201
			fbtk_tgrab_pointer(widget);
202
		return 0;
203
	}
204
 
205
	switch (cbi->event->value.keycode) {
206
 
207
	case NSFB_KEY_MOUSE_4:
208
		/* scroll up */
209
		newpos = widget->u.scroll.position - widget->u.scroll.page;
210
		if (newpos < widget->u.scroll.minimum)
211
			newpos = widget->u.scroll.minimum;
212
		ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
213
		break;
214
 
215
	case NSFB_KEY_MOUSE_5:
216
		/* scroll down */
217
		newpos = widget->u.scroll.position + widget->u.scroll.page;
218
		if (newpos > widget->u.scroll.maximum)
219
			newpos = widget->u.scroll.maximum;
220
		ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
221
		break;
222
 
223
	default:
224
 
225
		if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
226
			vscroll = ((widget->height - 4) * widget->u.scroll.thumb) /
227
				(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
228
			vpos = ((widget->height - 4) * widget->u.scroll.position) /
229
				(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
230
		} else {
231
			vscroll = (widget->height - 4);
232
			vpos = 0;
233
		}
234
 
235
		if (cbi->y < vpos) {
236
			/* above bar */
237
			newpos = widget->u.scroll.position - widget->u.scroll.thumb;
238
			if (newpos < widget->u.scroll.minimum)
239
				newpos = widget->u.scroll.minimum;
240
			ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
241
		} else if (cbi->y > (vpos + vscroll)) {
242
			/* below bar */
243
			newpos = widget->u.scroll.position + widget->u.scroll.thumb;
244
			if (newpos > widget->u.scroll.maximum)
245
				newpos = widget->u.scroll.maximum;
246
			ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos);
247
		} else {
248
			/* on bar - start drag */
249
			widget->u.scroll.drag = cbi->y;
250
			widget->u.scroll.drag_position = vpos;
251
			fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, vscroll_drag, widget);
252
			fbtk_tgrab_pointer(widget);
253
		}
254
	}
255
	return ret;
256
}
257
 
258
 
259
/* exported function documented in fbtk.h */
260
fbtk_widget_t *
261
fbtk_create_vscroll(fbtk_widget_t *parent,
262
		    int x,
263
		    int y,
264
		    int width,
265
		    int height,
266
		    colour fg,
267
		    colour bg,
268
		    fbtk_callback callback,
269
		    void *context)
270
{
271
 
272
		LOG(("REDRAW SCROLL 4"));
273
	//__menuet__debug_out("REDRAW SCROLL 4");
274
	fbtk_widget_t *neww;
275
 
276
	neww = fbtk_widget_new(parent,
277
			       FB_WIDGET_TYPE_VSCROLL,
278
			       x,
279
			       y + scrollu.height,
280
			       width,
281
			       height  - scrollu.height - scrolld.height);
282
 
283
	neww->fg = fg;
284
	neww->bg = bg;
285
	neww->mapped = true;
286
 
287
	fbtk_set_handler(neww, FBTK_CBT_REDRAW, vscroll_redraw, NULL);
288
 
289
	fbtk_set_handler(neww, FBTK_CBT_CLICK, vscrollarea_click, neww);
290
 
291
	fbtk_set_handler(neww, FBTK_CBT_SCROLLY, callback, context);
292
 
293
	neww->u.scroll.btnul = fbtk_create_button(parent,
294
						  x,
295
						  y,
296
						  width,
297
						  scrollu.height,
298
						  fg,
299
						  &scrollu,
300
						  vscrollu_click,
301
						  neww);
302
 
303
	neww->u.scroll.btndr = fbtk_create_button(parent,
304
						  x,
305
						  y + height - scrolld.height,
306
						  width,
307
						  scrolld.height,
308
						  fg,
309
						  &scrolld,
310
						  vscrolld_click,
311
						  neww);
312
 
313
 
314
	return neww;
315
}
316
 
317
/* Horizontal scroll widget */
318
 
319
static int
320
hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
321
{
322
 
323
		LOG(("REDRAW SCROLL 5"));
324
	//__menuet__debug_out("REDRAW SCROLL 5");
325
	int hscroll;
326
	int hpos;
327
	nsfb_bbox_t bbox;
328
	nsfb_bbox_t rect;
329
	fbtk_widget_t *root = fbtk_get_root_widget(widget);
330
 
331
	fbtk_get_bbox(widget, &bbox);
332
 
333
	nsfb_claim(root->u.root.fb, &bbox);
334
 
335
	rect = bbox;
336
 
337
	/* background */
338
 
339
	//STUB
340
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
341
 
342
	/* scroll well */
343
	rect.x0 = bbox.x0 + 1;
344
	rect.y0 = bbox.y0 + 2;
345
	rect.x1 = bbox.x1 - 2;
346
	rect.y1 = bbox.y1 - 3;
347
 
348
	//STUB
349
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);
350
 
351
	/* scroll well outline */
352
	//STUB
353
	nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false);
354
 
355
	if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
356
		hscroll = ((widget->width - 4) * widget->u.scroll.thumb) /
357
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
358
		hpos = ((widget->width - 4) * widget->u.scroll.position) /
359
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
360
	} else {
361
		hscroll = (widget->width - 4);
362
		hpos = 0;
363
	}
364
 
365
	LOG(("hscroll %d", hscroll));
366
 
367
	rect.x0 = bbox.x0 + 3 + hpos;
368
	rect.y0 = bbox.y0 + 5;
369
	rect.x1 = bbox.x0 + hscroll + hpos;
370
	rect.y1 = bbox.y0 + widget->height - 5;
371
 
372
 
373
	//STUB
374
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);
375
 
376
	nsfb_update(root->u.root.fb, &bbox);
377
 
378
	return 0;
379
}
380
 
381
static int
382
hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
383
{
384
 
385
		LOG(("REDRAW SCROLL 6"));
386
	//__menuet__debug_out("REDRAW SCROLL 6");
387
	int newpos;
388
	fbtk_widget_t *scrollw = cbi->context;
389
 
390
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
391
		return 0;
392
 
393
	newpos = scrollw->u.scroll.position - scrollw->u.scroll.page;
394
	if (newpos < scrollw->u.scroll.minimum)
395
		newpos = scrollw->u.scroll.minimum;
396
 
397
	if (newpos == scrollw->u.scroll.position) {
398
		LOG(("horiz scroll was the same %d", newpos));
399
		return 0;
400
	}
401
 
402
	return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos);
403
}
404
 
405
static int
406
hscrollr_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
407
{
408
 
409
		LOG(("REDRAW SCROLL 7"));
410
	//__menuet__debug_out("REDRAW SCROLL 7");
411
	int newpos;
412
	fbtk_widget_t *scrollw = cbi->context;
413
 
414
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN)
415
		return 0;
416
 
417
	newpos = scrollw->u.scroll.position + scrollw->u.scroll.page;
418
	if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
419
		newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
420
 
421
	if (newpos == scrollw->u.scroll.position)
422
		return 0;
423
 
424
	return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos);
425
}
426
 
427
static int
428
hscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi)
429
{
430
 
431
		LOG(("REDRAW SCROLL 8"));
432
	//__menuet__debug_out("REDRAW SCROLL 8");
433
	int newpos;
434
	fbtk_widget_t *scrollw = cbi->context;
435
 
436
	newpos = ((widget->u.scroll.drag_position +
437
			(cbi->x - widget->u.scroll.drag)) *
438
			(widget->u.scroll.maximum - widget->u.scroll.minimum)) /
439
			(widget->width - 4);
440
 
441
	if (newpos < scrollw->u.scroll.minimum)
442
		newpos = scrollw->u.scroll.minimum;
443
 
444
	if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb ))
445
		newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb);
446
 
447
	if (newpos == scrollw->u.scroll.position)
448
		return 0;
449
 
450
	return fbtk_post_callback(widget, FBTK_CBT_SCROLLX, newpos);
451
}
452
 
453
static int
454
hscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
455
{
456
 
457
		LOG(("REDRAW SCROLL 9"));
458
	//__menuet__debug_out("REDRAW SCROLL 9");
459
	int hscroll;
460
	int hpos;
461
	int newpos;
462
	int ret = 0;
463
 
464
	if (cbi->event->type != NSFB_EVENT_KEY_DOWN) {
465
		/* end all drags, just in case */
466
		if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL)
467
			fbtk_tgrab_pointer(widget);
468
		return 0;
469
	}
470
 
471
	if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) {
472
		hscroll = ((widget->width - 4) * widget->u.scroll.thumb) /
473
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
474
		hpos = ((widget->width - 4) * widget->u.scroll.position) /
475
			(widget->u.scroll.maximum - widget->u.scroll.minimum) ;
476
	} else {
477
		hscroll = (widget->width - 4);
478
		hpos = 0;
479
	}
480
 
481
	if (cbi->x < hpos) {
482
		/* left of  bar */
483
		newpos = widget->u.scroll.position - widget->u.scroll.page;
484
		if (newpos < widget->u.scroll.minimum)
485
			newpos = widget->u.scroll.minimum;
486
		ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos);
487
	} else if (cbi->x > (hpos + hscroll)) {
488
		/* right of bar */
489
		newpos = widget->u.scroll.position + widget->u.scroll.page;
490
		if (newpos > widget->u.scroll.maximum)
491
			newpos = widget->u.scroll.maximum;
492
		ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos);
493
	} else {
494
		/* on bar - start drag */
495
		widget->u.scroll.drag = cbi->x;
496
		widget->u.scroll.drag_position = hpos;
497
		fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, hscroll_drag, widget);
498
		fbtk_tgrab_pointer(widget);
499
	}
500
	return ret;
501
}
502
 
503
/* exported function documented in fbtk.h */
504
fbtk_widget_t *
505
fbtk_create_hscroll(fbtk_widget_t *parent,
506
		    int x,
507
		    int y,
508
		    int width,
509
		    int height,
510
		    colour fg,
511
		    colour bg,
512
		    fbtk_callback callback,
513
		    void *context)
514
{
515
 
516
		LOG(("REDRAW SCROLL 10"));
517
	//__menuet__debug_out("REDRAW SCROLL 10");
518
	fbtk_widget_t *neww;
519
 
520
	neww = fbtk_widget_new(parent,
521
			       FB_WIDGET_TYPE_HSCROLL,
522
			       x + scrolll.width,
523
			       y,
524
			       width - scrolll.width - scrollr.width,
525
			       height);
526
 
527
	neww->fg = fg;
528
	neww->bg = bg;
529
	neww->mapped = true;
530
 
531
	fbtk_set_handler(neww, FBTK_CBT_REDRAW, hscroll_redraw, NULL);
532
	fbtk_set_handler(neww, FBTK_CBT_CLICK, hscrollarea_click, neww);
533
	fbtk_set_handler(neww, FBTK_CBT_SCROLLX, callback, context);
534
 
535
	neww->u.scroll.btnul = fbtk_create_button(parent,
536
						  x,
537
						  y,
538
						  scrolll.width,
539
						  height,
540
						  fg,
541
						  &scrolll,
542
						  hscrolll_click,
543
						  neww);
544
 
545
	neww->u.scroll.btndr = fbtk_create_button(parent,
546
						  x + width - scrollr.width,
547
						  y,
548
						  scrollr.width,
549
						  height,
550
						  fg,
551
						  &scrollr,
552
						  hscrollr_click,
553
						  neww);
554
 
555
	return neww;
556
}
557
 
558
 
559
/* exported function documented in fbtk.h */
560
bool
561
fbtk_set_scroll_parameters(fbtk_widget_t *widget,
562
			   int min,
563
			   int max,
564
			   int thumb,
565
			   int page)
566
{
567
		LOG(("REDRAW SCROLL 11"));
568
	//__menuet__debug_out("REDRAW SCROLL 11");
569
	if (widget == NULL)
570
		return false;
571
 
572
	if ((widget->type != FB_WIDGET_TYPE_HSCROLL) &&
573
	    (widget->type != FB_WIDGET_TYPE_VSCROLL))
574
		return false;
575
 
576
	widget->u.scroll.minimum = min;
577
	widget->u.scroll.maximum = max;
578
	widget->u.scroll.thumb = thumb;
579
	widget->u.scroll.page = page;
580
 
581
	if (widget->u.scroll.position > max)
582
		widget->u.scroll.position = max;
583
	if (widget->u.scroll.position < min)
584
		widget->u.scroll.position = min;
585
 
586
	fbtk_request_redraw(widget);
587
 
588
	return true;
589
}
590
 
591
/* exported function documented in fbtk.h */
592
bool
593
fbtk_set_scroll_position(fbtk_widget_t *widget, int position)
594
{
595
		LOG(("REDRAW SCROLL 12"));
596
	//__menuet__debug_out("REDRAW SCROLL 12");
597
	if (widget == NULL)
598
		return false;
599
 
600
	if ((widget->type != FB_WIDGET_TYPE_HSCROLL) &&
601
	    (widget->type != FB_WIDGET_TYPE_VSCROLL))
602
		return false;
603
 
604
	if ((position < widget->u.scroll.minimum) ||
605
	    (position > widget->u.scroll.maximum))
606
		return false;
607
 
608
	widget->u.scroll.position = position;
609
 
610
	fbtk_request_redraw(widget);
611
 
612
	return true;
613
}
614
 
615
/*
616
 * Local Variables:
617
 * c-basic-offset:8
618
 * End:
619
 */