Subversion Repositories Kolibri OS

Rev

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