现在的位置: 首页 > 综合 > 正文

自绘滚动条,滚动条模型,滚动条数据结构

2013年10月13日 ⁄ 综合 ⁄ 共 1612字 ⁄ 字号 评论关闭

最近作一个东西要自己做一个滚动条,决定用GDI自己绘制一个滚动条,然后加上鼠标键盘响应,做完了总结下滚动条的数据结构/模型,方便以后再用,或者方便有相同需求的同学。

 

本文讲述如何实现一个滚动条所用到的必要的数据结构和模型,方便自己去绘制一个滚动条,不是滚动条的入门或者使用教程。

关键字: 自绘滚动条,滚动条模型,滚动条数据结构,scrollbar data structure

 

<图> <CSDN不能传图现在,等能传在传上来>

 

绘制一个滚动条,我们必须绘制如下几个部分(如图):

1.一个向上按钮,一个向下按钮,用于鼠标单击让其滚动;
2.track:thumb所在的轨道,用以拖动滚动的轨道;
3.thumb:可以拖动滚动的部分(或者scroll box)

 

期中track和向上按钮,向下按钮位置大小都很容易确定(也比较固定),这里不讨论如何绘制这个部分。主要讨论如何绘制计算和绘制thumb,我们要确定thumb的大小和位置。

先定义一个结构体供我们设置绘制使用的数据(参考上图):

ScrollInfo {
  int min;
  int max; 
  int page; // 一页包含的unit数。
  int pos;  // 当前thumb位置。
};

 

Scroll Information(简称si)都是以数据模型为单位的,一般用整数表示。(比如,如果数据模型为文本,这个单位就可以是文本的行),这个单位我们统一抽象称为unit。 图中右边的信息单位都是unit(左边的数据信息都是pix,下面带_len的变量单位都是pix).

要决定如何绘制滚动,条我们就必须知道图中左边标注的信息,那就是track的长度,和thumb(也叫scroll box)的长度.
这个track就是thumb可滚动的地方,它的长度track_len等于整个滚动条长度减去两个滚动条上的按钮:
track_len = scrollbar_len - scroll_buttion_len * 2

 

上图中的si中的数据都是已知的(其中pos可能是滚动过程中算出,其他都是由用户设置的)。track的长度可以通过滚动条长度算出来,滚动条长度是创建时候决定的(或者窗口跟新后设置好的)。
于是我们就可以计算出thumb的长度了。从图中的关系可以明显的看出一个比例关系:
thumb_len / track_len = si.page / (si.max-si.min)
=> thumb_len = track_len * si.page / (si.max-si.min)

 

到此为止我们要绘制的部件的大小都知道了。那么如何决定thumb的位置呢?
thumb的位置是和si.pos对应的。
thumb的X坐标很容易确定,这里我们主要确定Y坐标,假设track y坐标为0,我们有:
thumb_y / track_len = si.pos / (si.max-si.min)
=> thumb_y = track_len * si.pos / (si.max-si.min)

至此我们就有了绘制整个滚动条的所有数据了。

当鼠标单击向上或向下按钮的时候,我们把si.pos加1 unit或减1 unit然后重新绘制thumb就好了。注意边界:
1. 当si.pos = < 0的时候,让si.pos = 0;
2. max_scroll_pos = (si.max-si.min) - (si.page - 1)
   当si.pos > max_scroll_pos 的时候,让si.pos = max_scroll_pos;

 

当鼠标拖动thumb时候,
1.记下鼠标拖动的距离drag_len,然后把thumb_y加上这个drag_len.
2.立即重绘thumb
3.通知滚动内容,滚动条发生滚动。
4.更新滚动内容。

 

更新滚动内容注意:
方法1.将滚动内容移动drag_len距离
方法2.drag_len < 1 unit, 内容不滚动,累加drag_len,直到drag_len > N unit, 将si.pos + N,然后update thumb.

抱歉!评论已关闭.