diff --git a/ChivalryServerLauncher.dpr b/ChivalryServerLauncher.dpr index a1d972e..1e9d139 100644 --- a/ChivalryServerLauncher.dpr +++ b/ChivalryServerLauncher.dpr @@ -13,7 +13,8 @@ uses Bindings.Converters in 'source\bindings\Bindings.Converters.pas', Game.List in 'source\model\Game.List.pas', Persist.GameList in 'source\persist\Persist.GameList.pas', - Forms.Map in 'source\view\Forms.Map.pas' {MapForm}; + Forms.Map in 'source\view\Forms.Map.pas' {MapForm}, + Frame.MapPreview in 'source\view\Frame.MapPreview.pas' {MapPreviewFrame: TFrame}; {$R *.res} diff --git a/ChivalryServerLauncher.dproj b/ChivalryServerLauncher.dproj index 949299a..b0045fc 100644 --- a/ChivalryServerLauncher.dproj +++ b/ChivalryServerLauncher.dproj @@ -6,7 +6,7 @@ ChivalryServerLauncher.dpr True Build - Win32 + Win64 3 Application @@ -99,6 +99,11 @@
MapForm
+ +
MapPreviewFrame
+ dfm + TFrame +
Base diff --git a/assets/maps/AOCCTF-Frigid_p.jpg b/assets/maps/AOCCTF-Frigid_p.jpg new file mode 100644 index 0000000..6188420 Binary files /dev/null and b/assets/maps/AOCCTF-Frigid_p.jpg differ diff --git a/assets/maps/AOCCTF-Moor_p.jpg b/assets/maps/AOCCTF-Moor_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCCTF-Moor_p.jpg differ diff --git a/assets/maps/AOCCTF-Ruins_Large_P.jpg b/assets/maps/AOCCTF-Ruins_Large_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCCTF-Ruins_Large_P.jpg differ diff --git a/assets/maps/AOCCTF-Ruins_P.jpg b/assets/maps/AOCCTF-Ruins_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCCTF-Ruins_P.jpg differ diff --git a/assets/maps/AOCDuel-Arena_Flat_p.jpg b/assets/maps/AOCDuel-Arena_Flat_p.jpg new file mode 100644 index 0000000..2981a0c Binary files /dev/null and b/assets/maps/AOCDuel-Arena_Flat_p.jpg differ diff --git a/assets/maps/AOCDuel-Arena_p.jpg b/assets/maps/AOCDuel-Arena_p.jpg new file mode 100644 index 0000000..2981a0c Binary files /dev/null and b/assets/maps/AOCDuel-Arena_p.jpg differ diff --git a/assets/maps/AOCDuel-Bridge_p.jpg b/assets/maps/AOCDuel-Bridge_p.jpg new file mode 100644 index 0000000..9183e19 Binary files /dev/null and b/assets/maps/AOCDuel-Bridge_p.jpg differ diff --git a/assets/maps/AOCDuel-Cistern_p.jpg b/assets/maps/AOCDuel-Cistern_p.jpg new file mode 100644 index 0000000..f33fd9a Binary files /dev/null and b/assets/maps/AOCDuel-Cistern_p.jpg differ diff --git a/assets/maps/AOCDuel-Courtyard_p.jpg b/assets/maps/AOCDuel-Courtyard_p.jpg new file mode 100644 index 0000000..6fc606b Binary files /dev/null and b/assets/maps/AOCDuel-Courtyard_p.jpg differ diff --git a/assets/maps/AOCDuel-Dininghall_p.jpg b/assets/maps/AOCDuel-Dininghall_p.jpg new file mode 100644 index 0000000..08ff463 Binary files /dev/null and b/assets/maps/AOCDuel-Dininghall_p.jpg differ diff --git a/assets/maps/AOCDuel-FrostPeak_p.jpg b/assets/maps/AOCDuel-FrostPeak_p.jpg new file mode 100644 index 0000000..3e3c4e6 Binary files /dev/null and b/assets/maps/AOCDuel-FrostPeak_p.jpg differ diff --git a/assets/maps/AOCDuel-Mines_p.jpg b/assets/maps/AOCDuel-Mines_p.jpg new file mode 100644 index 0000000..6cacc86 Binary files /dev/null and b/assets/maps/AOCDuel-Mines_p.jpg differ diff --git a/assets/maps/AOCDuel-Shaft_p.jpg b/assets/maps/AOCDuel-Shaft_p.jpg new file mode 100644 index 0000000..ab9765c Binary files /dev/null and b/assets/maps/AOCDuel-Shaft_p.jpg differ diff --git a/assets/maps/AOCDuel-Shipyard_p.jpg b/assets/maps/AOCDuel-Shipyard_p.jpg new file mode 100644 index 0000000..c0693e8 Binary files /dev/null and b/assets/maps/AOCDuel-Shipyard_p.jpg differ diff --git a/assets/maps/AOCDuel-ThroneRoom_p.jpg b/assets/maps/AOCDuel-ThroneRoom_p.jpg new file mode 100644 index 0000000..7778712 Binary files /dev/null and b/assets/maps/AOCDuel-ThroneRoom_p.jpg differ diff --git a/assets/maps/AOCDuel-Tower_p.jpg b/assets/maps/AOCDuel-Tower_p.jpg new file mode 100644 index 0000000..c9d4a04 Binary files /dev/null and b/assets/maps/AOCDuel-Tower_p.jpg differ diff --git a/assets/maps/AOCFFA-Arena3_p.jpg b/assets/maps/AOCFFA-Arena3_p.jpg new file mode 100644 index 0000000..2981a0c Binary files /dev/null and b/assets/maps/AOCFFA-Arena3_p.jpg differ diff --git a/assets/maps/AOCFFA-Darkforest_Cistern_p.jpg b/assets/maps/AOCFFA-Darkforest_Cistern_p.jpg new file mode 100644 index 0000000..b315959 Binary files /dev/null and b/assets/maps/AOCFFA-Darkforest_Cistern_p.jpg differ diff --git a/assets/maps/AOCFFA-Darkforest_Valley_p.jpg b/assets/maps/AOCFFA-Darkforest_Valley_p.jpg new file mode 100644 index 0000000..495e9ff Binary files /dev/null and b/assets/maps/AOCFFA-Darkforest_Valley_p.jpg differ diff --git a/assets/maps/AOCFFA-HillsidePyre_P.jpg b/assets/maps/AOCFFA-HillsidePyre_P.jpg new file mode 100644 index 0000000..7f5f557 Binary files /dev/null and b/assets/maps/AOCFFA-HillsidePyre_P.jpg differ diff --git a/assets/maps/AOCFFA-Hillside_P.jpg b/assets/maps/AOCFFA-Hillside_P.jpg new file mode 100644 index 0000000..36b1fcd Binary files /dev/null and b/assets/maps/AOCFFA-Hillside_P.jpg differ diff --git a/assets/maps/AOCFFA-Moor_p.jpg b/assets/maps/AOCFFA-Moor_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCFFA-Moor_p.jpg differ diff --git a/assets/maps/AOCFFA-Ruins_P.jpg b/assets/maps/AOCFFA-Ruins_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCFFA-Ruins_P.jpg differ diff --git a/assets/maps/AOCFFA-StoneshillVillage_P.jpg b/assets/maps/AOCFFA-StoneshillVillage_P.jpg new file mode 100644 index 0000000..66c9af3 Binary files /dev/null and b/assets/maps/AOCFFA-StoneshillVillage_P.jpg differ diff --git a/assets/maps/AOCFFA-ThroneRoomXL_P.jpg b/assets/maps/AOCFFA-ThroneRoomXL_P.jpg new file mode 100644 index 0000000..7778712 Binary files /dev/null and b/assets/maps/AOCFFA-ThroneRoomXL_P.jpg differ diff --git a/assets/maps/AOCKOTH-Arena3_p.jpg b/assets/maps/AOCKOTH-Arena3_p.jpg new file mode 100644 index 0000000..2981a0c Binary files /dev/null and b/assets/maps/AOCKOTH-Arena3_p.jpg differ diff --git a/assets/maps/AOCKOTH-Darkforest_Valley_p.jpg b/assets/maps/AOCKOTH-Darkforest_Valley_p.jpg new file mode 100644 index 0000000..495e9ff Binary files /dev/null and b/assets/maps/AOCKOTH-Darkforest_Valley_p.jpg differ diff --git a/assets/maps/AOCKOTH-Hillside_P.jpg b/assets/maps/AOCKOTH-Hillside_P.jpg new file mode 100644 index 0000000..7f5f557 Binary files /dev/null and b/assets/maps/AOCKOTH-Hillside_P.jpg differ diff --git a/assets/maps/AOCKOTH-Moor_p.jpg b/assets/maps/AOCKOTH-Moor_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCKOTH-Moor_p.jpg differ diff --git a/assets/maps/AOCLTS-Arena3_p.jpg b/assets/maps/AOCLTS-Arena3_p.jpg new file mode 100644 index 0000000..2981a0c Binary files /dev/null and b/assets/maps/AOCLTS-Arena3_p.jpg differ diff --git a/assets/maps/AOCLTS-ArgonsWall_p.jpg b/assets/maps/AOCLTS-ArgonsWall_p.jpg new file mode 100644 index 0000000..e419ed1 Binary files /dev/null and b/assets/maps/AOCLTS-ArgonsWall_p.jpg differ diff --git a/assets/maps/AOCLTS-Battlegrounds_Farm_p.jpg b/assets/maps/AOCLTS-Battlegrounds_Farm_p.jpg new file mode 100644 index 0000000..06534ec Binary files /dev/null and b/assets/maps/AOCLTS-Battlegrounds_Farm_p.jpg differ diff --git a/assets/maps/AOCLTS-Battlegrounds_p.jpg b/assets/maps/AOCLTS-Battlegrounds_p.jpg new file mode 100644 index 0000000..7231226 Binary files /dev/null and b/assets/maps/AOCLTS-Battlegrounds_p.jpg differ diff --git a/assets/maps/AOCLTS-Darkforest_Valley_p.jpg b/assets/maps/AOCLTS-Darkforest_Valley_p.jpg new file mode 100644 index 0000000..495e9ff Binary files /dev/null and b/assets/maps/AOCLTS-Darkforest_Valley_p.jpg differ diff --git a/assets/maps/AOCLTS-Darkforest_XL_p.jpg b/assets/maps/AOCLTS-Darkforest_XL_p.jpg new file mode 100644 index 0000000..e155320 Binary files /dev/null and b/assets/maps/AOCLTS-Darkforest_XL_p.jpg differ diff --git a/assets/maps/AOCLTS-Frigid_p.jpg b/assets/maps/AOCLTS-Frigid_p.jpg new file mode 100644 index 0000000..6188420 Binary files /dev/null and b/assets/maps/AOCLTS-Frigid_p.jpg differ diff --git a/assets/maps/AOCLTS-HillsidePyre_P.jpg b/assets/maps/AOCLTS-HillsidePyre_P.jpg new file mode 100644 index 0000000..7f5f557 Binary files /dev/null and b/assets/maps/AOCLTS-HillsidePyre_P.jpg differ diff --git a/assets/maps/AOCLTS-Hillside_P.jpg b/assets/maps/AOCLTS-Hillside_P.jpg new file mode 100644 index 0000000..36b1fcd Binary files /dev/null and b/assets/maps/AOCLTS-Hillside_P.jpg differ diff --git a/assets/maps/AOCLTS-Moor_Large_p.jpg b/assets/maps/AOCLTS-Moor_Large_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCLTS-Moor_Large_p.jpg differ diff --git a/assets/maps/AOCLTS-Moor_p.jpg b/assets/maps/AOCLTS-Moor_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCLTS-Moor_p.jpg differ diff --git a/assets/maps/AOCLTS-Ruins_Large_P.jpg b/assets/maps/AOCLTS-Ruins_Large_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCLTS-Ruins_Large_P.jpg differ diff --git a/assets/maps/AOCLTS-Ruins_P.jpg b/assets/maps/AOCLTS-Ruins_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCLTS-Ruins_P.jpg differ diff --git a/assets/maps/AOCLTS-StoneshillVillage_P.jpg b/assets/maps/AOCLTS-StoneshillVillage_P.jpg new file mode 100644 index 0000000..66c9af3 Binary files /dev/null and b/assets/maps/AOCLTS-StoneshillVillage_P.jpg differ diff --git a/assets/maps/AOCLTS-ThroneRoom_P.jpg b/assets/maps/AOCLTS-ThroneRoom_P.jpg new file mode 100644 index 0000000..7778712 Binary files /dev/null and b/assets/maps/AOCLTS-ThroneRoom_P.jpg differ diff --git a/assets/maps/AOCTD-ArgonsWall_p.jpg b/assets/maps/AOCTD-ArgonsWall_p.jpg new file mode 100644 index 0000000..e419ed1 Binary files /dev/null and b/assets/maps/AOCTD-ArgonsWall_p.jpg differ diff --git a/assets/maps/AOCTD-Battlegrounds_Farm_p.jpg b/assets/maps/AOCTD-Battlegrounds_Farm_p.jpg new file mode 100644 index 0000000..06534ec Binary files /dev/null and b/assets/maps/AOCTD-Battlegrounds_Farm_p.jpg differ diff --git a/assets/maps/AOCTD-Battlegrounds_p.jpg b/assets/maps/AOCTD-Battlegrounds_p.jpg new file mode 100644 index 0000000..7231226 Binary files /dev/null and b/assets/maps/AOCTD-Battlegrounds_p.jpg differ diff --git a/assets/maps/AOCTD-Darkforest_Valley_p.jpg b/assets/maps/AOCTD-Darkforest_Valley_p.jpg new file mode 100644 index 0000000..495e9ff Binary files /dev/null and b/assets/maps/AOCTD-Darkforest_Valley_p.jpg differ diff --git a/assets/maps/AOCTD-Darkforest_XL_p.jpg b/assets/maps/AOCTD-Darkforest_XL_p.jpg new file mode 100644 index 0000000..e155320 Binary files /dev/null and b/assets/maps/AOCTD-Darkforest_XL_p.jpg differ diff --git a/assets/maps/AOCTD-Frigid_p.jpg b/assets/maps/AOCTD-Frigid_p.jpg new file mode 100644 index 0000000..6188420 Binary files /dev/null and b/assets/maps/AOCTD-Frigid_p.jpg differ diff --git a/assets/maps/AOCTD-HillsidePyre_P.jpg b/assets/maps/AOCTD-HillsidePyre_P.jpg new file mode 100644 index 0000000..7f5f557 Binary files /dev/null and b/assets/maps/AOCTD-HillsidePyre_P.jpg differ diff --git a/assets/maps/AOCTD-Hillside_P.jpg b/assets/maps/AOCTD-Hillside_P.jpg new file mode 100644 index 0000000..36b1fcd Binary files /dev/null and b/assets/maps/AOCTD-Hillside_P.jpg differ diff --git a/assets/maps/AOCTD-Moor_Large_p.jpg b/assets/maps/AOCTD-Moor_Large_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCTD-Moor_Large_p.jpg differ diff --git a/assets/maps/AOCTD-Moor_p.jpg b/assets/maps/AOCTD-Moor_p.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCTD-Moor_p.jpg differ diff --git a/assets/maps/AOCTD-Ruins_Large_P.jpg b/assets/maps/AOCTD-Ruins_Large_P.jpg new file mode 100644 index 0000000..86b8d13 Binary files /dev/null and b/assets/maps/AOCTD-Ruins_Large_P.jpg differ diff --git a/assets/maps/AOCTD-Ruins_P.jpg b/assets/maps/AOCTD-Ruins_P.jpg new file mode 100644 index 0000000..39865ab Binary files /dev/null and b/assets/maps/AOCTD-Ruins_P.jpg differ diff --git a/assets/maps/AOCTD-StoneshillVillage_P.jpg b/assets/maps/AOCTD-StoneshillVillage_P.jpg new file mode 100644 index 0000000..66c9af3 Binary files /dev/null and b/assets/maps/AOCTD-StoneshillVillage_P.jpg differ diff --git a/assets/maps/AOCTD-ThroneRoom_P.jpg b/assets/maps/AOCTD-ThroneRoom_P.jpg new file mode 100644 index 0000000..7778712 Binary files /dev/null and b/assets/maps/AOCTD-ThroneRoom_P.jpg differ diff --git a/assets/maps/AOCTO-Battlegrounds_v3_P.jpg b/assets/maps/AOCTO-Battlegrounds_v3_P.jpg new file mode 100644 index 0000000..06534ec Binary files /dev/null and b/assets/maps/AOCTO-Battlegrounds_v3_P.jpg differ diff --git a/assets/maps/AOCTO-Citadel_p.jpg b/assets/maps/AOCTO-Citadel_p.jpg new file mode 100644 index 0000000..2e18959 Binary files /dev/null and b/assets/maps/AOCTO-Citadel_p.jpg differ diff --git a/assets/maps/AOCTO-Darkforest_p.jpg b/assets/maps/AOCTO-Darkforest_p.jpg new file mode 100644 index 0000000..4f2b9e8 Binary files /dev/null and b/assets/maps/AOCTO-Darkforest_p.jpg differ diff --git a/assets/maps/AOCTO-Hillside_P.jpg b/assets/maps/AOCTO-Hillside_P.jpg new file mode 100644 index 0000000..7f5f557 Binary files /dev/null and b/assets/maps/AOCTO-Hillside_P.jpg differ diff --git a/assets/maps/AOCTO-Stoneshill_P.jpg b/assets/maps/AOCTO-Stoneshill_P.jpg new file mode 100644 index 0000000..66c9af3 Binary files /dev/null and b/assets/maps/AOCTO-Stoneshill_P.jpg differ diff --git a/resources/images/UnknownMap.jpg b/resources/images/UnknownMap.jpg new file mode 100644 index 0000000..11b3934 Binary files /dev/null and b/resources/images/UnknownMap.jpg differ diff --git a/resources/images/toolbar/active.png b/resources/images/toolbar/active.png new file mode 100644 index 0000000..7da7a71 Binary files /dev/null and b/resources/images/toolbar/active.png differ diff --git a/source/Resources.pas b/source/Resources.pas index 7c67ffe..b861966 100644 --- a/source/Resources.pas +++ b/source/Resources.pas @@ -4,6 +4,8 @@ interface const AssetsPath = 'assets\'; AssetChivalryMedievalWarfareMapListFileName = 'Chivalry.MedievalWarfare.MapList.ini'; + AssetMapPreviewPath = 'maps\'; + AssetMapPreviewExtension = '.jpg'; UserDataPath = 'Chivalry Server Launcher\'; diff --git a/source/view/Forms.Main.dfm b/source/view/Forms.Main.dfm index 1d257f3..24e0778 100644 --- a/source/view/Forms.Main.dfm +++ b/source/view/Forms.Main.dfm @@ -76,7 +76,7 @@ object MainForm: TMainForm AlignWithMargins = True Left = 8 Top = 30 - Width = 541 + Width = 403 Height = 359 Margins.Left = 8 Margins.Top = 0 @@ -99,11 +99,12 @@ object MainForm: TMainForm OnChange = vstMapListChange OnDragOver = vstMapListDragOver OnDragDrop = vstMapListDragDrop + OnFocusChanged = vstMapListFocusChanged OnGetText = vstMapListGetText Columns = < item Position = 0 - Width = 337 + Width = 199 WideText = 'Map name' end item @@ -161,6 +162,64 @@ object MainForm: TMainForm AutoSize = True end end + object pnlMapListSidebar: TPanel + AlignWithMargins = True + Left = 419 + Top = 30 + Width = 130 + Height = 359 + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 8 + Margins.Bottom = 8 + Align = alRight + BevelOuter = bvNone + TabOrder = 2 + ExplicitLeft = 415 + inline frmMapPreview: TMapPreviewFrame + Left = 0 + Top = 0 + Width = 130 + Height = 130 + Align = alTop + TabOrder = 0 + ExplicitTop = 216 + end + object btnMapListSave: TButton + AlignWithMargins = True + Left = 0 + Top = 171 + Width = 130 + Height = 25 + Margins.Left = 0 + Margins.Top = 8 + Margins.Right = 0 + Margins.Bottom = 0 + Action = actMapListSave + Align = alTop + TabOrder = 2 + ExplicitLeft = 28 + ExplicitTop = 168 + ExplicitWidth = 75 + end + object btnMapListLoad: TButton + AlignWithMargins = True + Left = 0 + Top = 138 + Width = 130 + Height = 25 + Margins.Left = 0 + Margins.Top = 8 + Margins.Right = 0 + Margins.Bottom = 0 + Action = actMapListLoad + Align = alTop + TabOrder = 1 + ExplicitLeft = 28 + ExplicitTop = 168 + ExplicitWidth = 75 + end + end end object tsConfiguration: TTabSheet Caption = 'Server - Configuration' @@ -309,8 +368,10 @@ object MainForm: TMainForm TabOrder = 1 TreeOptions.PaintOptions = [toHideFocusRect, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages] TreeOptions.SelectionOptions = [toFullRowSelect, toMiddleClickSelect, toRightClickSelect] + OnDblClick = vstGamesDblClick OnFocusChanged = vstGamesFocusChanged OnGetText = vstGamesGetText + OnPaintText = vstGamesPaintText Columns = < item Position = 0 @@ -518,6 +579,20 @@ object MainForm: TMainForm Action = actGameRemove AutoSize = True end + object tbGamesSep1: TToolButton + Left = 178 + Top = 0 + Width = 8 + Caption = 'tbGamesSep1' + ImageIndex = 2 + Style = tbsSeparator + end + object tbGameActive: TToolButton + Left = 186 + Top = 0 + Action = actGameActive + AutoSize = True + end end end object tsAbout: TTabSheet @@ -2260,6 +2335,121 @@ object MainForm: TMainForm FDCBD5FEC029EF257802B99873F02768CFEC0000000049454E44AE426082} PictureName = 'down' end + object gcToolbaractive: TX2GraphicContainerItem + Picture.Data = { + 0954506E67496D61676589504E470D0A1A0A0000000D49484452000000100000 + 001008060000001FF3FF6100000B2769545874584D4C3A636F6D2E61646F6265 + 2E786D7000000000003C3F787061636B657420626567696E3D22EFBBBF222069 + 643D2257354D304D7043656869487A7265537A4E54637A6B633964223F3E0A3C + 783A786D706D65746120786D6C6E733A783D2261646F62653A6E733A6D657461 + 2F2220783A786D70746B3D2241646F626520584D5020436F726520352E302D63 + 3036302036312E3133343737372C20323031302F30322F31322D31373A33323A + 30302020202020202020223E0A203C7264663A52444620786D6C6E733A726466 + 3D22687474703A2F2F7777772E77332E6F72672F313939392F30322F32322D72 + 64662D73796E7461782D6E7323223E0A20203C7264663A446573637269707469 + 6F6E207264663A61626F75743D22220A20202020786D6C6E733A70686F746F73 + 686F703D22687474703A2F2F6E732E61646F62652E636F6D2F70686F746F7368 + 6F702F312E302F220A20202020786D6C6E733A786D705269676874733D226874 + 74703A2F2F6E732E61646F62652E636F6D2F7861702F312E302F726967687473 + 2F220A20202020786D6C6E733A786D703D22687474703A2F2F6E732E61646F62 + 652E636F6D2F7861702F312E302F220A20202020786D6C6E733A786D704D4D3D + 22687474703A2F2F6E732E61646F62652E636F6D2F7861702F312E302F6D6D2F + 220A20202020786D6C6E733A73744576743D22687474703A2F2F6E732E61646F + 62652E636F6D2F7861702F312E302F73547970652F5265736F75726365457665 + 6E7423220A20202020786D6C6E733A64633D22687474703A2F2F7075726C2E6F + 72672F64632F656C656D656E74732F312E312F220A20202020786D6C6E733A49 + 70746334786D70436F72653D22687474703A2F2F697074632E6F72672F737464 + 2F4970746334786D70436F72652F312E302F786D6C6E732F220A20202020786D + 6C6E733A706C75735F315F3D22687474703A2F2F6E732E757365706C75732E6F + 72672F6C64662F786D702F312E302F220A20202070686F746F73686F703A4865 + 61646C696E653D225573657220696E74657266616365206D616B65207570220A + 202020786D705269676874733A4D61726B65643D2254727565220A202020786D + 703A4D65746164617461446174653D22323031312D30312D32355431333A3535 + 3A31352B30313A3030220A202020786D704D4D3A496E7374616E636549443D22 + 786D702E6969643A363135353933354138323238453031313938394343304131 + 4144303242354332220A202020786D704D4D3A446F63756D656E7449443D2278 + 6D702E6469643A30434645453044344530323745303131393839434330413141 + 44303242354332220A202020786D704D4D3A4F726967696E616C446F63756D65 + 6E7449443D22786D702E6469643A304346454530443445303237453031313938 + 3943433041314144303242354332223E0A2020203C786D705269676874733A55 + 736167655465726D733E0A202020203C7264663A416C743E0A20202020203C72 + 64663A6C6920786D6C3A6C616E673D22782D64656661756C74223E4372656174 + 69766520436F6D6D6F6E73204174747269627574696F6E2D4E6F6E436F6D6D65 + 726369616C206C6963656E73653C2F7264663A6C693E0A202020203C2F726466 + 3A416C743E0A2020203C2F786D705269676874733A55736167655465726D733E + 0A2020203C786D704D4D3A486973746F72793E0A202020203C7264663A536571 + 3E0A20202020203C7264663A6C690A20202020202073744576743A616374696F + 6E3D227361766564220A20202020202073744576743A696E7374616E63654944 + 3D22786D702E6969643A30434645453044344530323745303131393839434330 + 41314144303242354332220A20202020202073744576743A7768656E3D223230 + 31312D30312D32345431383A33393A30312B30313A3030220A20202020202073 + 744576743A6368616E6765643D222F6D65746164617461222F3E0A2020202020 + 3C7264663A6C690A20202020202073744576743A616374696F6E3D2273617665 + 64220A20202020202073744576743A696E7374616E636549443D22786D702E69 + 69643A3631353539333541383232384530313139383943433041314144303242 + 354332220A20202020202073744576743A7768656E3D22323031312D30312D32 + 355431333A35353A31352B30313A3030220A20202020202073744576743A6368 + 616E6765643D222F6D65746164617461222F3E0A202020203C2F7264663A5365 + 713E0A2020203C2F786D704D4D3A486973746F72793E0A2020203C64633A6372 + 6561746F723E0A202020203C7264663A5365713E0A20202020203C7264663A6C + 693E47656E746C656661636520637573746F6D20746F6F6C6261722069636F6E + 732064657369676E3C2F7264663A6C693E0A202020203C2F7264663A5365713E + 0A2020203C2F64633A63726561746F723E0A2020203C64633A64657363726970 + 74696F6E3E0A202020203C7264663A416C743E0A20202020203C7264663A6C69 + 20786D6C3A6C616E673D22782D64656661756C74223E576972656672616D6520 + 6D6F6E6F20746F6F6C6261722069636F6E733C2F7264663A6C693E0A20202020 + 3C2F7264663A416C743E0A2020203C2F64633A6465736372697074696F6E3E0A + 2020203C64633A7375626A6563743E0A202020203C7264663A4261673E0A2020 + 2020203C7264663A6C693E637573746F6D2069636F6E2064657369676E3C2F72 + 64663A6C693E0A20202020203C7264663A6C693E746F6F6C6261722069636F6E + 733C2F7264663A6C693E0A20202020203C7264663A6C693E637573746F6D2069 + 636F6E733C2F7264663A6C693E0A20202020203C7264663A6C693E696E746572 + 666163652064657369676E3C2F7264663A6C693E0A20202020203C7264663A6C + 693E75692064657369676E3C2F7264663A6C693E0A20202020203C7264663A6C + 693E6775692064657369676E3C2F7264663A6C693E0A20202020203C7264663A + 6C693E7461736B6261722069636F6E733C2F7264663A6C693E0A202020203C2F + 7264663A4261673E0A2020203C2F64633A7375626A6563743E0A2020203C6463 + 3A7269676874733E0A202020203C7264663A416C743E0A20202020203C726466 + 3A6C6920786D6C3A6C616E673D22782D64656661756C74223E43726561746976 + 6520436F6D6D6F6E73204174747269627574696F6E2D4E6F6E436F6D6D657263 + 69616C206C6963656E73653C2F7264663A6C693E0A202020203C2F7264663A41 + 6C743E0A2020203C2F64633A7269676874733E0A2020203C4970746334786D70 + 436F72653A43726561746F72436F6E74616374496E666F0A2020202049707463 + 34786D70436F72653A436955726C576F726B3D22687474703A2F2F7777772E67 + 656E746C65666163652E636F6D222F3E0A2020203C706C75735F315F3A496D61 + 676543726561746F723E0A202020203C7264663A5365713E0A20202020203C72 + 64663A6C690A202020202020706C75735F315F3A496D61676543726561746F72 + 4E616D653D2267656E746C65666163652E636F6D222F3E0A202020203C2F7264 + 663A5365713E0A2020203C2F706C75735F315F3A496D61676543726561746F72 + 3E0A2020203C706C75735F315F3A436F707972696768744F776E65723E0A2020 + 20203C7264663A5365713E0A20202020203C7264663A6C690A20202020202070 + 6C75735F315F3A436F707972696768744F776E65724E616D653D2267656E746C + 65666163652E636F6D222F3E0A202020203C2F7264663A5365713E0A2020203C + 2F706C75735F315F3A436F707972696768744F776E65723E0A20203C2F726466 + 3A4465736372697074696F6E3E0A203C2F7264663A5244463E0A3C2F783A786D + 706D6574613E0A3C3F787061636B657420656E643D2272223F3E47D4B9E10000 + 001974455874536F6674776172650041646F626520496D616765526561647971 + C9653C0000003C74455874414C54546167005468697320697320746865206963 + 6F6E2066726F6D2047656E746C65666163652E636F6D20667265652069636F6E + 73207365742E20D86BE8C40000004474455874436F7079726967687400437265 + 617469766520436F6D6D6F6E73204174747269627574696F6E204E6F6E2D436F + 6D6D65726369616C204E6F2044657269766174697665737BDDB0A00000004569 + 5458744465736372697074696F6E000000000054686973206973207468652069 + 636F6E2066726F6D2047656E746C65666163652E636F6D20667265652069636F + 6E73207365742E20BC11F81A0000004869545874436F70797269676874000000 + 0000437265617469766520436F6D6D6F6E73204174747269627574696F6E204E + 6F6E2D436F6D6D65726369616C204E6F2044657269766174697665735882CB05 + 000001044944415478DA6364A0103092A3C9C0C040809191713F907981640374 + 7575619A0D80F8034906686A6A823503B101C95E505555C5D00C048D28062829 + 2981241DEEDDBB37014D1CD9D93070E0EEDDBB8E7003E4E4E40CA03608FCFFFF + 7FC2C3870F0BA1E2D86CFE00E42BDEBF7F1F120652525270CD30154043128178 + 0316CD20E0F8E4C99303F030909090788FAC19C9900740710534E1C6E7CF9F37 + A004A2A8A8E87C20954044581E78FDFAB523B2003C0C040505091902F6F7BB77 + EF3E60350004F8F8F8F019E2F8E9D3A703E88218E9808B8B0B9B218DDFBE7D6B + C0662AD684C4C6C6866CC8815FBF7E3932E000385322333333C8900090BFFFFC + F9F3816403880500C19F5431B559EAF70000000049454E44AE426082} + PictureName = 'active' + end end object glToolbar: TX2GraphicList Container = gcToolbar @@ -2323,6 +2513,14 @@ object MainForm: TMainForm ShortCut = 16424 OnExecute = actMapDownExecute end + object actMapListLoad: TAction + Caption = '&Load map list' + Visible = False + end + object actMapListSave: TAction + Caption = 'Sa&ve map list' + Visible = False + end end object alGames: TActionList Images = glToolbar @@ -2341,5 +2539,11 @@ object MainForm: TMainForm ShortCut = 16430 OnExecute = actGameRemoveExecute end + object actGameActive: TAction + Caption = '&Set as active' + Enabled = False + ImageIndex = 4 + OnExecute = actGameActiveExecute + end end end diff --git a/source/view/Forms.Main.pas b/source/view/Forms.Main.pas index 8184152..22f87f5 100644 --- a/source/view/Forms.Main.pas +++ b/source/view/Forms.Main.pas @@ -11,6 +11,8 @@ uses Vcl.Controls, Vcl.ExtCtrls, Vcl.Forms, + Vcl.Graphics, + Vcl.Imaging.jpeg, Vcl.Imaging.pngimage, Vcl.ImgList, Vcl.Mask, @@ -29,6 +31,7 @@ uses X2CLMenuBar, X2CLmusikCubeMenuBarPainter, + Frame.MapPreview, Game.Base, Game.Intf; @@ -121,6 +124,16 @@ type alGames: TActionList; actGameAdd: TAction; actGameRemove: TAction; + pnlMapListSidebar: TPanel; + frmMapPreview: TMapPreviewFrame; + tbGamesSep1: TToolButton; + tbGameActive: TToolButton; + actGameActive: TAction; + gcToolbaractive: TX2GraphicContainerItem; + btnMapListSave: TButton; + btnMapListLoad: TButton; + actMapListLoad: TAction; + actMapListSave: TAction; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); @@ -132,22 +145,26 @@ type procedure actCloseExecute(Sender: TObject); procedure actGameAddExecute(Sender: TObject); procedure actGameRemoveExecute(Sender: TObject); + procedure actGameActiveExecute(Sender: TObject); procedure vstGamesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); + procedure vstGamesPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); procedure vstGamesFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); + procedure vstGamesDblClick(Sender: TObject); procedure vstMapListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vstMapListChange(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure vstMapListDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean); procedure vstMapListDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); + procedure vstMapListFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure actMapAddExecute(Sender: TObject); procedure actMapRemoveExecute(Sender: TObject); procedure actMapUpExecute(Sender: TObject); procedure actMapDownExecute(Sender: TObject); private type TBindingExpressionList = TList; - TPageMenuMap = TDictionary; + TPageMenuDictionary = TDictionary; private FActiveGame: TCustomGame; - FPageMenuMap: TPageMenuMap; + FPageMenuMap: TPageMenuDictionary; FUIBindings: TBindingExpressionList; procedure SetActiveGame(const Value: TCustomGame); @@ -171,7 +188,7 @@ type procedure CopyMapSelection(ANodes: TNodeArray; ATargetIndex: Integer); property ActiveGame: TCustomGame read FActiveGame write SetActiveGame; - property PageMenuMap: TPageMenuMap read FPageMenuMap; + property PageMenuMap: TPageMenuDictionary read FPageMenuMap; property UIBindings: TBindingExpressionList read FUIBindings; end; @@ -182,7 +199,6 @@ uses System.Math, System.StrUtils, System.SysUtils, - Vcl.Graphics, Vcl.GraphUtil, Vcl.Themes, Winapi.ShellAPI, @@ -236,7 +252,7 @@ var begin FUIBindings := TBindingExpressionList.Create; - FPageMenuMap := TPageMenuMap.Create(pcMain.PageCount); + FPageMenuMap := TPageMenuDictionary.Create(pcMain.PageCount); vstGames.NodeDataSize := SizeOf(TCustomGame); @@ -441,12 +457,11 @@ var sourceShift: Integer; sourceIndex: Integer; newIndex: Integer; - newNode: PVirtualNode; selectedMaps: TList; map: TGameMap; begin - if (ATargetIndex < 0) or (ATargetIndex > vstMapList.RootNodeCount) then + if (ATargetIndex < 0) or (Cardinal(ATargetIndex) > vstMapList.RootNodeCount) then exit; if not Supports(ActiveGame, IGameMapList, gameMapList) then @@ -629,6 +644,21 @@ begin end; +procedure TMainForm.actGameActiveExecute(Sender: TObject); +begin + if Assigned(vstGames.FocusedNode) then + begin + vstGames.BeginUpdate; + try + ActiveGame := TGameList.Instance[vstGames.FocusedNode^.Index]; + vstGames.InvalidateNode(vstGames.FocusedNode); + finally + vstGames.EndUpdate; + end; + end; +end; + + procedure TMainForm.vstGamesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var game: TCustomGame; @@ -649,6 +679,13 @@ end; procedure TMainForm.vstGamesFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); begin actGameRemove.Enabled := Assigned(Sender.FocusedNode); + actGameActive.Enabled := Assigned(Sender.FocusedNode) and (ActiveGame <> TGameList.Instance[Sender.FocusedNode^.Index]); +end; + + +procedure TMainForm.vstGamesDblClick(Sender: TObject); +begin + actGameActive.Execute; end; @@ -673,6 +710,13 @@ begin end; +procedure TMainForm.vstGamesPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); +begin + if (Column = GameColumnName) and (TGameList.Instance[Node^.Index] = ActiveGame) then + TargetCanvas.Font.Style := [fsBold]; +end; + + procedure TMainForm.vstMapListChange(Sender: TBaseVirtualTree; Node: PVirtualNode); var hasSelection: Boolean; @@ -730,6 +774,18 @@ begin end; +procedure TMainForm.vstMapListFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); +var + gameMapList: IGameMapList; + +begin + if not Supports(ActiveGame, IGameMapList, gameMapList) then + exit; + + frmMapPreview.Load(gameMapList.GetMapList[Node^.Index].Name); +end; + + procedure TMainForm.actMapAddExecute(Sender: TObject); var gameMapList: IGameMapList; diff --git a/source/view/Forms.Map.dfm b/source/view/Forms.Map.dfm index 12a6e85..df24f7f 100644 --- a/source/view/Forms.Map.dfm +++ b/source/view/Forms.Map.dfm @@ -32,8 +32,6 @@ object MapForm: TMapForm AutoSize = True BevelOuter = bvNone TabOrder = 3 - ExplicitTop = 91 - ExplicitWidth = 503 object btnCancel: TButton Left = 486 Top = 0 @@ -44,7 +42,6 @@ object MapForm: TMapForm Caption = 'Cancel' ModalResult = 2 TabOrder = 1 - ExplicitLeft = 428 end object btnOK: TButton AlignWithMargins = True @@ -61,14 +58,13 @@ object MapForm: TMapForm Default = True TabOrder = 0 OnClick = btnOKClick - ExplicitLeft = 345 end end object vstMap: TVirtualStringTree AlignWithMargins = True - Left = 8 + Left = 154 Top = 37 - Width = 561 + Width = 415 Height = 433 Margins.Left = 8 Margins.Top = 8 @@ -91,8 +87,8 @@ object MapForm: TMapForm OnFocusChanging = vstMapFocusChanging OnGetText = vstMapGetText OnPaintText = vstMapPaintText - ExplicitTop = 13 - ExplicitHeight = 457 + ExplicitLeft = 8 + ExplicitWidth = 561 Columns = <> end object pnlMapName: TPanel @@ -109,27 +105,25 @@ object MapForm: TMapForm AutoSize = True BevelOuter = bvNone TabOrder = 2 - ExplicitTop = 468 - ExplicitWidth = 689 + ExplicitTop = 475 DesignSize = ( 561 21) object lblMapName: TLabel - Left = 0 + Left = 146 Top = 3 Width = 53 Height = 13 Caption = 'Map name:' end object edtMapName: TEdit - Left = 76 + Left = 216 Top = 0 - Width = 485 + Width = 341 Height = 21 Anchors = [akLeft, akTop, akRight] TabOrder = 0 OnChange = edtMapNameChange - ExplicitWidth = 613 end end object pnlFilter: TPanel @@ -146,26 +140,54 @@ object MapForm: TMapForm AutoSize = True BevelOuter = bvNone TabOrder = 0 - ExplicitLeft = 12 - ExplicitTop = 482 DesignSize = ( 561 21) object lblFilter: TLabel - Left = 0 + Left = 146 Top = 3 Width = 28 Height = 13 Caption = 'Filter:' end object edtFilter: TEdit - Left = 76 + Left = 216 Top = 0 - Width = 485 + Width = 345 Height = 21 Anchors = [akLeft, akTop, akRight] TabOrder = 0 OnChange = edtFilterChange end end + object pnlMapPreview: TPanel + AlignWithMargins = True + Left = 8 + Top = 29 + Width = 130 + Height = 449 + Margins.Left = 8 + Margins.Top = 0 + Margins.Right = 8 + Margins.Bottom = 0 + Align = alLeft + BevelOuter = bvNone + TabOrder = 4 + ExplicitLeft = 0 + ExplicitHeight = 342 + inline frmMapPreview: TMapPreviewFrame + AlignWithMargins = True + Left = 0 + Top = 8 + Width = 130 + Height = 130 + Margins.Left = 0 + Margins.Top = 8 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + TabOrder = 0 + ExplicitWidth = 342 + end + end end diff --git a/source/view/Forms.Map.pas b/source/view/Forms.Map.pas index c8492cb..f5f5d68 100644 --- a/source/view/Forms.Map.pas +++ b/source/view/Forms.Map.pas @@ -11,6 +11,7 @@ uses VirtualTrees, + Frame.MapPreview, Game.Base, Game.Intf; @@ -27,6 +28,8 @@ type pnlFilter: TPanel; lblFilter: TLabel; edtFilter: TEdit; + frmMapPreview: TMapPreviewFrame; + pnlMapPreview: TPanel; procedure btnOKClick(Sender: TObject); procedure FormCreate(Sender: TObject); @@ -177,7 +180,7 @@ begin begin nodeData := Sender.GetNodeData(Node); - Abort := SameText(nodeData^.Name, AMapName); + Abort := (Sender.GetNodeLevel(Node) > 0) and SameText(nodeData^.Name, AMapName); end, nil); end; @@ -259,9 +262,13 @@ var nodeData: PGameMap; begin + if FLockMapChange then + exit; + if Assigned(Node) then begin nodeData := Sender.GetNodeData(Node); + frmMapPreview.Load(nodeData^.Name); FLockMapChange := True; try @@ -269,7 +276,8 @@ begin finally FLockMapChange := False; end; - end; + end else + frmMapPreview.Clear; end; @@ -298,8 +306,6 @@ end; procedure TMapForm.edtFilterChange(Sender: TObject); var node: PVirtualNode; - filtered: Boolean; - childNode: PVirtualNode; begin vstMap.BeginUpdate; @@ -347,12 +353,22 @@ begin exit; node := FindMapNode(MapName); - vstMap.FocusedNode := node; + FLockMapChange := True; + try + vstMap.FocusedNode := node; + finally + FLockMapChange := False; + end; if Assigned(node) then - vstMap.Selected[node] := True - else + begin + vstMap.Selected[node] := True; + frmMapPreview.Load(MapName); + end else + begin vstMap.ClearSelection; + frmMapPreview.Clear; + end; end; end. diff --git a/source/view/Frame.MapPreview.dfm b/source/view/Frame.MapPreview.dfm new file mode 100644 index 0000000..b476c4d --- /dev/null +++ b/source/view/Frame.MapPreview.dfm @@ -0,0 +1,226 @@ +object MapPreviewFrame: TMapPreviewFrame + Left = 0 + Top = 0 + Width = 130 + Height = 130 + TabOrder = 0 + object shpBorder: TShape + Left = 0 + Top = 0 + Width = 41 + Height = 45 + Brush.Style = bsClear + end + object imgMapPreview: TImage + AlignWithMargins = True + Left = 0 + Top = 2 + Width = 29 + Height = 35 + Margins.Left = 1 + Margins.Top = 1 + Margins.Right = 1 + Margins.Bottom = 1 + end + object gcMapPreview: TX2GraphicContainer + Left = 36 + Top = 28 + object gcMapPreviewUnknownMap: TX2GraphicContainerItem + Picture.Data = { + 0A544A504547496D616765FE170000FFD8FFE000104A46494600010200006400 + 640000FFEC00114475636B79000100040000003C0000FFEE000E41646F626500 + 64C000000001FFDB0084000604040405040605050609060506090B080606080B + 0C0A0A0B0A0A0C100C0C0C0C0C0C100C0E0F100F0E0C1313141413131C1B1B1B + 1C1F1F1F1F1F1F1F1F1F1F010707070D0C0D181010181A1511151A1F1F1F1F1F + 1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F + 1F1F1F1F1F1F1F1F1F1F1F1FFFC00011080080008003011100021101031101FF + C400960000020301010101000000000000000000040502030607010008010003 + 0101010000000000000000000000000102030405100002010204050203060404 + 060300000001020311040021120531415113066122713214819142522307A162 + 7215B1D1A233F0E1825324164393251100020202020201020603010000000000 + 000111022103311241045161227181A1D14213C1F13214FFDA000C0301000211 + 0311003F00ED897018568472CF2C60681313D79E002CEE807001EF72B960033B + E5F20B9BAD8B65198BEBE59AE17AC1663BCE0FC5828C26557CB346D73CF04927 + 82E873C0079F5280E670C0F4DD57860020ECAEA4380C0F1073C0054B31321570 + D2460575AFBA45A7A71907FAFF00AB00145C37E9A4A8EB25BCC3543321AA38F4 + 3FE238E1318B669C8273C4B1823CC49C0050F70A1B4161AF8E9AE74F860012DF + F926DF0CE606726456D2C029A03EA7040CDB09472C5121313903D70488917A71 + C21C14BDD3D72C861819AB7B8379E717770C6B16D36696A9E935CB77643F622A + 8C22BC1A15BB078E024935C823A530001CBBE6D504ED0DC5CAA3C67F522AD1F8 + 034A1A71AE28200B77F37B7B6899ED2D7BBA464B9F01CEA0E2BF208FA8B7C7BF + 74B64DEEEFE80ABD96E2455209482B275ED38A6AF852B84D0441A0FEE1A4D41C + F911880299B75963EE5CC64998E72C24068671CFBA991D6393A10DD6B84CA4A7 + 00936E3B5DEBB47B6BB7F7055D726D52652E9FCD139A0753CB81C1286E965966 + 466F23DD1277D4153492A6165A53E35F757008452DC3872EB2307E0581209078 + E78000DEEA38DBB8E9DE63511C6491A9E99027A0E2DE98A480ECD1DC2E9D6400 + 0E6286B97F0C2242A3BA4640C0E4786003D370A700C1E4B8450598D154558F40 + 38E09032FE1CEF36D32EE726526ED7335E67F919B4443FFAD0610EC3BEF95C04 + 9E8B9D4CA09C8915C319CDBCB37B81BC867908D5292CAAD41AB56428BC864B9E + 1D6D2CD2D5846577ABF79AC97DC174E71E93EDA00A084E7A7E39E34821331725 + FDC437B1CB6EE639223DE5753F294CF50E94C508FD07E31E4716F9B159EE4A40 + 9278FF005D0705957DB201E9AB318C6CA010C8CC3AE2462BBEDCE1B6BA579A24 + B9B67A06A10B346CBC1A3907BD48F8D30872E206EF6165E43145169FAC120290 + 6E71E94B84D20B69B91906A01C4FFA789B488E0CB6EFE3DB0ED96324B79BF44D + 76A5CC56F6F0C926A08330CC40D27565D3D7A5FF005895CCC1CDFBA191D48A44 + A86BA52BCEB9EA6E2C7EEC8622D82D1AD7DCE5625A39DF429A85D5450390A570 + 84151F90DF22690D52465ED5C8D78E0005B9DDAEEE40EEBB871500AFB72FB298 + 005FBE7906E56DB0DCDBC52306997E9E339125E73A06673FC584341516E77905 + 9C5648C45AC312C2880014545D233030C4531DD5CC527761670FC0126BE87080 + 23FBC6E0DF2C8F519F2FF2C0339DF9D3EE515D4D242FFA2CC090A2AE35D09666 + 232CD820C6AAB0A415A5C099361DF2F6E36EB72422DF422E5535977589AA03CA + 175151974C45B6249B3A69A1B697C8AF79B09F6FBDEDC647B498A474AD482396 + A15E58BD56EC8CF7D3A3835BFB71B8DFA7D4D9C3A1638C891C2B149351142420 + CA869EE23D306C506299B57DC2F5AB491C7FD4719140524C5DBDC0173C4D73AF + 1AE0081AEDBB95D78FECDB86F4B04D3349118A04B70ACE8AAEA5EE1A37203C62 + 9A39E67962E9F526C739DE7F750CD0B496E23BA765096AECA62ED95C8892225A + B4EA2953D78E36215449E3F16E70EF506E3B8DD04B670657FD45479514E97489 + 4F2AE55A6919F4C2BA2D283A5770E922B91CC8E47190065A4EAD1E80DEF5AF1A + D6989605C4B5695A9A65C700186FDC2B8DD967B78E1940B48D45CB0506AA626F + 9DBEDA05C125246C2D6E52EACE1B946AA4E8197222B97BA80D381C1022F0A436 + 469E984324132143E87AE10408BC966DAB6D4B896E57BD737B069168481A97F3 + B7E5E1C79D31D7AB43B2978A89B484B26F7BB6FF00696CDB5DDC5B742BA61DDE + 58C0371098FF00183505D5940A0E472C716CD54D567E53E3F63D4D5B2FBAA926 + AB1CFCFE2663CB277EFDB8794BCD45323380A5F4823569CBAE35F5961FC1C9EE + 3FB9006DF3DD43325E5BCC62B8473A241E9CBD6BCC63A4E33F477835EF85DD78 + DD8EE0DB73DFEFB7A5A35B520CAA93A00194443222A75660E58E7D50DB4F94FF + 00D1774F0D703F9FFB5C3215BE82DEF7730A08DBE1822ECC6D4A524655F730AF + C8A7EDC5DACB84895530FF00B89FB85B6EDBB7CD6770EB717C47B582A0EC05F9 + 6381402A8BC9D6946191CB109365A38B78C596D3BCEEB7326E10089A5025B785 + 18A067D5EEA0AD68472C696C2279635BFB8DB368DFDA0BCB60DB5B592430A1AD + 5523058AA356AA5E4515233E3D7129F6592B8CA35C182398C9F683442321F0FF + 002C41321566F4B85E86A08C024342D55A624A02B09D22BBDD6EDA40972EB0D9 + D93269D4A151A4929A87E661C317526D2F839F4FBFDDA6F306E8F7125E5D2369 + 91E5919F50AE961A8F0071AB52A0CD383A4DA9B9BAB05BC36D25BAB00C5641C2 + BC0D7983C8E30B55A374E4AF77DE2DB68DA9EF6450F293DBB583FEE4C46429D1 + 466D8E8F574F772F840DC2167EDBFEDD9F3DDCAFB7ADFEF5ADFC6ACE5297B78D + 20592E660A0BC11BF0545AFBD87F48C746DDCDE0CA4EF7796DFB59FB77E2ADBA + C3B6D9596DB047AE378A247964A81401DAB23B364055B1C5B76250B96F82A8AC + DCF107E72F2AF30F38F30B99B708DE1D836E9AA6DEC6DA18FEA3B35A069A6214 + FBBE3C780C4D742E6D97FA1A777E04167E1BE5B721A54432C318265BCB955458 + CE927F526A22AFA6ACF1BAAFC19B66D7C73CA67B48E5D8B646B7DA377B901847 + 11FD1DCE254F7ADB4F255E3B939FB75057E191A0C677AE64AAD97923E4FF00B8 + 76365B505DB1B4BB2D0CA6A26561F3AB039A904612A8D1CB6C2DFF00F60DCCCF + 7F70B05BB12503B2AD7A91A881974E672C6B104B723EDF6CB61B3065B79D6D6D + 56047B1B47AC97371213473A57D88A0FE266E55184A405FE77B84286CF65497E + A05A5B24B3DDB68677BA94565456503F4E1A76C2826A6AD9E54210D3375133CD + 3767B2E5E4A05A0E7D6A787DB8C59290E61DA6DD5EDE2BC9985CAC940915349A + 91EE2DF8A9D073C64B726F069D20023BDB749AF6F267D11290B56340401C33E6 + 71A3252236304D75B4C093A069AE58DC48BFCCC4D474F90D3ECC55536E113669 + 297C1969B6B822BD91EE9219222E585AABB301FD6E85450F456C7A7ABD36D7DD + 8382FECAFE26B22F2E85A35BDB701248008E4B634A14A50C7C335651C71E7EED + 2F5DA19DDAB62B2931FE77BE8BBDCC5BDAFF00B4891259961987B865F77C403F + C31D557D3514F2CDC6F092ED9B75A6D16EC536ADB2358D554FB10FCCF23D0FCC + CC6AC71C5DFED4CD69AE6D00BFB97B84177BA788ED0F72D7BB44A62B99955AA1 + D54572AF2049C61A6DDF6DADF185FE4AD95E9555FA8C2E6EB63315BDC42EB1A9 + 4866B80E3585FAA790811915CE0B740003CEA698EB325C4B2CB38B70DFAFEF21 + BE67B4D8E1731436CBA8C5028CE3A2FE32C0D589CCE2E3E0C6D7C2C193F3ADAF + 69DAECE4B59144B0D6A91A3668C335B8B793967CB125239ADDDD497772B35FB1 + 9D541EF4CA4AB4FA05416AD4770E41A9F1C34A0AE40E4DD25770248C30A69444 + 14007200618B80799A682E2B28789B22A1C153A788C9A996043B391BDEEE36B7 + D16A9214ABB771580A1576A6B4A8E03F2FA614049DB6430EDD03A40C1EFA4D22 + 590E6AA9C5D1473AF0AE381DD5B9E0D556047B96E42CEC9AECD5A504456B12D6 + BA883EE006748CD3EDC3D549616643C37C5EEBC86C778B437B1DAA5BF6E6B8B9 + 948114606AD45DC9D2B97F1C6BB2B94D934BC2690BBCBF7ED967BB6DBFC7A792 + 6DB2CD16292FC9A2CB30AD5A15C8E80294EB8BAA6B2438664EE3739F456A42B5 + 54BF2AD3865C33C7A74F6257D4E1B698651B7EE724770BA891A805901AE32DCB + B2FA9A6B7D596F94CEC6E24746E0D0C8AC3AE83983E86985B14D57E47549ACB1 + F35BBDE76A92CE0922FACB8005DDA3A80ED5203988F30C33EA31E6DAAEAA3C1D + DA7655D93FE480B78DE66B6DA7C7B768CF7A6D86E64B29108A512BAD55B9E618 + E1685176BE507B89E19E5C79578FDCD8CD00D7190804601E26363A7A71B790AF + F50F5C75C338938348BFB89B74FB0D9CB6737FFAB656E963770643BF1C22914D + 97E2D3C6BCEBD70CCFAE4C1EF5BBDC6EEAC1EAC03160D50029E3424D07D98703 + 33B757D3CF1456CCFF00F8F6E4F6A3000153C5B21EE27A9C0CBAA41DE313CF6F + 7CD736E81E6B7469550D3DCABF3AE7D56B9E161E194745867DB775B68EED523B + 889B34322AB15EAA6A0D08E78E7B55D5C153251B9EDD65B847DBBA855C7E1651 + A597A6923055B42793413C9042CCF348B2B7E18D0EA04FF330E0B8CABABE46EC + 6637CD9E7BEBB4BE865D13434D31162B180331A78E9A7F1C7456119D9499BBE6 + DC2DECEE6C3B9DFB59D83CF142E4C5A92B42C0501209C5369B252842DB69DE3B + A86794095A2D234BA8D1EDE45464700076E096D797373F4E163EEB1784466888 + 4FE0653CBD460AB879075958141B3BF8641DE8FB47504899B3D6B4E2295AD3A8 + C7552D2F0616AC7214D21B98FE8A5986B8D4D6A6829C88FE938D1A4D43E4BD76 + 94266592294A31D2EBC194F03C98118E5B5630CDAAF21ADE41B95E5BFD2DFDD3 + C912B0660E6AC4A0A0AB7CC69CAB885AAA9CA592AD7B3505316D9AE3EF16D05D + AA8AD9D13AE077CC1BD7D67D3B371FB0FE0F0BDF62B18EFF00E8DFB6C3B8B22B + A8744A5753AEAD4829D463AE8F5F0DE4F3EF5BF2B8135CA770025CE9E22BC2A7 + 9E34B694B833AEC6F92A86DD58BD7DE545550102A4E55CF90C617AC1B55C85EC + 327D2EEF01724062503A30E2C34D6B9F5C569D74B5A2C16BD92C05EC9BC4BB2E + E52DBCB536C5B45C47CC53838F5A7F0C46DD732BCA2EB637A1D248D64460D1B0 + 0C8C0F1073046389A8340A2187E1FB30E44299B679E59E48AE2F266B59486088 + 400B4FC26B5CBA5300CF6D364B3FA7B8EC23160E52135258E9C8FDED5C26C685 + 3BD6C315B48238DD5DCD05141F99B9660660E58BAF67E09B42F278FE256EB704 + CDB942AB9552206490310091F8538E5C71D5AFD4B3E5A4725FDB4B84D8D6CDB6 + C8626B4B9B75BDB6D2000F93AF1A90D90E7E98DD7AD0B0CC9FB12F28164F12DB + EE6368BC7675B3BB946705FA90CC3A248726F41538E478B7393A6B6C0877AF1A + B9B08DA2BEB59639D4829352894E74E35CF9571BAFBD7D4A56467D60114C0CB1 + 8627E56E469CF1CF7AB474EAB29C87C12BB48920A12A43134A83A4D40A1E23AE + 34F5B44BC8BDBF67ED8513E4EA3B56ECF716A2669FB9752B19C4674831AB50E8 + C801A54D6831CEE2610DD2CB2C4973B5ED5B5B5FEED71A4AC8ECF1A950562591 + B2445E6C6BC7A6367B2D64AA62AAAB2C41BFDC779076A18E609FEE23282DA48A + 82ACB9E5E871351D8CFDBA8B9BC862B642819C00356B6A923870FB31B56CAAE5 + B23ABB2C20BF2082F26BB8B714B578D6F0307A0F6168CD2BAB87C856A7EDC2D9 + B55EEECBC82A3AAC8D7C5B7CED536CB8208D47E95EB9024E695E84FCBEB88D94 + 9528B4CD74B3CA57E7231CC515C4659251ADD80E25893C067C05700065DDEDBE + DD6EA9B7B16908ACD7272219B36544FC39F3E78D35D97E66774CCA5E6E0EC68F + 21A961427AD78E359220A2293719AE9A288FCB5008190CF9B540181FB2D13FF9 + D0EAC36786202EAEE532C8BEE50C498C1072A0CABFE18E7BEEB5BC9B57556A7D + 7F7B2DECDD9894BC60FB47520F1385550361C9B9EF7B66DCBDD912EE163A65B2 + B8A4A9A07A1A95AFA1C6B5B4325D4CD5F45617DAFF00B65A88269583FD23FEA0 + 565AE7139F7019F06FE38E95B13E494FC00EED65042F1CD6209866501E0D2C1E + 298002442385351AAD0F0C6DB3656BE605AF4DACFF00E5DBF00DD9B76DC20416 + F2DBBB4714652D108D059F59246B6229F363877EDD5329E4ECD1EAEF756BAFDA + 886E335C6E96EED732C51450316FA712333160429AD000280F138CE9BD6624D3 + 6FA56ABAD6ED2EC67CA42CB495CBB2D5638D6A7DBF1E43155D9662DBA7553CF6 + 642CEE13EB232B1232A9F6A3E51E5CDF864302A322FEC2784A17D061B9DE2DFB + 06D2CF3B4548C70AC701D1A634F957D895514E54C5A5073D9C8ADD9CC71B23AB + C6C7D8CAAA8E08FCC00AFDB8BAB11D42589C674200CEBE98E5342FBF961AC734 + 602EB51901D000460013EE4804CAF1966130A54E4A70AAC76A8A67DB58A991DC + 328398420B53A915C6BDCCFA109BBC205785DE349541201E9D71112506DB4777 + 785565B83DA5A51304407269ECB6FB44D28A8BA40CE435D4C70041ECDB7BCCCC + 2422385797518A101C496DB73B7D3C40B36465A7BB0810CADFC7B66BBB7EF6F6 + D208A6632C691921CE8CAA0A826AE7DB5E58E9D15D6D7DF9F833D9B7755AFEB7 + 1F26377CD9B6A82213DABC9148C4F72D64677D22B97BC85271AEBD3ADD67ED4F + E0D2FEC6CED136B2F991118622AD414047004E78E95AA9E2A8E377B666CC1661 + 2339A926BC470AFDD8CEDAAA82B76CA9ACE53908CFDD8869169845B595EBDCC0 + 429530D3B6FC34D093CFD4E31BA46B56C732ED090C7AF40D4FEF60A28BC73A63 + 328E81BA4448EE22D0380C0FC78FFAAB8E646A2093BD2445548FD36D555CFDAD + 91E3EA06181F4D692B595B99413A5DB8E555E35EBCF12B91BE0B06CD0BC46A34 + 92A4A83EB8A102DC6D8E9046AA0D14675E3CF218689637DAB68096E24A740C48 + CB031A1A2C49150FE203DA0600069DD9D73CC13EEC007D67B7FD4DE450A2336A + 6150295A7127A6430E4502ADEB72BA6DC24B5BB7580C474C49ED7D207CA63202 + 8A7F49C5D5A6B038EAF280771113ABA349A52404AA00C40195391652748A9634 + 15A629DA055A37C09E5DADFEA342839B67D00A654E071D7A7D88C5B839B6699C + A26F650C6725A11954F3C696B499AAC124B676CE807318E7B5D266CA85D6B118 + CEA26B21F9428AD3E38CAD692EB580AB58DAE64313305241D3239E0FF841A753 + 9626419B178068ACC866543511D74E4DFF003C61E4D00A18AE04F218610BAD29 + A5BDF9A9D438FC303433E8ACEEA79EB39153D797DF81206C6325BA12230C2A07 + B9CE1C08AE68632B41EE0052A39E1814C3298D0A6607155198AE0802B3216933 + 6F5CB2C012418716AE75CC939E0035BE1FE37F55B56E5E437F2B5B6DBB7C6CB1 + 846ED99E623FDBD441AA8A8A8E6683AE2E954F9E08BDDAE393984BBDF665B887 + 72B21716F348599C7B250782D1865ED1C294C66F5F958365B3E720DB7FD5EE92 + CC96B3C5226605BCEFA6720B56ACECB4734F5C5BBC724AACF032B2B2BF86E0C0 + E8CB712921548550753534EAA8AEAA0C8138A4D325A28695096D542A1B4B7407 + 9AF2197A61881A76662597E4047B72140295AE5CF0002B4EC5989CCF251C3EE1 + 8045667951F5834AFCC38570B919AFB1DEE7B862EDDF8A1CE8C238D55B97CD21 + 27EE182B45E57EA4BB075A5C2B5D2D6E649119823950958DC9A2F11EE15F9B86 + 587B2A9295C0AB67C17C7796FAA44635742470E5D798C2BD7AB2EAE51169A06A + 9D401F5E189191377181426A47003860022D7259288748E9800188766000A9AF + 1E784036F1ED91770BCED4EE63B6895A7B97500B08D3885FE63C061A426E02F7 + FF00269B71B2FF00D6F6F31EDD6B0256CA2622550C4D4195E9ED766E75A75C52 + 6B8074B25D8E793C61BBA9B9C220BF8AB1491D280953C704647DB102431A4555 + 8720714405C1BD5FDAC5DBEEF720FF00B12FBD7EE3C3ECC4BAA652B344937AB5 + 932689E1A1A858C8295E15A30C10C3B22335DA4B42935686A15D0104F5391A9C + 0A41C114914255AACDCF2FF8182184A0AB5D96496237338283FF008D1B8D3AD3 + 0C4378AE15D241313AC37CDE98724C14DBEE6B6979ADDEA1482A78D40CC540C2 + B6502E4B9EFDADE1495894797F535AB7B82E6B4A0FBF11B5F665D705716FA65D + 21E31293C5ABA5ABF6647EEC4650E46D1BC6D10700807911420E1D6D2104B557 + E38A024AE56B415AE001C307DB36492F4B9B892FD15161B270F2470337EAB4AA + 3DCA4659606B025C9F5EEE3E316BB32A58BC72A32E954419B659892B43F1AE2E + 17825DACDCB394F926E0935C17EF1330F6A393C053253D74F2C34025DAEF374B + ABA10449DE7A3108054FB454F0C0C0314DC4CF49A178645F991C11F75700406D + BEDF7327FB30B37F3532FBF8614840C6DFC767908371208D3F2266C7EDE030BB + 0E03A5B74B19E37887FE31A2B026BA4F0AFF00D58246696DADE19EDE311A879A + 5A88A3390A8E2CDE830107FFD9} + PictureName = 'UnknownMap' + end + end +end diff --git a/source/view/Frame.MapPreview.pas b/source/view/Frame.MapPreview.pas new file mode 100644 index 0000000..c890e4a --- /dev/null +++ b/source/view/Frame.MapPreview.pas @@ -0,0 +1,96 @@ +unit Frame.MapPreview; + +interface +uses + System.Classes, + Vcl.Controls, + Vcl.Dialogs, + Vcl.ExtCtrls, + Vcl.Forms, + Vcl.Imaging.jpeg, + + X2CLGraphicList; + + +type + TMapPreviewFrame = class(TFrame) + shpBorder: TShape; + imgMapPreview: TImage; + gcMapPreview: TX2GraphicContainer; + gcMapPreviewUnknownMap: TX2GraphicContainerItem; + public + constructor Create(AOwner: TComponent); override; + + procedure Clear; + procedure Load(const AMapName: string); + end; + + +implementation +uses + System.SysUtils, + Vcl.Graphics, + + Resources; + + +{$R *.dfm} + + +{ TMapPreviewFrame } +constructor TMapPreviewFrame.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + { Having the components not aligned at design-time makes it easier to drag the frame around } + shpBorder.Align := alClient; + imgMapPreview.Align := alClient; + + Clear; +end; + + +procedure TMapPreviewFrame.Clear; +begin + imgMapPreview.Picture.Assign(gcMapPreviewUnknownMap.Picture); +end; + + +procedure TMapPreviewFrame.Load(const AMapName: string); +var + preview: TPicture; + fileName: string; + previewItem: TX2GraphicContainerItem; + +begin + preview := nil; + + if Length(AMapName) > 0 then + begin + preview := gcMapPreview.PictureByName(AMapName); + if not Assigned(preview) then + begin + previewItem := TX2GraphicContainerItem.Create(Self); + previewItem.Container := gcMapPreview; + previewItem.PictureName := AMapName; + preview := previewItem.Picture; + + fileName := GetAssetPath(AssetMapPreviewPath + AMapName + AssetMapPreviewExtension); + if FileExists(fileName) then + begin + try + preview.LoadFromFile(fileName); + except + preview.Assign(nil); + end; + end; + end; + end; + + if Assigned(preview) and Assigned(preview.Graphic) then + imgMapPreview.Picture.Assign(preview) + else + Clear; +end; + +end.