Click here to Skip to main content
15,867,308 members
Articles / Multimedia / GDI

GtProject: A C++ Project Management Control for GT Graphical User Interface Library

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
1 Mar 2017MIT6 min read 11.3K   500   5  
GtProject is intended to provide the user a Microsoft Project equivalent control to use for scheduling tasks.

Introduction

GT is a compact, efficient, and customizable graphical user interface (GUI) library for the Windows environment (eventually Linux and Mac will be added). The majority of the code is platform independent, only relying directly on the Operating System’s graphics, threading, and clipboard APIs (these features are encapsulated). With the number of GUI systems growing, one might ask why make another system. GT was made to address shortcomings in some of the major competitors in addition to being really compact (GT currently has approx. 90,000 lines of code, or LOC, including comments). With the LOC count this low, GT is possible to embed directly into your application solution or project files. Its major competitors are MFC, QT, GIMP Toolkit, wxWidgets, Fox Toolkit. GT most closely tracks with QT in design and function. For more information on GT, read the following article:

GtProject is a new addition to the greater GT library. As an engineer, I am constantly in need of project or task management functionality into my applications. GtProject is intended to provide the user a Microsoft Project equivalent control to use for scheduling tasks.

GtProject Design Overview

The major components of the code base are as follows:

  • GtProjectView is the main viewport control for viewing a GtProjectModel object. It contains a menu for controlling the model, a tree view for viewing tasks, a date ruler control for demarking time, and a viewport for showing the Gantt chart.
  • GtProjectModel is the class that contains all of the tasks being modelled. It possessed within it the ability to serialize itself using the HPC Template Library (HTL) serialization engine. For more information on the HTL, see the following article. The native storage format is XDL.
  • GtProjectTask is the main task object. It provides start and end dates for the task, can contain sub tasks, and have constraints between other tasks.
  • GtProjectConstraint is a constraint between two tasks. There are four types shown below. In all cases, Task A is the owner of the constraint. Collectively, they turn the task constraint network into a directed acyclic graph (DAG).
    • GtEndToBegin –from the end of task A to the beginning of task B
    • GtBeginToEnd – from the beginning of task A to the end of task B
    • GtBeginToBegin – from the beginning of task A to the beginning of task B
    • GtEndToEnd – from the end of task A to the end of task B

The GtProjectView looks like the following:

Image 1

Using the Code

Using GtProject is very simple. In any application that uses GT as the user interface, insert the following code into the InitializeControls() method of the GtDialog that is intended as the parent of the spreadsheet. You set the control size and add it to the sub-widget collection for that dialog.

C++
//in header file
GtProjectView * m_ptrProject;

//in 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);

Like with the rest of GT controls, the GtProjectView is nestable. So if you want to insert it into a tab page, frame, etc., you can do so. Just set the parent object pointer and the AddSubWidget method accordingly. For example, inserting the project viewer into a frame would look something like this:

C++
//in 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);

The menus for the control are Project and Task. The Project menu has all of the document control functions such as New, Open, Save, Save As, Close. The Task menu has all of the commands necessary to manipulate an individual task. The menu items are Properties, Add Task, Add Sub Task, Delete Task, and Delete All Tasks. The add and deletes are self-explanatory. Task Properties brings up the properties editor for the selected task which is shown below:

Image 2

To edit the dates, either type directly into the edit boxes or launch up the date selector by clicking the “sel” button for the appropriate date. This launches the calendar view date picker dialogue (shown below). The lower half of the editor is for creating and deleting constraints between tasks. To add a constraint, click the Add button, select it in the list view, then click “Sel Target” to pick the task it is related to. Click Save to save your changes to the constraint before selecting another one to edit.

Image 3

How GtProject Works (How to Draw a Gantt Chart)

At the heart of GtProject is the visualization engine that displays the information in a Gantt chart. Some discussion of how this was implemented is necessary to understand how GtProject works. The Gantt chart portion of the viewer has three primary components: the viewport, the date ruler, and the horizontal scroll bar. The date ruler is responsible for displaying the demarcations of time across the top of the viewport. It is hooked up to the horizontal scroll bar which has its limits set to the number of days, months or years based on the combobox that is in the upper left hand of the date ruler. Based on the current horizontal scroll position, it determines the first visible day, month, or year. Code snippet from the Month based calculations is shown for example.

C++
//set at timeline and cursor start
iYearStart = m_dtStart.Get_intYear();
iMonthStart = m_dtStart.Get_intMonth();

//advance to viewport start, iCursor is from the horizontal scrollbar position
for (i = 0; i < iCursor; i++)
{
    iMonthStart++;
    if (iMonthStart > 12)
    {
        iMonthStart = 1;
        iYearStart++;
    }
}

m_dtViewStart.Set_intYear(iYearStart);
m_dtViewStart.Set_intMonth(iMonthStart);

Once the position of the viewport start has been established, the rulers OnPaint() algorithm then mark time at regular intervals across the top of the viewport. The delta for Months was decided to be 150 pixels per month. Drawing the tasks correctly in the viewport is what remains. To accomplish this, the first thing to do is to determine whether a task is visible to be drawn. This is done by querying the tree view to see if the node that represents the task is visible. If the task is visible, the code gets the frame for that tree node. The Y values for that node are kept for the task so they line up correctly. Next, the x values for that node are calculated using a utility function in the date ruler called GetDatePos().

C++
//get the rect from the tree view node, then calculate task position in viewport
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 works similarly to the date ruler drawing algorithm where it advances time from the viewport beginning to requested date time and returns the x coordinate for that date. If the date time is outside of the viewport, the appropriate limit is returned such that the drawing rectangle for the task doesn’t draw outside the viewport. It should be noted that rendering of the time scale is done by the GtDateRuler and the rendering of the tasks and constraints is done by the GtProjectView.

Future Development

The goal of the GtProject is to provide the user with an encapsulated project management control. Now that the baseline project, tasks, constraints, and Gantt chart viewer are operational, the author is going to start making GtProject more Microsoft like. The first task will be to implement Microsoft Project’s Auto-Leveling feature where it automatically moves start dates to adhere to constraints between tasks. Next, resources and utilization calculations will be added to tasks.

History

  • 2nd March, 2017: Initial version

Author: Anthony Daniels

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --