GT图形用户界面库与GtProject项目管理工具

在Windows环境中,图形用户界面(GUI)库的选择日益增多,但GT库以其独特的优势脱颖而出。GT库的代码大部分是平台独立的,仅直接依赖于操作系统的图形、线程和剪贴板API(这些特性被封装)。尽管GUI系统众多,但GT库的创建是为了解决一些主要竞争对手的不足之处,同时保持了极高的紧凑性(GT库目前大约有90000行代码,包括注释)。由于代码行数如此之低,GT库可以直接嵌入到应用程序解决方案或项目文件中。其主要竞争对手包括MFC、QT、GIMP Toolkit、wxWidgets和Fox Toolkit。在设计和功能上,GT库与QT最为接近。

GtProject是GT库的一个新扩展,它为工程师提供了项目管理功能,使其能够将任务或项目管理功能集成到应用程序中。GtProject旨在为用户提供一个类似于Microsoft Project的控件,用于安排任务。

GtProject设计概览

代码库的主要组件如下:

  • GtProjectView:这是查看GtProjectModel对象的主视图控件。它包含一个用于控制模型的菜单、一个用于查看任务的树视图、一个用于标记时间的日期标尺控件,以及一个用于显示甘特图的视图。
  • GtProjectModel:这个类包含了所有正在建模的任务。它具有使用HPC模板库(HTL)序列化引擎序列化自身的能力。原生存储格式是XDL。
  • GtProjectTask:这是主要的任务对象。它提供了任务的开始和结束日期,可以包含子任务,并具有与其他任务之间的约束。
  • GtProjectConstraint:这是两个任务之间的约束。下面展示了四种类型。在所有情况下,任务A是约束的所有者。它们共同将任务约束网络转变为有向无环图(DAG)。

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的核心是可视化引擎,它以甘特图的形式显示信息。有必要讨论一下这是如何实现的,以理解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的自动平衡功能,它会自动移动开始日期以遵守任务之间的约束。接下来,将为任务添加资源和利用率计算。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485