MODULE MainMenu;
IMPORT
KernelLog, XML, Modules, Files, Inputs,
WMMessages, WMStandardComponents, WMComponents, WMTabComponents,
Strings, WM := WMWindowManager;
CONST
MenuFilePrefix = "MenuPage";
TYPE
Window* = OBJECT (WMComponents.FormWindow)
VAR
tabs : WMTabComponents.Tabs;
pages : ARRAY 100 OF WMComponents.VisualComponent;
tabList : ARRAY 100 OF WMTabComponents.Tab;
currentPage : WMComponents.VisualComponent;
currentPageNr : LONGINT;
page : WMStandardComponents.Panel;
moveToFront : BOOLEAN;
PROCEDURE CreateForm(): WMComponents.VisualComponent;
VAR
panel : WMStandardComponents.Panel;
pagePanel : WMStandardComponents.Panel;
tabs : WMTabComponents.Tabs;
BEGIN
NEW(panel); panel.bounds.SetExtents(1024, 60); panel.fillColor.Set(0); panel.takesFocus.Set(TRUE);
NEW(tabs); tabs.fillColor.Set(000600080H); tabs.bounds.SetHeight(20); tabs.alignment.Set(WMComponents.AlignTop);
panel.AddContent(tabs);
SELF.tabs := tabs;
NEW(pagePanel); pagePanel.fillColor.Set(0H); pagePanel.alignment.Set(WMComponents.AlignClient);
panel.AddContent(pagePanel);
page := pagePanel;
RETURN panel
END CreateForm;
PROCEDURE &New*;
VAR vc : WMComponents.VisualComponent;
view : WM.ViewPort;
BEGIN
vc := CreateForm();
moveToFront := TRUE;
currentPageNr := -1;
tabs.onSelectTab.Add(TabSelected);
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), TRUE);
SetContent(vc);
SetTitle(Strings.NewString("MainMenu"));
pointerThreshold := 10;
manager := WM.GetDefaultManager();
view := WM.GetDefaultView();
manager.Add(0, view.height0 - GetHeight(), SELF, {WM.FlagNavigation, WM.FlagHidden});
END New;
PROCEDURE PointerMove(x, y : LONGINT; keys : SET);
BEGIN
PointerMove^(x, y, keys);
moveToFront := FALSE;
manager.ToFront(SELF);
END PointerMove;
PROCEDURE PointerLeave;
BEGIN
PointerLeave^;
moveToFront := TRUE;
END PointerLeave;
PROCEDURE SetOriginator*(extView : ANY);
VAR view : WM.ViewPort;
BEGIN
IF (extView # NIL) & (extView IS WM.ViewPort) THEN
view := extView(WM.ViewPort)
ELSE view := WM.GetDefaultView()
END;
Refresh(NIL, NIL);
IF ~(WM.FlagNavigation IN SELF.flags) THEN
manager.SetWindowPos(SELF, ENTIER(view.range.l), ENTIER(view.range.b) - GetHeight());
END;
manager.ToFront(SELF)
END SetOriginator;
PROCEDURE UpdatePages;
VAR i : LONGINT;
tab : WMTabComponents.Tab;
s : Strings.String;
BEGIN
tabs.RemoveAllTabs;
IF currentPage # NIL THEN page.RemoveContent(currentPage);
currentPage := NIL
END;
IF currentPageNr >= 0 THEN currentPage := pages[currentPageNr] END;
FOR i := 0 TO 99 DO
tabList[i] := NIL;
IF pages[i] # NIL THEN
pages[i].alignment.Set(WMComponents.AlignClient);
tab := tabs.NewTab();
tabs.AddTab(tab);
tabList[i] := tab;
s := pages[i].GetAttributeValue("caption");
IF s = NIL THEN s := Strings.NewString("Untitled") END;
tabs.SetTabCaption(tab, s);
tabs.SetTabData(tab, pages[i])
END
END;
IF currentPage = NIL THEN
i := 0;
WHILE (i < 100) & (currentPage = NIL) DO
IF pages[i] # NIL THEN currentPage := pages[i]; currentPageNr := i END;
INC(i);
END
END;
IF currentPage # NIL THEN
page.AddContent(currentPage);
currentPage.Reset(SELF, NIL);
page.AlignSubComponents;
page.Invalidate;
IF tabList[currentPageNr] # NIL THEN tabs.Select(tabList[currentPageNr]) END
END;
END UpdatePages;
PROCEDURE TryLoad(CONST name : ARRAY OF CHAR; pos : LONGINT);
VAR x : XML.Content;
BEGIN
IF (pos >= 0) & (pos <= 99) THEN
x := WMComponents.Load(name);
IF x # NIL THEN
IF x IS WMComponents.VisualComponent THEN
pages[pos] := x(WMComponents.VisualComponent);
END
END
END
END TryLoad;
PROCEDURE LoadPages*;
VAR mask : ARRAY 64 OF CHAR;
name : ARRAY 256 OF CHAR; flags : SET;
time, date, size : LONGINT;
i: LONGINT;
enumerator : Files.Enumerator;
number: LONGINT;
PROCEDURE IsNum(ch : CHAR) : BOOLEAN;
BEGIN
RETURN (ch >= '0') & (ch <= '9')
END IsNum;
BEGIN
NEW(enumerator);
FOR i := 0 TO 99 DO
IF pages[i] = currentPage THEN currentPageNr := i END;
pages[i] := NIL
END;
mask := MenuFilePrefix;
i := Strings.Length(mask);
Strings.Append(mask, "*.XML");
enumerator.Open(mask, {});
WHILE enumerator.HasMoreEntries() DO
IF enumerator.GetEntry(name, flags, time, date, size) THEN
i := Strings.Length(name);
IF IsNum(name[i - 6]) & IsNum(name[i - 5]) THEN
number := (ORD(name[i - 6]) - ORD('0')) * 10 + (ORD(name[i - 5]) - ORD('0'));
IF pages[number] = NIL THEN
TryLoad(name, number);
END;
END
END
END;
enumerator.Close;
UpdatePages
END LoadPages;
PROCEDURE Refresh(sender, data : ANY);
BEGIN
DisableUpdate;
LoadPages;
EnableUpdate;
page.Invalidate
END Refresh;
PROCEDURE TabSelected(sender, data : ANY);
VAR tab : WMTabComponents.Tab;
BEGIN
IF (data # NIL) & (data IS WMTabComponents.Tab) THEN
DisableUpdate;
page.RemoveContent(currentPage);
tab := data(WMTabComponents.Tab);
IF (tab.data # NIL) & (tab.data IS WMComponents.VisualComponent) THEN
currentPage := tab.data(WMComponents.VisualComponent);
page.AddContent(currentPage);
IF ~currentPage.initialized THEN currentPage.Initialize END;
currentPage.Reset(SELF, NIL);
page.AlignSubComponents;
END;
EnableUpdate;
page.Invalidate
END
END TabSelected;
PROCEDURE Close;
BEGIN
Close^;
window := NIL
END Close;
END Window;
TYPE
Starter = OBJECT
VAR
originator : ANY;
w : Window;
PROCEDURE &Init*(o : ANY);
BEGIN
originator := o;
w := NIL;
END Init;
BEGIN {ACTIVE}
BEGIN {EXCLUSIVE}
IF (window = NIL) THEN NEW(window); w := window;
ELSE window.SetOriginator(originator);
END;
END;
IF (w # NIL) THEN w.LoadPages; END;
END Starter;
VAR
window : Window;
manager : WM.WindowManager;
PROCEDURE MessagePreview(VAR m : WMMessages.Message; VAR discard : BOOLEAN);
VAR starter : Starter;
BEGIN
IF m.msgType = WMMessages.MsgKey THEN
IF (m.y = 0FF1BH) & ((m.flags * Inputs.Ctrl # {}) OR (m.flags * Inputs.Meta # {})) THEN
NEW(starter, m.originator); discard := TRUE
END
END
END MessagePreview;
PROCEDURE Open*;
VAR w : Window;
BEGIN
BEGIN {EXCLUSIVE}
IF window = NIL THEN NEW(window); w := window;
ELSE window.SetOriginator(NIL)
END;
END;
IF w # NIL THEN w.LoadPages END;
END Open;
PROCEDURE Cleanup;
BEGIN {EXCLUSIVE}
KernelLog.String("Cleanup"); KernelLog.Ln;
manager.RemoveMessagePreview(MessagePreview);
IF window # NIL THEN window.Close END;
END Cleanup;
BEGIN
manager := WM.GetDefaultManager();
Modules.InstallTermHandler(Cleanup)
END MainMenu.
SystemTools.Free MainMenu WMTabComponents ~
MainMenu.Open ~