在Windows环境中,图形用户界面(GUI)库的选择日益增多,但GT库以其独特的优势脱颖而出。GT库的代码大部分是平台独立的,仅直接依赖于操作系统的图形、线程和剪贴板API(这些特性被封装)。尽管GUI系统众多,但GT库的创建是为了解决一些主要竞争对手的不足之处,同时保持了极高的紧凑性(GT库目前大约有90000行代码,包括注释)。由于代码行数如此之低,GT库可以直接嵌入到应用程序解决方案或项目文件中。其主要竞争对手包括MFC、QT、GIMP Toolkit、wxWidgets和Fox Toolkit。在设计和功能上,GT库与QT最为接近。
GtProject是GT库的一个新扩展,它为工程师提供了项目管理功能,使其能够将任务或项目管理功能集成到应用程序中。GtProject旨在为用户提供一个类似于Microsoft Project的控件,用于安排任务。
代码库的主要组件如下:
GtProjectView的界面如下:
// 示例代码
GtProjectView * m_ptrProject;
// 在InitializeControls()中
m_ptrProject = new GtProjectView(this);
rectNew.xMin = 0; rectNew.xMax = 900; rectNew.yMin = 0; rectNew.yMax = 650;
m_ptrProject->Set_objFrame(rectNew);
this->AddSubWidget(m_ptrProject);
GtProjectView是可嵌套的。因此,如果想将其插入到标签页、框架等中,只需相应地设置父对象指针和AddSubWidget方法。例如,将项目查看器插入到框架中可能如下所示:
// 在InitializeControls()中
m_ptrProject = new GtProjectView(m_ptrProjFrame);
rectNew.xMin = 0; rectNew.xMax = 900; rectNew.yMin = 0; rectNew.yMax = 650;
m_ptrProject->Set_objFrame(rectNew);
m_ptrProjFrame->AddSubWidget(m_ptrProject);
控件的菜单包括“项目”和“任务”。“项目”菜单包含所有文档控制功能,如新建、打开、保存、另存为、关闭。“任务”菜单包含所有操作单个任务所需的命令。菜单项包括属性、添加任务、添加子任务、删除任务和删除所有任务。添加和删除是不言而喻的。任务属性会弹出所选任务的属性编辑器,如下所示:
要编辑日期,可以直接在编辑框中输入,或者点击相应日期的“sel”按钮启动日期选择器。这将启动日历视图日期选择对话框(如下所示)。编辑器的下半部分用于创建和删除任务之间的约束。要添加约束,请点击“添加”按钮,在列表视图中选择它,然后点击“Sel Target”选择与之相关的任务。点击“保存”以保存对约束的更改,然后选择另一个要编辑的约束。
GtProject的核心是可视化引擎,它以甘特图的形式显示信息。有必要讨论一下这是如何实现的,以理解GtProject的工作原理。查看器的甘特图部分有三个主要组件:视图、日期标尺和水平滚动条。日期标尺负责在视图顶部显示时间的划分。它与水平滚动条相连,其限制设置为基于日期标尺左上角的组合框的天数、月份或年份。根据当前的水平滚动位置,它确定第一个可见的天、月或年。下面展示了基于月份的计算代码片段示例。
// 设置时间线和光标开始
iYearStart = m_dtStart.Get_intYear();
iMonthStart = m_dtStart.Get_intMonth();
// 推进到视图开始,iCursor是从水平滚动条位置
for (i = 0; i < iCursor; i++) {
iMonthStart++;
if (iMonthStart > 12) {
iMonthStart = 1;
iYearStart++;
}
}
m_dtViewStart.Set_intYear(iYearStart);
m_dtViewStart.Set_intMonth(iMonthStart);
一旦确定了视图开始的位置,标尺OnPaint()算法就在视图顶部以固定间隔标记时间。月份的增量被确定为每月150像素。在视图中正确绘制任务是接下来要做的事情。要做到这一点,首先要做的是确定一个任务是否可见以便绘制。这是通过查询树视图来完成的,看看代表任务的节点是否可见。如果任务可见,代码会获取该树节点的框架。该节点的Y值用于任务,以便它们正确对齐。接下来,使用日期标尺中的一个实用函数GetDatePos()计算该节点的X值。
// 从树视图节点获取矩形,然后计算视图中任务的位置
GtRectI rectDraw = ptrNode->m_objFrame;
rectDraw.xMin = m_dateRuler->GetDatePos(ptrTask->Get_objStart());
rectDraw.xMax = m_dateRuler->GetDatePos(ptrTask->Get_objEnd());
rectDraw.yMin += 5;
rectDraw.yMax -= 5;
ptrTask->Set_objDrawFrame(rectDraw);
GetDatePos的工作方式类似于日期标尺绘制算法,它从视图开始推进时间到请求的日期时间,并返回该日期的X坐标。如果日期时间在视图之外,将返回适当的限制,以便任务的绘图矩形不会绘制到视图之外。值得注意的是,时间尺度的渲染由GtDateRuler完成,任务和约束的渲染由GtProjectView完成。
GtProject的目标是为用户提供一个封装的项目管理工作。现在,基线项目、任务、约束和甘特图查看器已经可以运行,作者将开始使GtProject更像Microsoft。第一个任务将是实现Microsoft Project的自动平衡功能,它会自动移动开始日期以遵守任务之间的约束。接下来,将为任务添加资源和利用率计算。