home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
msysjour
/
vol04
/
02b
/
project
/
classes
/
ganttwin.cls
< prev
next >
Wrap
Text File
|
1988-11-24
|
6KB
|
236 lines
/* Maintain a Gantt chart in a Window. The GanttWindow is
responsible for drawing the project.
GanttWindow descends from the Window class and inherits all
of its methods and instance variables.
*/!!
inherit(Window, #GanttWindow, #(project /* the project */
activities /* in the project */
barWidth /* width of a unit */
barHeight /* based on scrnsize */
activHeight /* bar + dead space */), 2, nil)!!
now(GanttWindowClass)!!
/* Return the name of this class's MS-Windows window class
either for registration or new window creation. */
Def wndClass(self)
{ ^"GanttWindow" }!!
/* Create a new window class Struct.
Change the cursor to a cross. */
Def newWClass(self, lpCl, lpIcon | wc)
{ wc := newWClass(self:WindowClass, lpCl, lpIcon);
putWord(wc, Call LoadCursor(0, IDC_CROSS), 14);
^wc;
} !!
now(GanttWindow)!!
/* For a Task, draw a critical bar. Make sure we don't draw
draw over the titles if the node hasn't been hooked up yet.
Uses early binding, direct Windows calls for speed. */
Def drawTask(self, aNode, x, y, hDC | startX)
{
startX := max(GW_STARTX, x - asInt(getTime(aNode)*barWidth));
Call FillRect(hDC, rect(startX:Int, y, x, y + barHeight),
stock(BLACK_BRUSH));
}!!
/* Create the window using a regular window style. */
Def create(self, par, wName, rect, style)
{
^create(self:Window, par, wName, rect,
WS_POPUPWIND);
}!!
/* If we close, be sure to tell the parent.
For testing a standalone Gantt chart delete this method. */
Def close(self)
{
close(self:Window);
closeGantt(parent); /* assumes parent is a ProjWindow */
}!!
/* Make sure the parent window knows that the project
has changed. */
Def dirty(self)
{
invalidate(self);
invalidate(parent);
}!!
/* Set up a dummy project, menus and the method table. */
Def init(self)
{
setProject(self, new(Project));
recalc(project);
setMenus(self);
setResolution(self);
}!!
/* Set the resolution for the size of bars, spacing etc.
For CGA, bars should be smaller. */
Def setResolution(self | hDC, ts)
{
hDC := getContext(self);
ts := textSize(self, hDC);
releaseContext(self, hDC);
barHeight := y(ts);
activHeight := asInt(1.25 * y(ts));
}!!
/* Handle menu commands. */
Def command(self, wp, lp)
{
select
case wp == GW_HELP
help(self);
endCase
/* use the same accelerator to open and close */
case wp == PW_VIEW_GANTT
close(self);
endCase
endSelect;
}!!
/* Load menu resources. */
Def setMenus(self)
{
loadMenu(self, "GWMenus");
setMenu(self, hMenu);
}
!!
/* Display help information from resource file. */
Def help(self | dlg)
{
dlg := new(Dialog);
checkRunModal(dlg, GW_HELP_BOX, self);
}!!
/* Draw a Milestone diamond in the window. */
Def drawMilestone(self, aNode, x, y, hDC)
{
draw(new(Polygon,
tuple(
point(x, y), /* top */
point(x - GW_DMWIDTH,
y + barHeight/2), /* left */
point(x, y + barHeight), /* bottom */
point(x + GW_DMWIDTH,
y + barHeight/2) /* right */
)), hDC);
}!!
/* Draw a slack bar in the window.
Uses direct Windows call for speed. */
Def drawSlackBar(self, aNode, x, y, hDC | hBrush)
{
Call FillRect(hDC, rect(x:Int, y,
x + asInt(getSlack(aNode)*barWidth),
y + barHeight), stock(GRAY_BRUSH)
);
}!!
/* Draw text info in the window. */
Def drawTextInfo(self, aNode, x, y, hDC | str)
{
if critical(aNode)
str := "*" + getName(aNode);
else
str := " " + getName(aNode);
endif;
Call TextOut(hDC, x, y, str, size(str));
}!!
/* Set the bar width so that the chart fits in the window.
Adjust in case it's very large or very small. */
Def setBarWidth(self, time)
{
barWidth := asInt((right(clientRect(self)) - GW_STARTX) /
(time + 1));
barWidth := min(75, max(2, barWidth));
}!!
/* Set the project. */
Def setProject(self, aProject)
{
project := aProject;
recalc(project);
}!!
/* See if the user has clicked on a bar in the chart.
If so, bring up a dialog for editing. */
Def WM_LBUTTONDOWN(self, wP, lP | idx)
{
idx:= (y(asPoint(lP)) - barHeight) / activHeight;
if idx <= size(activities) - 1
if editInfo(activities[idx]) == IDOK
dirty(self);
endif;
else
beep();
endif;
}!!
/* Draw the axis for the window.
Uses direct Windows calls for speed. */
Def drawAxis(self, hDC | endX, endY, str)
{
endX := GW_STARTX + barWidth *
(max(2,asInt(getTime(project)+getSlack(project)))) ;
endY := activHeight * (size(nodes(project))+1);
/* draw a rectangle for x and y axis */
Call Rectangle(hDC, GW_STARTX, GW_STARTY, endX, endY+1);
/* draw notches on the x axis */
do(overBy(GW_STARTX, endX, barWidth),
{using(i)
Call MoveTo(hDC, i, GW_STARTY); /* top */
Call LineTo(hDC, i, GW_STARTY + GW_NOTCH);
Call MoveTo(hDC, i,endY); /* bot */
Call LineTo(hDC, i, endY - GW_NOTCH);
});
str := asString(getEarlyStart(project));
Call TextOut(hDC, GW_STARTX, endY + 10, str, size(str));
}!!
/* Respond to MS-Windows messages to paint the window.
Show the project as a Gantt chart.
Draw the axis, then for each node draw the graphics. */
Def paint(self, hDC | y, t)
{
setBarWidth(self, asInt(getTime(project)+getSlack(project)));
activities := sortedActivities(project);
drawAxis(self, hDC);
y := barHeight; /* starting positions for bars */
do(activities,
{using(aNode)
drawTextInfo(self, aNode, 10, y, hDC);
/* make a temp to avoid calculating starting position */
t := max(GW_STARTX, GW_STARTX + barWidth *
asInt(getEarlyStart(aNode)-getEarlyStart(project)+getTime(aNode)));
/* draw a slack bar if necessary. */
if getSlack(aNode) > 0
drawSlackBar(self, aNode, t, y, hDC)
endif;
draw(aNode, self, t, y, hDC); /* node knows how */
y := y + activHeight; /* move down for next bar */
});
}!!