scroller.c
来自「SEAL是DOS 下的32位保护模式的GUI程序」· C语言 代码 · 共 1,223 行 · 第 1/2 页
C
1,223 行
/******************************************************************
* SEAL 2.0 *
* Copyright (c) 1999-2002 SEAL Developers. All Rights Reserved. *
* *
* Web site: http://sealsystem.sourceforge.net/ *
* E-mail (current maintainer): orudge@users.sourceforge.net *
******************************************************************/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <seal.h>
#include <scroller.h>
#include <math.h>
l_bool scroll_after = false;
/*
0 3d_face="200, 200, 200"
1 3d_light="255, 255, 255"
2 3d_shadow="128, 128, 128"
3 3d_dark="32, 32, 32"
*/
p_scroller (*scroller_init) ( p_scroller o, t_rect r, l_int flags ) = &_scroller_init;
p_vscrollbar (*vscrollbar_init) ( p_vscrollbar o, t_rect r, p_scroller f ) = &_vscrollbar_init;
p_hscrollbar (*hscrollbar_init) ( p_hscrollbar o, t_rect r, p_scroller f ) = &_hscrollbar_init;
/* vscrollbar functions */
void vscrollbar_translate_event ( p_object o, t_event *event )
{
p_vscrollbar vsb = VSCROLLBAR(o);
RETVIEW(o, event);
view_translate_event(o, event);
if ( !vsb->scroller && vsb->scroller->deltax <= 0 )
return; /* if hasn't scroller or deltax <= 0 */
if ( event->type & EV_MOUSE && OBJECT(mouse)->state & MO_SF_MOUSELDOWN ) {
p_scroller scr = SCROLLER(vsb->scroller);
p_vscrollbar so = VSCROLLBAR(o);
t_point ml = VIEW(o)->get_local_point(VIEW(o), mouse->where);
t_rect s = VIEW(o)->size_limits(VIEW(o));
l_rect size = vsb->get_bar_size(vsb);
l_rect pos = vsb->get_bar_pos(vsb);
l_long maxy = 0;
scr->max_moves(scr, 0, &maxy);
if ( ml.y > pos && ml.y < pos + STANDARD_SCROLLBUTTON_SIZE ) { /* UP scrolling by 1 */
/* UP scrolling by 1*/
#define ok_scroll_up ((OBJECT(mouse)->state & MO_SF_MOUSELPRESS) && (scr->scrolly > 0))
while ( ok_scroll_up ) {
l_rect pos_mouse;
t_point p;
scr->scroll_place(scr, 0, -scr->deltay, (vsb->flags & SBF_SCROLL_AFTER_MOVE)); /* up scrolling */
clear_event(event);
o->get_event(o, event); /* get events */
if ( !ok_scroll_up )
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
pos_mouse = vsb->get_bar_pos(vsb)+(STANDARD_SCROLLBUTTON_SIZE/2);
p = point_assign(s.a.x+rect_sizex(s)/2, pos_mouse);
mouse->set_pos(mouse, VIEW(o)->get_global_point(VIEW(o), p));
};
} else
if ( ml.y < pos + size &&
ml.y > pos + size - STANDARD_SCROLLBUTTON_SIZE ) { /* DOWN scrolling by 1 */
/* DOWN scrolling by 1*/
#define ok_scroll_down ((OBJECT(mouse)->state & MO_SF_MOUSELPRESS) && (scr->scrolly < maxy))
while ( ok_scroll_down ) {
l_rect size;
l_rect pos_mouse;
t_point p;
scr->scroll_place(scr, 0, scr->deltay, (vsb->flags & SBF_SCROLL_AFTER_MOVE)); /* down scrolling */
clear_event(event);
o->get_event(o, event); /* get events */
if ( !ok_scroll_down )
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
size = vsb->get_bar_size(vsb);
pos_mouse = vsb->get_bar_pos(vsb)+size-(STANDARD_SCROLLBUTTON_SIZE/2);
p = point_assign(s.a.x+rect_sizex(s)/2, pos_mouse);
mouse->set_pos(mouse, VIEW(o)->get_global_point(VIEW(o), p));
};
} else
if ( ml.y > pos + STANDARD_SCROLLBUTTON_SIZE &&
ml.y < pos + size - STANDARD_SCROLLBUTTON_SIZE ) { /* 2 sides scrolling */
l_rect oldy = ml.y;
/* UPDOWN scrolling */
#define ok_scroll_updown (!(OBJECT(mouse)->state & MO_SF_MOUSELUP))
while ( ok_scroll_updown ) {
if ( ml.y != oldy ) { /* */
scr->scroll_place(scr, 0, so->get_real_pos(so, ml.y)-so->get_real_pos(so, oldy), (vsb->flags & SBF_SCROLL_AFTER_MOVE));
};
oldy = ml.y;
o->get_event(o, event); /* get events */
if ( !ok_scroll_updown ) /* scroll after */
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
ml = VIEW(o)->get_local_point(VIEW(o), mouse->where);
};
};
};
};
t_rect vscrollbar_size_limits ( p_view o )
{
t_rect r = o->get_local_extent(o);
return rect_assign(r.a.x+1, r.a.y+1, r.b.x-1, r.b.y-1);
};
t_point vscrollbar_size_minimum ( p_view o )
{
return point_assign(MINIMUM_SCROLLBAR_WIDTH, MINIMUM_SCROLLBAR_SIZE);
};
void vscrollbar_draw ( p_view o )
{
t_rect r = o->get_local_extent(o);
t_point p;
BITMAP *out = o->begin_paint(o, &p, r);
if ( out ) {
o->background(o, out, rect_move(r, p.x, p.y));
rectfill(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_face);
// light_image ( out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, 20, 20, 20);
button(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_shadow, color_3d_light);
VSCROLLBAR(o)->draw_bar(VSCROLLBAR(o));
};
o->end_of_paint(o, r);
};
void vscrollbar_draw_bar ( p_vscrollbar o )
{
p_view vo = VIEW(o);
t_rect r = vo->size_limits(vo);
t_rect s = r;
t_point p;
l_rect pos = o->get_bar_pos(o);
l_rect size = o->get_bar_size(o);
BITMAP *out;
r = rect_assign(r.a.x, r.a.y+pos, r.b.x, min(r.b.y, r.a.y+pos+size));
out = vo->begin_paint(vo, &p, r);
if ( out ) {
l_color bcolor = color_3d_face;
l_int minush = 8;
l_int plush = 8;
GrFONT *font = get_font_in_size("Symbols", 8, 8);
//if (!vo->brush.skin) {
rectfill(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, bcolor);
button( out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_light, color_3d_shadow);
draw_double_text(out, font, "f", -1, r.a.x+p.x+1, r.a.y+p.y,
r.b.x+p.x, r.a.y+p.y+minush, TX_ALIGN_CENTER, color_3d_light, color_3d_shadow, 0);
draw_double_text(out, font, "g", -1, r.a.x+p.x+1, r.b.y+p.y-plush,
r.b.x+p.x, r.b.y+p.y, TX_ALIGN_CENTER, color_3d_light, color_3d_shadow, 0);
/*} else {
blit(VIEW(o)->brush.skin, out, 0, 0, r.a.x+p.x, r.a.y+p.y, 15, 10);
stretch_blit(VIEW(o)->brush.skin, out, 0, 10, 15, 10, r.a.x+p.x, r.a.y+p.y+10, 15, rect_sizey(r)-19);
blit(VIEW(o)->brush.skin, out, 0, 20, r.a.x+p.x, r.b.y+p.y-9, 15, 10);
};*/
};
vo->end_of_paint(vo, r);
};
l_rect vscrollbar_get_bar_size ( p_vscrollbar o )
{
if ( o->scroller ) {
l_rect sizey = rect_sizey(VIEW(o)->size_limits(VIEW(o)));
l_rect sizey_scroller = rect_sizey(o->scroller->scroll_limits(o->scroller));
l_long maxy = 0;
l_rect size;
o->scroller->scroll_size(o->scroller, NULL, &maxy);
size = lmax(MINIMUM_SCROLLBOX_SIZE, (l_rect)((double)sizey*((double)sizey_scroller/(double)(lmax(1, maxy)))));
return size;
};
return 0;
};
l_long vscrollbar_get_real_pos ( p_vscrollbar o, l_rect pos )
{
l_long i = 0;
l_long m_x = 0;
l_long m_y = 0;
t_rect s = VIEW(o)->size_limits(VIEW(o));
if ( !o->scroller ) return i;
o->scroller->scroll_size(o->scroller, &m_x, &m_y);
if ( rect_sizey(s) && m_y ) {
double y = ((double)m_y / (double)max(1, rect_sizey(s))) * (double)pos;
y = (ceil(y / max(1, o->scroller->deltay))*o->scroller->deltay);
i = (l_long)y;
};
return i;
};
l_rect vscrollbar_get_bar_pos ( p_vscrollbar o )
{
if ( o->scroller ) {
l_rect sizey = rect_sizey(VIEW(o)->size_limits(VIEW(o)));
l_rect sizey_scroller = rect_sizey(o->scroller->scroll_limits(o->scroller));
l_long maxy = 0;
l_long sy = o->scroller->scrolly;
l_rect pos;
l_rect size;
l_int dy = 0;
o->scroller->scroll_size(o->scroller, NULL, &maxy);
size = (l_rect)((double)sizey*((double)sizey_scroller/(double)(lmax(1, maxy))));
if ( size < MINIMUM_SCROLLBOX_SIZE ) dy = MINIMUM_SCROLLBOX_SIZE-size;
pos = (l_rect)((double)(sizey-dy)*((double)sy/(double)(max(1, maxy))));
if ( pos+size > sizey ) pos = lmax(0, sizey-size);
return pos;
};
return 0;
};
/* hscrollbar functions */
void hscrollbar_translate_event ( p_object o, t_event *event )
{
p_hscrollbar hsb = HSCROLLBAR(o);
RETVIEW(o, event);
view_translate_event(o, event);
if ( !hsb->scroller && hsb->scroller->deltax <= 0 )
return; /* if hasn't scroller or deltax <= 0 */
if ( event->type & EV_MOUSE && OBJECT(mouse)->state & MO_SF_MOUSELDOWN ) {
p_scroller scr = SCROLLER(hsb->scroller);
p_hscrollbar so = HSCROLLBAR(o);
t_point ml = VIEW(o)->get_local_point(VIEW(o), mouse->where);
t_rect s = VIEW(o)->size_limits(VIEW(o));
l_rect size = hsb->get_bar_size(hsb);
l_rect pos = hsb->get_bar_pos(hsb);
l_long maxx = 0;
scr->max_moves(scr, &maxx, 0);
if ( ml.x > pos && ml.x < pos + STANDARD_SCROLLBUTTON_SIZE ) { /* LEFT scrolling by 1 */
/* LEFT scrolling by 1*/
#define ok_scroll_left ((OBJECT(mouse)->state & MO_SF_MOUSELPRESS) && (scr->scrollx > 0))
while ( ok_scroll_left ) {
l_rect pos_mouse;
t_point p;
scr->scroll_place(scr, -scr->deltax, 0, (hsb->flags & SBF_SCROLL_AFTER_MOVE)); /* left scrolling */
clear_event(event);
o->get_event(o, event); /* get events */
if ( !ok_scroll_left )
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
pos_mouse = hsb->get_bar_pos(hsb)+(STANDARD_SCROLLBUTTON_SIZE/2);
p = point_assign(pos_mouse, s.a.y+rect_sizey(s)/2);
mouse->set_pos(mouse, VIEW(o)->get_global_point(VIEW(o), p));
};
} else
if ( ml.x < pos + size &&
ml.x > pos + size - STANDARD_SCROLLBUTTON_SIZE ) { /* RIGHT scrolling by 1 */
/* RIGHT scrolling by 1*/
#define ok_scroll_right ((OBJECT(mouse)->state & MO_SF_MOUSELPRESS) && (scr->scrollx < maxx))
while ( ok_scroll_right ) {
l_rect size;
l_rect pos_mouse;
t_point p;
scr->scroll_place(scr, scr->deltax, 0, (hsb->flags & SBF_SCROLL_AFTER_MOVE)); /* right scrolling */
clear_event(event);
o->get_event(o, event); /* get events */
if ( !ok_scroll_right )
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
size = hsb->get_bar_size(hsb);
pos_mouse = hsb->get_bar_pos(hsb)+size-(STANDARD_SCROLLBUTTON_SIZE/2);
p = point_assign(pos_mouse, s.a.y+rect_sizey(s)/2);
mouse->set_pos(mouse, VIEW(o)->get_global_point(VIEW(o), p));
};
} else
if ( ml.x > pos + STANDARD_SCROLLBUTTON_SIZE &&
ml.x < pos + size - STANDARD_SCROLLBUTTON_SIZE ) { /* 2 sides scrolling */
l_rect oldx = ml.x;
/* LEFTRIGHT scrolling */
#define ok_scroll_leftright (!(OBJECT(mouse)->state & MO_SF_MOUSELUP))
while ( ok_scroll_leftright ) {
if ( ml.x != oldx ) { /* */
scr->scroll_place(scr, so->get_real_pos(so, ml.x)-so->get_real_pos(so, oldx), 0, (hsb->flags & SBF_SCROLL_AFTER_MOVE));
};
oldx = ml.x;
o->get_event(o, event); /* get events */
if ( !ok_scroll_leftright ) /* scroll after */
scr->scroll_place(scr, 0, 0, SCROLL_NOW); /* scroll if SBF_SCROLL_AFTER_MOVE is set */
ml = VIEW(o)->get_local_point(VIEW(o), mouse->where);
};
};
};
};
t_rect hscrollbar_size_limits ( p_view o )
{
t_rect r = o->get_local_extent(o);
return rect_assign(r.a.x+1, r.a.y+1, r.b.x-1, r.b.y-1);
};
t_point hscrollbar_size_minimum ( p_view o )
{
return point_assign(MINIMUM_SCROLLBAR_SIZE, MINIMUM_SCROLLBAR_WIDTH);
};
void hscrollbar_draw ( p_view o )
{
t_rect r = o->get_local_extent(o);
t_point p;
BITMAP *out = o->begin_paint(o, &p, r);
if ( out ) {
o->background(o, out, rect_move(r, p.x, p.y));
rectfill(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_face);
button(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_shadow, color_3d_light);
HSCROLLBAR(o)->draw_bar(HSCROLLBAR(o));
};
o->end_of_paint(o, r);
};
void hscrollbar_draw_bar ( p_hscrollbar o )
{
p_view vo = VIEW(o);
t_rect r = vo->size_limits(vo);
t_point p;
l_rect pos = o->get_bar_pos(o);
l_rect size = o->get_bar_size(o);
BITMAP *out;
r = rect_assign(r.a.x+pos, r.a.y, min(r.b.x, r.a.x+pos+size), r.b.y);
out = vo->begin_paint(vo, &p, r);
if ( out ) {
l_color bcolor = color_3d_face;
GrFONT *font = get_font_in_size("Symbols", 8, 8);
l_int minusw = FONT_GETWIDTH(font, '!');
l_int plusw = FONT_GETWIDTH(font, '"');
if ( plusw > minusw ) minusw = plusw;
// if (!vo->brush.skin) {
rectfill(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, bcolor);
button(out, r.a.x+p.x, r.a.y+p.y, r.b.x+p.x, r.b.y+p.y, color_3d_light, color_3d_shadow);
draw_double_text(out, font, "e", -1, r.a.x+p.x, r.a.y+p.y,
r.a.x+p.x+minusw+1, r.b.y+p.y, TX_ALIGN_CENTER, color_3d_light, color_3d_shadow, 0);
draw_double_text(out, font, "b", -1, r.b.x+p.x-plusw-1, r.a.y+p.y,
r.b.x+p.x, r.b.y+p.y, TX_ALIGN_CENTER, color_3d_light, color_3d_shadow, 0);
/* } else {
blit(vo->brush.skin, out, 0, 0, r.a.x+p.x, r.a.y+p.y, 10, 15);
stretch_blit(vo->brush.skin, out, 10, 0, 10, 15, r.a.x+p.x+10, r.a.y+p.y, rect_sizex(r)-19, 15);
blit(vo->brush.skin, out, 20, 0, r.b.x+p.x-9, r.a.y+p.y, 10, 15);
};*/
};
vo->end_of_paint(vo, r);
};
l_rect hscrollbar_get_bar_size ( p_hscrollbar o )
{
if ( o->scroller ) {
l_rect sizex = rect_sizex(VIEW(o)->size_limits(VIEW(o)));
l_rect sizex_scroller = rect_sizex(o->scroller->scroll_limits(o->scroller));
l_long maxx;
l_rect size;
o->scroller->scroll_size(o->scroller, &maxx, NULL);
size = lmax(MINIMUM_SCROLLBOX_SIZE, (l_rect)((double)sizex*((double)sizex_scroller/(double)(max(1, maxx)))));
return size;
};
return 0;
};
l_long hscrollbar_get_real_pos ( p_hscrollbar o, l_rect pos )
{
l_long i = 0;
l_long m_x = 0;
l_long m_y = 0;
t_rect s = VIEW(o)->size_limits(VIEW(o));
if ( !o->scroller ) return i;
o->scroller->scroll_size(o->scroller, &m_x, &m_y);
if ( rect_sizex(s) && m_x ) {
double x = ((double)m_x / max(1, (double)rect_sizex(s))) * (double)pos;
x = (ceil(x / max(1, o->scroller->deltax))*o->scroller->deltax);
i = (l_long)x;
};
return i;
};
l_rect hscrollbar_get_bar_pos ( p_hscrollbar o )
{
if ( o->scroller ) {
l_rect sizex = rect_sizex(VIEW(o)->size_limits(VIEW(o)));
l_rect sizex_scroller = rect_sizex(o->scroller->scroll_limits(o->scroller));
l_long maxx;
l_rect pos;
l_rect size;
l_int dx = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?