diff --git a/src/editor/f_main.pas b/src/editor/f_main.pas
index 2bf10e67abbf1a555c9616463e212a1e3cda4082..790a646a334b9ff69700d3237260483e6baf427b 100644 (file)
--- a/src/editor/f_main.pas
+++ b/src/editor/f_main.pas
lLoad: TLabel;
// Главное меню:
MainMenu: TMainMenu;
+ // Apple menu:
+ miApple: TMenuItem;
+ miAppleAbout: TMenuItem;
+ miAppleLine0: TMenuItem;
+ miApplePref: TMenuItem;
+ miAppleLine1: TMenuItem;
// "Файл":
miMenuFile: TMenuItem;
miNewMap: TMenuItem;
miOpenMap: TMenuItem;
miSaveMap: TMenuItem;
miSaveMapAs: TMenuItem;
+ miMacRecentSubMenu: TMenuItem;
+ miMacRecentClear: TMenuItem;
miOpenWadMap: TMenuItem;
miLine1: TMenuItem;
miReopenMap: TMenuItem;
miSaveMiniMap: TMenuItem;
miDeleteMap: TMenuItem;
miPackMap: TMenuItem;
+ miWinRecent: TMenuItem;
miLine2: TMenuItem;
miExit: TMenuItem;
// "Правка":
miLine5: TMenuItem;
miToFore: TMenuItem;
miToBack: TMenuItem;
- // "Инструменты":
- miMenuTools: TMenuItem;
- miSnapToGrid: TMenuItem;
- miMiniMap: TMenuItem;
- miSwitchGrid: TMenuItem;
+ // View menu:
+ miMenuView: TMenuItem;
miShowEdges: TMenuItem;
miLayers: TMenuItem;
miLayer1: TMenuItem;
miLayer7: TMenuItem;
miLayer8: TMenuItem;
miLayer9: TMenuItem;
+ miViewLine1: TMenuItem;
+ miMiniMap: TMenuItem;
+ miViewLine2: TMenuItem;
+ miMapPreview: TMenuItem;
+ miSnapToGrid: TMenuItem;
+ miSwitchGrid: TMenuItem;
+ miLine6: TMenuItem;
+ miOptions: TMenuItem;
+ miMapOptions: TMenuItem;
// "Сервис":
miMenuService: TMenuItem;
miCheckMap: TMenuItem;
miOptimmization: TMenuItem;
- miMapPreview: TMenuItem;
miTestMap: TMenuItem;
- // "Настройка":
- miMenuSettings: TMenuItem;
- miMapOptions: TMenuItem;
- miLine6: TMenuItem;
- miOptions: TMenuItem;
- miLine7: TMenuItem;
- miMapTestSettings: TMenuItem;
+ // Window menu:
+ miMenuWindow: TMenuItem;
+ miMacMinimize: TMenuItem;
+ miMacZoom: TMenuItem;
// "Справка":
miMenuHelp: TMenuItem;
miAbout: TMenuItem;
// Скрытый пункт меню для Ctrl+Tab:
- miHidden1: TMenuItem;
+ miMenuHidden: TMenuItem;
minexttab: TMenuItem;
// Панель инструментов:
pbLoad: TProgressBar;
pLoadProgress: TPanel;
RenderPanel: TOpenGLControl;
+ Separator1: TMenuItem;
+ miMacRecentEnd: TMenuItem;
+ miWinRecentStart: TMenuItem;
+ Separator2: TMenuItem;
tbNewMap: TToolButton;
tbOpenMap: TToolButton;
tbSaveMap: TToolButton;
miLayerP7: TMenuItem;
miLayerP8: TMenuItem;
miLayerP9: TMenuItem;
- // Всплывающее меню для кнопки теста карты:
- pmMapTest: TPopupMenu;
- miMapTestPMSet: TMenuItem;
// Панель карты:
PanelMap: TPanel;
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormResize(Sender: TObject);
+ procedure FormWindowStateChange(Sender: TObject);
+ procedure miMacRecentClearClick(Sender: TObject);
+ procedure miMacZoomClick(Sender: TObject);
procedure lbTextureListClick(Sender: TObject);
procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
+ procedure miMacMinimizeClick(Sender: TObject);
procedure miReopenMapClick(Sender: TObject);
procedure RenderPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure miSaveMiniMapClick(Sender: TObject);
procedure bClearTextureClick(Sender: TObject);
procedure miPackMapClick(Sender: TObject);
- procedure aRecentFileExecute(Sender: TObject);
- procedure miMapTestSettingsClick(Sender: TObject);
procedure miTestMapClick(Sender: TObject);
procedure sbVerticalScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
private
procedure Draw();
procedure OnIdle(Sender: TObject; var Done: Boolean);
+ procedure RefillRecentMenu (menu: TMenuItem; start: Integer; fmt: AnsiString);
public
procedure RefreshRecentMenu();
procedure OpenMapFile(FileName: String);
f_activationtype, f_keys, wadreader, fileutil,
MAPREADER, f_selectmap, f_savemap, WADEDITOR, MAPDEF,
g_map, f_saveminimap, f_addresource, CONFIG, f_packmap,
- f_addresource_sound, f_maptest, f_choosetype,
+ f_addresource_sound, f_choosetype,
g_language, f_selectlang, ClipBrd, g_resources, g_options;
const
begin
ShowMap := not ShowMap;
MainForm.tbShowMap.Down := ShowMap;
+ MainForm.miMiniMap.Checked := ShowMap;
end;
procedure ShowEdges();
drEdge[3] := 255
else
drEdge[3] := gAlphaEdge;
+ MainForm.miShowEdges.Checked := drEdge[3] <> 255;
end;
function SelectedTexture(): String;
//Закончились вспомогательные процедуры
//----------------------------------------
-procedure TMainForm.RefreshRecentMenu();
-var
- i: Integer;
- MI: TMenuItem;
+type
+ TRecentHandler = class
+ private
+ FForm: TMainForm;
+ FPath: String;
+ public
+ constructor Create (form: TMainForm; path: String);
+ procedure Execute (Sender: TObject);
+ end;
+
+constructor TRecentHandler.Create (form: TMainForm; path: String);
begin
-// Лишние запомненные карты:
- while RecentFiles.Count > RecentCount do
- RecentFiles.Delete(RecentFiles.Count-1);
+ Assert(form <> nil);
+ FForm := form;
+ FPath := path;
+end;
-// Лишние строки меню:
- while MainMenu.Items[0].Count > RECENT_FILES_MENU_START do
- MainMenu.Items[0].Delete(MainMenu.Items[0].Count-1);
+procedure TRecentHandler.Execute (Sender: TObject);
+ var fn: AnsiString;
+begin
+ fn := g_ExtractWadName(FPath);
+ if FileExists(fn) then
+ OpenMap(fn, g_ExtractFilePathName(FPath))
+ else
+ Application.MessageBox('', 'File not available anymore', MB_OK);
+// if Application.MessageBox(PChar(_lc[I_MSG_DEL_RECENT_PROMT]), PChar(_lc[I_MSG_DEL_RECENT]), MB_ICONQUESTION or MB_YESNO) = idYes then
+// begin
+// RecentFiles.Delete(n);
+// RefreshRecentMenu();
+// end;
+end;
-// Отделение списка карт от строки "Выход":
- if RecentFiles.Count > 0 then
+procedure TMainForm.RefillRecentMenu (menu: TMenuItem; start: Integer; fmt: AnsiString);
+ var i: Integer; MI: TMenuItem; cb: TMethod; h: TRecentHandler; s: AnsiString;
+begin
+ Assert(menu <> nil);
+ Assert(start >= 0);
+ Assert(start <= menu.Count);
+
+ // clear all recent entries from menu
+ i := start;
+ while i < menu.Count do
begin
- MI := TMenuItem.Create(MainMenu.Items[0]);
- MI.Caption := '-';
- MainMenu.Items[0].Add(MI);
+ MI := menu.Items[i];
+ cb := TMethod(MI.OnClick);
+ if cb.Code = @TRecentHandler.Execute then
+ begin
+ // this is recent menu entry
+ // remove it and free callback handler
+ h := TRecentHandler(cb.Data);
+ menu.Delete(i);
+ MI.Free();
+ h.Free();
+ end
+ else
+ Inc(i);
end;
-// Добавление в меню списка запомненных карт:
- for i := 0 to RecentFiles.Count-1 do
+ // fill with a new ones
+ for i := 0 to RecentFiles.Count - 1 do
begin
- MI := TMenuItem.Create(MainMenu.Items[0]);
- MI.Caption := IntToStr(i+1) + ' ' + RecentFiles[i];
- MI.OnClick := aRecentFileExecute;
- MainMenu.Items[0].Add(MI);
+ s := RecentFiles[i];
+ h := TRecentHandler.Create(self, s);
+ MI := TMenuItem.Create(menu);
+ MI.Caption := Format(fmt, [i + 1, g_ExtractWadNameNoPath(s), g_ExtractFilePathName(s)]);
+ MI.OnClick := h.Execute;
+ menu.Insert(start + i, MI);
end;
end;
-procedure TMainForm.aRecentFileExecute(Sender: TObject);
-var
- n: Integer;
- fn, s: String;
-begin
- s := LowerCase((Sender as TMenuItem).Caption);
- Delete(s, Pos('&', s), 1);
- s := Trim(Copy(s, 1, 2));
- n := StrToIntDef(s, 0) - 1;
- if (n >= 0) and (n <= RecentFiles.Count) then
+procedure TMainForm.RefreshRecentMenu();
+ var start: Integer;
+begin
+ while RecentFiles.Count > RecentCount do
+ RecentFiles.Delete(RecentFiles.Count - 1);
+
+ if miMacRecentSubMenu.Visible then
begin
- fn := g_ExtractWadName(RecentFiles[n]);
- if FileExists(fn) then
- begin
- s := g_ExtractFilePathName(RecentFiles[n]);
- OpenMap(fn, s)
- end
- else if Application.MessageBox(PChar(_lc[I_MSG_DEL_RECENT_PROMT]), PChar(_lc[I_MSG_DEL_RECENT]), MB_ICONQUESTION or MB_YESNO) = idYes then
- begin
- RecentFiles.Delete(n);
- RefreshRecentMenu();
- end
- end
+ // Reconstruct OSX-like recent list
+ RefillRecentMenu(miMacRecentSubMenu, 0, '%1:s - %2:s');
+ miMacRecentEnd.Enabled := RecentFiles.Count <> 0;
+ miMacRecentEnd.Visible := RecentFiles.Count <> 0;
+ end;
+
+ if miWinRecentStart.Visible then
+ begin
+ // Reconstruct Windows-like recent list
+ start := miMenuFile.IndexOf(miWinRecent);
+ if start < 0 then start := miMenuFile.Count else start := start + 1;
+ RefillRecentMenu(miMenuFile, start, '%0:d %1:s:%2:s');
+ miWinRecent.Enabled := False;
+ miWinRecent.Visible := RecentFiles.Count = 0;
+ end;
+end;
+
+procedure TMainForm.miMacRecentClearClick(Sender: TObject);
+begin
+ RecentFiles.Clear();
+ RefreshRecentMenu();
end;
procedure TMainForm.aEditorOptionsExecute(Sender: TObject);
begin
Randomize();
+ {$IFDEF DARWIN}
+ miApple.Enabled := True;
+ miApple.Visible := True;
+ miMacRecentSubMenu.Enabled := True;
+ miMacRecentSubMenu.Visible := True;
+ miWinRecentStart.Enabled := False;
+ miWinRecentStart.Visible := False;
+ miWinRecent.Enabled := False;
+ miWinRecent.Visible := False;
+ miLine2.Enabled := False;
+ miLine2.Visible := False;
+ miExit.Enabled := False;
+ miExit.Visible := False;
+ miOptions.Enabled := False;
+ miOptions.Visible := False;
+ miMenuWindow.Enabled := True;
+ miMenuWindow.Visible := True;
+ miAbout.Enabled := False;
+ miAbout.Visible := False;
+ {$ELSE}
+ miApple.Enabled := False;
+ miApple.Visible := False;
+ miMacRecentSubMenu.Enabled := False;
+ miMacRecentSubMenu.Visible := False;
+ miWinRecentStart.Enabled := True;
+ miWinRecentStart.Visible := True;
+ miWinRecent.Enabled := True;
+ miWinRecent.Visible := True;
+ miLine2.Enabled := True;
+ miLine2.Visible := True;
+ miExit.Enabled := True;
+ miExit.Visible := True;
+ miOptions.Enabled := True;
+ miOptions.Visible := True;
+ miMenuWindow.Enabled := False;
+ miMenuWindow.Visible := False;
+ miAbout.Enabled := True;
+ miAbout.Visible := True;
+ {$ENDIF}
+
+ miNewMap.ShortCut := ShortCut(VK_N, [ssModifier]);
+ miOpenMap.ShortCut := ShortCut(VK_O, [ssModifier]);
+ miSaveMap.ShortCut := ShortCut(VK_S, [ssModifier]);
+ {$IFDEF DARWIN}
+ miSaveMapAs.ShortCut := ShortCut(VK_S, [ssModifier, ssShift]);
+ miReopenMap.ShortCut := ShortCut(VK_F5, [ssModifier]);
+ {$ENDIF}
+ miUndo.ShortCut := ShortCut(VK_Z, [ssModifier]);
+ miCopy.ShortCut := ShortCut(VK_C, [ssModifier]);
+ miCut.ShortCut := ShortCut(VK_X, [ssModifier]);
+ miPaste.ShortCut := ShortCut(VK_V, [ssModifier]);
+ miSelectAll.ShortCut := ShortCut(VK_A, [ssModifier]);
+ miToFore.ShortCut := ShortCut(VK_LCL_CLOSE_BRACKET, [ssModifier]);
+ miToBack.ShortCut := ShortCut(VK_LCL_OPEN_BRACKET, [ssModifier]);
+ {$IFDEF DARWIN}
+ miMapOptions.Shortcut := ShortCut(VK_P, [ssModifier, ssAlt]);
+ selectall1.Shortcut := ShortCut(VK_A, [ssModifier, ssAlt]);
+ {$ENDIF}
+
e_WriteLog('Doom 2D: Forever Editor version ' + EDITOR_VERSION, MSG_NOTIFY);
e_WriteLog('Build date: ' + EDITOR_BUILDDATE + ' ' + EDITOR_BUILDTIME, MSG_NOTIFY);
e_WriteLog('Build hash: ' + g_GetBuildHash(), MSG_NOTIFY);
Compress := config.ReadBool('Editor', 'Compress', True);
Backup := config.ReadBool('Editor', 'Backup', True);
+ TestGameMode := config.ReadStr('TestRun', 'GameMode', 'DM');
+ TestLimTime := config.ReadStr('TestRun', 'LimTime', '0');
+ TestLimScore := config.ReadStr('TestRun', 'LimScore', '0');
+ TestOptionsTwoPlayers := config.ReadBool('TestRun', 'TwoPlayers', False);
+ TestOptionsTeamDamage := config.ReadBool('TestRun', 'TeamDamage', False);
+ TestOptionsAllowExit := config.ReadBool('TestRun', 'AllowExit', True);
+ TestOptionsWeaponStay := config.ReadBool('TestRun', 'WeaponStay', False);
+ TestOptionsMonstersDM := config.ReadBool('TestRun', 'MonstersDM', False);
+ TestMapOnce := config.ReadBool('TestRun', 'MapOnce', False);
+ {$IF DEFINED(DARWIN)}
+ TestD2dExe := config.ReadStr('TestRun', 'ExeDrawin', GameExeFile);
+ {$ELSEIF DEFINED(WINDOWS)}
+ TestD2dExe := config.ReadStr('TestRun', 'ExeWindows', GameExeFile);
+ {$ELSE}
+ TestD2dExe := config.ReadStr('TestRun', 'ExeUnix', GameExeFile);
+ {$ENDIF}
+ TestD2DArgs := config.ReadStr('TestRun', 'Args', '');
+
RecentCount := config.ReadInt('Editor', 'RecentCount', 5);
if RecentCount > 10 then
RecentCount := 10;
RecentFiles := TStringList.Create();
for i := 0 to RecentCount-1 do
begin
- s := config.ReadStr('RecentFiles', IntToStr(i+1), '');
+ {$IFDEF WINDOWS}
+ s := config.ReadStr('RecentFilesWin', IntToStr(i), '');
+ {$ELSE}
+ s := config.ReadStr('RecentFilesUnix', IntToStr(i), '');
+ {$ENDIF}
if s <> '' then
RecentFiles.Add(s);
end;
MapOffset.Y := -sbVertical.Position;
end;
+procedure TMainForm.FormWindowStateChange(Sender: TObject);
+ {$IFDEF DARWIN}
+ var e: Boolean;
+ {$ENDIF}
+begin
+ {$IFDEF DARWIN}
+ // deactivate all menus when main window minimized
+ e := self.WindowState <> wsMinimized;
+ miMenuFile.Enabled := e;
+ miMenuEdit.Enabled := e;
+ miMenuView.Enabled := e;
+ miMenuService.Enabled := e;
+ miMenuWindow.Enabled := e;
+ miMenuHelp.Enabled := e;
+ miMenuHidden.Enabled := e;
+ {$ENDIF}
+end;
+
procedure SelectNextObject(X, Y: Integer; ObjectType: Byte; ID: DWORD);
var
j, j_max: Integer;
procedure TMainForm.FormDestroy(Sender: TObject);
var
config: TConfig;
+ s: AnsiString;
i: Integer;
begin
config := TConfig.CreateFile(CfgFileName);
config.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect);
config.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect);
- for i := 0 to RecentCount-1 do
- if i < RecentFiles.Count then
- config.WriteStr('RecentFiles', IntToStr(i+1), RecentFiles[i])
- else
- config.WriteStr('RecentFiles', IntToStr(i+1), '');
+ for i := 0 to RecentCount - 1 do
+ begin
+ if i < RecentFiles.Count then s := RecentFiles[i] else s := '';
+ {$IFDEF WINDOWS}
+ config.WriteStr('RecentFilesWin', IntToStr(i), s);
+ {$ELSE}
+ config.WriteStr('RecentFilesUnix', IntToStr(i), s);
+ {$ENDIF}
+ end;
RecentFiles.Free();
config.SaveFile(CfgFileName);
end;
end;
+procedure TMainForm.miMacMinimizeClick(Sender: TObject);
+begin
+ self.WindowState := wsMinimized;
+ self.FormWindowStateChange(Sender);
+end;
+
+procedure TMainForm.miMacZoomClick(Sender: TObject);
+begin
+ if self.WindowState = wsMaximized then
+ self.WindowState := wsNormal
+ else
+ self.WindowState := wsMaximized;
+ self.FormWindowStateChange(Sender);
+end;
+
procedure TMainForm.miReopenMapClick(Sender: TObject);
var
FileName, Resource: String;
PackMapForm.ShowModal();
end;
-procedure TMainForm.miMapTestSettingsClick(Sender: TObject);
-begin
- MapTestForm.ShowModal();
-end;
-
type SSArray = array of String;
function ParseString (Str: AnsiString): SSArray;
// Сохраняем временную карту:
time := 0;
repeat
- newWAD := ExtractFilePath(TestD2dExe) + Format('maps/temp%.4d', [time]);
+ newWAD := Format('%s/temp%.4d', [MapsDir, time]);
Inc(time);
until not FileExists(newWAD);
if OpenedMap <> '' then
end;
tempMap := newWAD + ':\' + TEST_MAP_NAME;
SaveMap(tempMap);
- tempMap := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', tempMap);
// Опции игры:
opt := 32 + 64;
// Запускаем:
proc := TProcessUTF8.Create(nil);
proc.Executable := TestD2dExe;
+ {$IFDEF DARWIN}
+ // TODO: get real executable name from Info.plist
+ if LowerCase(ExtractFileExt(TestD2dExe)) = '.app' then
+ proc.Executable := TestD2dExe + DirectorySeparator + 'Contents' + DirectorySeparator + 'MacOS' + DirectorySeparator + 'Doom2DF';
+ {$ENDIF}
proc.Parameters.Add('-map');
proc.Parameters.Add(tempMap);
proc.Parameters.Add('-gm');