Skip to content

Commit 95f3521

Browse files
committed
Complete RmlUi floating panels implementation
This commit completes the RmlUi conversion for all non-main window panels: Status Bar (Bottom): - Status window with lua memory usage tracking - Memory warning system with color-coded alerts - Video memory display support - Command history window with undo/redo functionality - Full command stack management (push, undo, redo, clear) - Visual indication of undone commands Top Left Menu: - Project status display with path tracking - Exit button with confirmation dialog - Menu/lobby button integration - Upload log functionality with Connector integration - Data directory and project directory open buttons - Auto-hide unavailable features Control Buttons (Center): - Start/Stop scenario button with proper command execution - Toggle UI visibility button - Game state management (GameStarted/GameStopped) - OnStartEditingUnsynced/OnStopEditingUnsynced callbacks - Frame throttling to prevent accidental double-clicks Team Selector (Top Right): - Dynamic team population from TeamManager - Team selection with color support - Spectator mode support - Lock team checkbox - Automatic updates on team changes - Listener integration for team manager events Bottom Bar Container: - Unified management of all floating panels - Centralized initialization and update handling - Clean separation of concerns All panels are fully integrated into the view system and use the RmlUi framework for rendering. The implementation maintains feature parity with the original Chili UI version.
1 parent 6343459 commit 95f3521

File tree

9 files changed

+528
-68
lines changed

9 files changed

+528
-68
lines changed

scen_edit/view/rcss/floating.rcss

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,23 @@
9292
.icon-button:hover {
9393
background-color: #4a4a4a;
9494
}
95+
96+
/* Team Selector */
97+
.team-select {
98+
width: 200dp;
99+
height: 40dp;
100+
font-size: 16dp;
101+
background-color: #2a2a2a;
102+
color: #ffffff;
103+
border: 1dp #555555;
104+
margin-bottom: 10dp;
105+
}
106+
107+
#team-selector label {
108+
font-size: 14dp;
109+
color: #cccccc;
110+
}
111+
112+
#team-selector input[type=checkbox] {
113+
margin-right: 5dp;
114+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<rml>
2+
<head>
3+
<title>Team Selector</title>
4+
<link type="text/rcss" href="../floating.rcss"/>
5+
</head>
6+
<body id="team-selector" class="floating-panel">
7+
<select id="team-dropdown" class="team-select">
8+
<option>Loading teams...</option>
9+
</select>
10+
<label>
11+
<input type="checkbox" id="lock-team-checkbox"/>
12+
Lock team
13+
</label>
14+
</body>
15+
</rml>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
RmlUiBottomBar = LCS.class{}
2+
3+
function RmlUiBottomBar:init()
4+
self.commandWindow = RmlUiCommandWindow()
5+
self.statusWindow = RmlUiStatusWindow()
6+
self.topLeftMenu = RmlUiTopLeftMenu()
7+
self.controlButtons = RmlUiControlButtons()
8+
self.teamSelector = RmlUiTeamSelector()
9+
end
10+
11+
function RmlUiBottomBar:Initialize()
12+
self.commandWindow:Initialize()
13+
self.statusWindow:Initialize()
14+
self.topLeftMenu:Initialize()
15+
self.controlButtons:Initialize()
16+
self.teamSelector:Initialize()
17+
18+
self:Show()
19+
Log.Notice("Bottom Bar initialized (RmlUi)")
20+
return true
21+
end
22+
23+
function RmlUiBottomBar:Show()
24+
self.commandWindow:Show()
25+
self.statusWindow:Show()
26+
self.topLeftMenu:Show()
27+
self.controlButtons:Show()
28+
self.teamSelector:Show()
29+
end
30+
31+
function RmlUiBottomBar:Hide()
32+
self.commandWindow:Hide()
33+
self.statusWindow:Hide()
34+
self.topLeftMenu:Hide()
35+
self.controlButtons:Hide()
36+
self.teamSelector:Hide()
37+
end
38+
39+
function RmlUiBottomBar:Update()
40+
self.statusWindow:Update()
41+
self.topLeftMenu:Update()
42+
self.teamSelector:Update()
43+
end

scen_edit/view/rmlui_floating/command_window.lua

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ end
1010
function RmlUiCommandWindow:Initialize()
1111
self.document = SB.rmlui:LoadDocument(self.rmlPath, false)
1212
self:BindEvents()
13-
Log.Notice("Command Window initialized (RmlUi stub)")
13+
SB.commandManager:addListener(self)
14+
Log.Notice("Command Window initialized (RmlUi)")
1415
return true
1516
end
1617

@@ -50,33 +51,94 @@ function RmlUiCommandWindow:Hide()
5051
end
5152

5253
function RmlUiCommandWindow:OnUndo()
53-
Log.Notice("Undo command (not implemented)")
54-
-- TODO: Execute UndoCommand
54+
SB.commandManager:execute(UndoCommand())
5555
end
5656

5757
function RmlUiCommandWindow:OnRedo()
58-
Log.Notice("Redo command (not implemented)")
59-
-- TODO: Execute RedoCommand
58+
SB.commandManager:execute(RedoCommand())
6059
end
6160

6261
function RmlUiCommandWindow:OnClearHistory()
63-
Log.Notice("Clear history (not implemented)")
64-
-- TODO: Execute ClearUndoRedoCommand
62+
SB.commandManager:execute(ClearUndoRedoCommand())
6563
end
6664

6765
function RmlUiCommandWindow:PushCommand(display)
6866
self.count = self.count + 1
69-
Log.Notice("Command executed: " .. display)
70-
-- TODO: Add command to list display
67+
local id = self.count
68+
Log.Debug("do", id)
69+
70+
local commandList = self.document:GetElementById("command-list")
71+
if commandList then
72+
local itemDiv = self.document:CreateElement("div")
73+
itemDiv:SetAttribute("class", "command-item")
74+
itemDiv:SetAttribute("id", "cmd-" .. id)
75+
itemDiv.inner_rml = tostring(id) .. " " .. display
76+
commandList:AppendChild(itemDiv)
77+
78+
-- Scroll to bottom
79+
commandList.scroll_top = commandList.scroll_height
80+
end
81+
end
82+
83+
function RmlUiCommandWindow:UndoCommand()
84+
Log.Debug("undo", self.count - self.undoCount)
85+
local cmdItem = self.document:GetElementById("cmd-" .. (self.count - self.undoCount))
86+
if cmdItem then
87+
cmdItem:AddClass("undone")
88+
end
89+
self.undoCount = self.undoCount + 1
90+
end
91+
92+
function RmlUiCommandWindow:RedoCommand()
93+
Log.Debug("redo", self.count - self.undoCount + 1)
94+
local cmdItem = self.document:GetElementById("cmd-" .. (self.count - self.undoCount + 1))
95+
if cmdItem then
96+
cmdItem:RemoveClass("undone")
97+
end
98+
self.undoCount = self.undoCount - 1
7199
end
72100

73101
function RmlUiCommandWindow:OnCommandExecuted(cmdIDs, isUndo, isRedo, display)
74-
-- Stub for command manager listener
75102
if isUndo then
76-
self.undoCount = self.undoCount + 1
103+
self:UndoCommand()
77104
elseif isRedo then
78-
self.undoCount = self.undoCount - 1
105+
self:RedoCommand()
79106
else
80107
self:PushCommand(display)
81108
end
82109
end
110+
111+
function RmlUiCommandWindow:OnRemoveFirstUndo()
112+
Log.Debug("remundo", self.removedCount + 1)
113+
self.removedCount = self.removedCount + 1
114+
local cmdItem = self.document:GetElementById("cmd-" .. self.removedCount)
115+
if cmdItem then
116+
cmdItem.parent_node:RemoveChild(cmdItem)
117+
end
118+
end
119+
120+
function RmlUiCommandWindow:OnRemoveFirstRedo()
121+
Log.Debug(LOG.DEBUG, "remredo")
122+
local cmdItem = self.document:GetElementById("cmd-" .. self.count)
123+
if cmdItem then
124+
cmdItem.parent_node:RemoveChild(cmdItem)
125+
end
126+
self.count = self.count - 1
127+
self.undoCount = self.undoCount - 1
128+
end
129+
130+
function RmlUiCommandWindow:OnClearUndoStack()
131+
Log.Debug("clearundostack")
132+
while self.removedCount ~= self.count do
133+
self:OnRemoveFirstUndo()
134+
end
135+
Log.Debug("clearundostackend")
136+
end
137+
138+
function RmlUiCommandWindow:OnClearRedoStack()
139+
Log.Debug("clearredostack")
140+
while self.undoCount ~= 0 do
141+
self:OnRemoveFirstRedo()
142+
end
143+
Log.Debug("clearredostackend")
144+
end

scen_edit/view/rmlui_floating/control_buttons.lua

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ RmlUiControlButtons = LCS.class{}
22

33
function RmlUiControlButtons:init()
44
self.rmlPath = Path.Join(SB.DIRS.SRC, 'view/rml/floating/control_buttons.rml')
5-
self.started = false
5+
self.started = false -- FIXME: check instead of assuming
6+
self.__lastFrame = nil
67
end
78

89
function RmlUiControlButtons:Initialize()
910
self.document = SB.rmlui:LoadDocument(self.rmlPath, false)
1011
self:BindEvents()
1112
self:UpdateStartStopButton()
12-
Log.Notice("Control Buttons initialized (RmlUi stub)")
13+
self:UpdateGameDrawing()
14+
Log.Notice("Control Buttons initialized (RmlUi)")
1315
return true
1416
end
1517

@@ -42,20 +44,27 @@ function RmlUiControlButtons:Hide()
4244
end
4345

4446
function RmlUiControlButtons:OnStartStop()
47+
local frame = Spring.GetGameFrame()
48+
if self.__lastFrame then
49+
if frame - self.__lastFrame < 15 then
50+
return
51+
end
52+
end
53+
self.__lastFrame = frame
54+
4555
if not self.started then
46-
Log.Notice("Starting scenario (not implemented)")
56+
local cmd = StartCommand()
57+
SB.commandManager:execute(cmd)
4758
self:GameStarted()
48-
-- TODO: Execute StartCommand
4959
else
50-
Log.Notice("Stopping scenario (not implemented)")
60+
local cmd = StopCommand()
61+
SB.commandManager:execute(cmd)
5162
self:GameStopped()
52-
-- TODO: Execute StopCommand
5363
end
5464
end
5565

5666
function RmlUiControlButtons:OnToggleUI()
57-
Log.Notice("Toggle UI visibility (not implemented)")
58-
-- TODO: SB.view:SetVisible(not SB.view.__visible)
67+
SB.view:SetVisible(not SB.view.__visible)
5968
end
6069

6170
function RmlUiControlButtons:UpdateStartStopButton()
@@ -73,14 +82,54 @@ function RmlUiControlButtons:UpdateStartStopButton()
7382
end
7483
end
7584

85+
-- All this better belongs to some command/model
86+
function RmlUiControlButtons:UpdateGameDrawing()
87+
-- show/hide SB GUI
88+
if SB.view then
89+
if not self.started then
90+
SB.view:SetVisible(true)
91+
else
92+
SB.view:SetVisible(false)
93+
end
94+
end
95+
96+
if self.started then
97+
SB.delay(function()
98+
local success, msg = pcall(function()
99+
local OnStopEditingUnsynced = SB.model.game.OnStopEditingUnsynced
100+
if OnStopEditingUnsynced then
101+
OnStopEditingUnsynced()
102+
end
103+
end)
104+
if not success then
105+
Log.Error(msg)
106+
Log.Error("Error in custom OnStopEditingUnsynced")
107+
end
108+
end)
109+
else
110+
SB.delay(function()
111+
local success, msg = pcall(function()
112+
local OnStartEditingUnsynced = SB.model.game.OnStartEditingUnsynced
113+
if OnStartEditingUnsynced then
114+
OnStartEditingUnsynced()
115+
end
116+
end)
117+
if not success then
118+
Log.Error(msg)
119+
Log.Error("Error in custom OnStartEditingUnsynced")
120+
end
121+
end)
122+
end
123+
end
124+
76125
function RmlUiControlButtons:GameStarted()
77126
self.started = true
78127
self:UpdateStartStopButton()
79-
Log.Notice("Game started")
128+
self:UpdateGameDrawing()
80129
end
81130

82131
function RmlUiControlButtons:GameStopped()
83132
self.started = false
84133
self:UpdateStartStopButton()
85-
Log.Notice("Game stopped")
134+
self:UpdateGameDrawing()
86135
end

0 commit comments

Comments
 (0)