• 其他语言



可移植和可重用 GUI 控件的设计
页面和feed选项
打印
收藏此页
Digg此页 | 添加到您的del.icio.us帐号
目录

自定义的外观和用户交互
通常您可以区别控件的两个部分,即区别数据元素与核心部分,数据元素表示数据的各个部分,核心部分负责将数据组织为一个整体。图表数据元素由节点和边组成。当需要时,核心部分会使用数据元素的自定义版本来提供一些功能,如滚动、缩放、绘图和事件处理。例如,当您单击鼠标按钮时,核心部分会定义这个事件发生的位置。如果事件发生在某个数据元素上,那么事件信息会传递到这个数据元素的处理程序,此外核心部分会处理事件本身。

图表中有两样东西项目会随着不同应用程序而改变,您应当进行自定义。一个是数据元素的外观与行为;另一个是组织元素的方式。如果要很容易地自定义控件,就需要为这些东西定义界面,然后仅通过界面将这些东西用于控件。所以,如果要进行某种更改,只需要采用新的方式实现界面,无需更改控件中的代码。这就是所谓的“策略”模式。

图表控件采用了以下策略:

  1. INodeHandler

  2. IEdgeHandler

  3. ILayout
class INodeHandler
{
public:
// 绘制给定的节点
	virtual void Draw(Node) = 0;

// 返回描述正方形的尺寸。此函数在布局中用来确定
// 节点位置,没有交叉点。
	virtual idvc::dsize GetSize(Node)= 0;

// 设置所有后续 Draw 调用函数中要使用的缩放系数。此函数
// 在实现缩放时由控件的核心部分使用。
	virtual void SetZoomFactor(double f) {};

// 处理鼠标单击事件
virtual ChangesType HandleClick(Node n, double inX, double inY,
int kstate, idvc::MouseButton Button);

	// 处理工具提示事件
virtual ChangesType HandleOnTooltip(Node n, CGraphTooltipEvent* pEvent);

}; // 结束 INodeHandler
      
 

class ILayout
{
public:

/// 这个函数应为给定节点内的所有节点
/// 生成新布局,并计算新布局的尺寸。内部节点的位置
/// 必须根据给定节点的左上角进行定义,
/// 假使给定节点的坐标是 (0,0)。
virtual void Make( Node ) = 0;

/// 与 Make 一样,但是应使用以前布局
/// 的信息,然后尝试保持已摆放节点
/// 的相对位置。
virtual void Update( Node ) = 0;

/// 这个函数在更改了已拥有节点的尺寸
/// 或跳过 ILayout 的参数时
	 /// 用于重新计算节点与边的坐标。
/// 它假定以前调用过 Make 或 Update,而且
/// 所有已拥有节点的尺寸。与 Make 和 Update 不同,它 
	 /// 不可递归。
virtual void Resize( Node ) = 0;
};

以上类定义了三种不同情况下的布局策略函数,即:

  • 图表需要完全重新排列时

  • 图表结构已部分更改,只需要重新排列更改部分时

  • 只有节点尺寸更改了,需要重新计算坐标(不需要定义节点和边的相对位置)时
定义这种区别的主要目的是为了减少布局计算时间。如果向某个大型图表中添加一个节点,就不需要重新计算整个图表的布局。

上一部分1  2  3  4  5  下一部分

第 3 页, 共 7 页