diff --git a/LuaMenu/widgets/api_chili.lua b/LuaMenu/widgets/api_chili.lua index 6e971a217..314095ee8 100644 --- a/LuaMenu/widgets/api_chili.lua +++ b/LuaMenu/widgets/api_chili.lua @@ -106,7 +106,7 @@ function widget:DrawLoadScreen() if WG.Chobby and WG.Chobby.Configuration and WG.Chobby.Configuration.hideInterface then return end - + gl.Color(1,1,1,1) if (not screen0:IsEmpty()) then gl.PushMatrix() @@ -125,7 +125,7 @@ function widget:TweakDrawScreen() if WG.Chobby and WG.Chobby.Configuration and WG.Chobby.Configuration.hideInterface then return end - + gl.Color(1,1,1,1) if (not screen0:IsEmpty()) then gl.PushMatrix() @@ -143,7 +143,7 @@ function widget:DrawGenesis() if WG.Chobby and WG.Chobby.Configuration and WG.Chobby.Configuration.hideInterface then return end - + gl.Color(1,1,1,1) tf.Update() th.Update() @@ -220,6 +220,12 @@ function widget:TextInput(utf8, ...) return screen0:TextInput(utf8, ...) end +function widget:TextEditing(utf8, start, length, ...) + if Spring.IsGUIHidden() then return false end + + return screen0:TextEditing(utf8, start, length, ...) +end + local oldSizeX, oldSizeY function widget:ViewResize(vsx, vsy) diff --git a/LuaMenu/widgets/chobby/components/chat_windows.lua b/LuaMenu/widgets/chobby/components/chat_windows.lua index 9d3d46656..93a635953 100644 --- a/LuaMenu/widgets/chobby/components/chat_windows.lua +++ b/LuaMenu/widgets/chobby/components/chat_windows.lua @@ -748,8 +748,14 @@ function ChatWindows:GetChannelConsole(chanName) self.userListPanels[chanName] = userListPanel local caption = "#" .. chanName - local myFont = Font:New(Configuration:GetFont(1)) + local tooltip = nil + local origCaption = caption + local fontSize = 1 + local myFont = Font:New(Configuration:GetFont(fontSize)) caption = StringUtilities.GetTruncatedStringWithDotDot(caption, myFont, 70) + if origCaption ~= caption then + tooltip = origCaption + end local closeChannelButton = Button:New { width = 24, height = 24, y = 5, right = Configuration.userListWidth + 18, @@ -770,7 +776,8 @@ function ChatWindows:GetChannelConsole(chanName) { name = chanName, caption = caption, - font = Configuration:GetFont(1), + font = Configuration:GetFont(fontSize), + tooltip = tooltip, children = { Control:New { x = 0, y = 0, right = Configuration.userListWidth, bottom = 0, @@ -825,8 +832,14 @@ function ChatWindows:GetPrivateChatConsole(userName, switchTo) self.privateChatConsoles[chanName] = privateChatConsole local caption = "@" .. userName - local myFont = Font:New(Configuration:GetFont(1)) + local tooltip = nil + local origCaption = caption + local fontSize = 1 + local myFont = Font:New(Configuration:GetFont(fontSize)) caption = StringUtilities.GetTruncatedStringWithDotDot(caption, myFont, 70) + if origCaption ~= caption then + tooltip = origCaption + end local closeChannelButton = Button:New { width = 24, height = 24, y = 5, right = 18, @@ -845,7 +858,8 @@ function ChatWindows:GetPrivateChatConsole(userName, switchTo) { name = chanName, caption = caption, - font = Configuration:GetFont(1), + tooltip = tooltip, + font = Configuration:GetFont(fontSize), children = { privateChatConsole.panel, closeChannelButton diff --git a/LuaMenu/widgets/gui_modoptions_panel.lua b/LuaMenu/widgets/gui_modoptions_panel.lua index 4c2ffacf9..9f64087ea 100644 --- a/LuaMenu/widgets/gui_modoptions_panel.lua +++ b/LuaMenu/widgets/gui_modoptions_panel.lua @@ -41,7 +41,7 @@ local function UpdateControlValue(key, value) end end - + local function ResetToDefault() if not (modoptionDefaults and modoptionChanges) then return @@ -67,10 +67,10 @@ local function ProcessListOption(data, index) font = WG.Chobby.Configuration:GetFont(2), tooltip = data.desc, } - + local defaultItem = 1 - local defaultKey = modoptionChanges[data.key] or data.def - + local defaultKey = modoptionChanges[data.key] or data.def + local items = {} local itemNameToKey = {} local itemKeyToName = {} @@ -78,12 +78,12 @@ local function ProcessListOption(data, index) items[i] = itemData.name itemNameToKey[itemData.name] = itemData.key itemKeyToName[itemData.key] = itemData.name - + if itemData.key == defaultKey then defaultItem = i end end - + local list = ComboBox:New { x = 340, y = 1, @@ -102,7 +102,7 @@ local function ProcessListOption(data, index) itemKeyToName = itemKeyToName -- Not a chili key } modoptionControlNames[data.key] = list - + return Control:New { x = 0, y = index*32, @@ -125,7 +125,7 @@ local function ProcessBoolOption(data, index) elseif modoptionChanges[data.key] == "1" then checked = true end - + local checkBox = Checkbox:New { x = 5, y = index*32, @@ -137,7 +137,7 @@ local function ProcessBoolOption(data, index) checked = checked, font = WG.Chobby.Configuration:GetFont(2), tooltip = data.desc, - + OnChange = { function (obj, newState) modoptionLocalChanges[data.key] = tostring((newState and 1) or 0) @@ -145,12 +145,12 @@ local function ProcessBoolOption(data, index) }, } modoptionControlNames[data.key] = checkBox - + return checkBox end local function ProcessNumberOption(data, index) - + local label = Label:New { x = 5, y = 0, @@ -162,9 +162,9 @@ local function ProcessNumberOption(data, index) font = WG.Chobby.Configuration:GetFont(2), tooltip = data.desc, } - + local oldText = modoptionChanges[data.key] or modoptionDefaults[data.key] - + local numberBox = EditBox:New { x = 340, y = 1, @@ -177,14 +177,14 @@ local function ProcessNumberOption(data, index) if obj.focused then return end - + local newValue = tonumber(obj.text) - + if not newValue then obj:SetText(oldText) return end - + local places = 0 if data.step < 0.01 then places = 3 @@ -193,26 +193,26 @@ local function ProcessNumberOption(data, index) elseif data.step < 1 then places = 3 end - + -- Bound the number newValue = math.min(data.max, math.max(data.min, newValue)) -- Round to step size newValue = math.floor(newValue/data.step)*data.step + 0.01*data.step - + -- Remove excess accuracy oldText = string.format("%." .. places .. "f", newValue) -- Remove trailing zeros while oldText:find("%.") and (oldText:find("0", oldText:len()) or oldText:find("%.", oldText:len())) do oldText = oldText:sub(0, oldText:len() - 1) end - + modoptionLocalChanges[data.key] = oldText obj:SetText(oldText) end } } modoptionControlNames[data.key] = numberBox - + return Control:New { x = 0, y = index*32, @@ -227,7 +227,7 @@ local function ProcessNumberOption(data, index) end local function ProcessStringOption(data, index) - + local label = Label:New { x = 5, y = 0, @@ -239,9 +239,9 @@ local function ProcessStringOption(data, index) font = WG.Chobby.Configuration:GetFont(2), tooltip = data.desc, } - + local oldText = modoptionChanges[data.key] or modoptionDefaults[data.key] - + local textBox = EditBox:New { x = 340, y = 1, @@ -259,7 +259,7 @@ local function ProcessStringOption(data, index) } } modoptionControlNames[data.key] = textBox - + return Control:New { x = 0, y = index*32, @@ -278,7 +278,7 @@ local function PopulateTab(options) -- bool = tickbox -- number = sliderbar (with label) -- string = editBox - + local contentsPanel = ScrollPanel:New { x = 6, right = 5, @@ -286,7 +286,7 @@ local function PopulateTab(options) bottom = 8, horizontalScrollbar = false, } - + for i = 1, #options do local data = options[i] if data.type == "list" then @@ -317,17 +317,28 @@ local function CreateModoptionWindow() draggable = false, classname = "main_window", } - + modoptionLocalChanges = Spring.Utilities.CopyTable(modoptionChanges) modoptionControlNames = {} local tabs = {} + local tabWidth = 120 + for key, data in pairs(modoptionStructure.sections) do + local caption = modoptionStructure.sectionTitles[data.title] or data.title + local fontSize = 2 + local tooltip = nil + local origCaption = caption + caption = StringUtilities.GetTruncatedStringWithDotDot(caption, Font:New(WG.Chobby.Configuration:GetFont(fontSize)), tabWidth) + if origCaption ~= caption then + tooltip = origCaption + end tabs[#tabs + 1] = { name = key, - caption = modoptionStructure.sectionTitles[data.title] or data.title, - font = WG.Chobby.Configuration:GetFont(2), + caption = caption, + tooltip = tooltip, + font = WG.Chobby.Configuration:GetFont(fontSize), children = PopulateTab(data.options) } end @@ -338,7 +349,7 @@ local function CreateModoptionWindow() y = 49, bottom = 75, padding = {0, 0, 0, 0}, - minTabWidth = 120, + minTabWidth = tabWidth, tabs = tabs, parent = modoptionsSelectionWindow, OnTabChange = { @@ -371,7 +382,7 @@ local function CreateModoptionWindow() end local buttonAccept - + local function AcceptFunc() screen0:FocusControl(buttonAccept) -- Defocus the text entry battleLobby:SetModOptions(modoptionLocalChanges) @@ -393,7 +404,7 @@ local function CreateModoptionWindow() end }, } - + buttonAccept = Button:New { right = 150, width = 135, @@ -459,7 +470,7 @@ local function InitializeModoptionsDisplay() text = text .. "\255\120\120\120" .. tostring(key) .. " = \255\255\255\255" .. tostring(value) .. "\n" empty = false end - + UpdateControlValue(key, value) end for key, value in pairs(modoptionChanges) do @@ -468,7 +479,7 @@ local function InitializeModoptionsDisplay() end end modoptionChanges = modoptions - + lblText:SetText(text) if mainScrollPanel.parent then diff --git a/libs/chiliui/luamenu/chili/api_chili.lua b/libs/chiliui/luamenu/chili/api_chili.lua index f2d124f23..97c6f9b48 100644 --- a/libs/chiliui/luamenu/chili/api_chili.lua +++ b/libs/chiliui/luamenu/chili/api_chili.lua @@ -193,6 +193,12 @@ function widget:TextInput(utf8, ...) return screen0:TextInput(utf8, ...) end +function widget:TextEditing(utf8, start, length, ...) + if Spring.IsGUIHidden() then return false end + + return screen0:TextEditing(utf8, start, length, ...) +end + function widget:ViewResize(vsx, vsy) screen0:Resize(vsx, vsy) diff --git a/libs/chiliui/luamenu/chili/chili/controls/detachabletabpanel.lua b/libs/chiliui/luamenu/chili/chili/controls/detachabletabpanel.lua index d9880e636..073306067 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/detachabletabpanel.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/detachabletabpanel.lua @@ -27,7 +27,7 @@ local inherited = this.inherited function DetachableTabPanel:New(obj) obj = inherited.New(self,obj) - + obj.tabBar = TabBar:New { tabs = obj.tabs, x = 0, @@ -37,7 +37,7 @@ function DetachableTabPanel:New(obj) minItemWidth = obj.minTabWidth, padding = {0, 0, 0, 0}, } - + obj.currentTab = Control:New { x = 0, y = 0, @@ -48,7 +48,7 @@ function DetachableTabPanel:New(obj) obj:AddChild(obj.currentTab) obj.tabIndexMapping = {} for i=1, #obj.tabs do - local tabName = obj.tabs[i].name + local tabName = obj.tabs[i].name local tabFrame = Control:New { padding = {0, 0, 0, 0}, x = 0, @@ -72,9 +72,14 @@ end function DetachableTabPanel:AddTab(tab, neverSwitchTab) local tabbar = self.tabBar local switchTab = (#tabbar.children == 0) or (not neverSwitchTab) - tabbar:AddChild( - TabBarItem:New{name = tab.name, caption = tab.caption or tab.name, font = tab.font, defaultWidth = tabbar.minItemWidth, defaultHeight = tabbar.minItemHeight} --FIXME: implement an "Add Tab in TabBar too" - ) + tabbar:AddChild(TabBarItem:New { + name = tab.name, + caption = tab.caption or tab.name, + tooltip = tab.tooltip, + font = tab.font, + defaultWidth = tabbar.minItemWidth, + defaultHeight = tabbar.minItemHeight + }) --FIXME: implement an "Add Tab in TabBar too" local tabFrame = Control:New { padding = {0, 0, 0, 0}, x = 0, @@ -125,4 +130,4 @@ function DetachableTabPanel:ChangeTab(tabname) self:CallListeners(self.OnTabChange, tabname) end ---//============================================================================= \ No newline at end of file +--//============================================================================= diff --git a/libs/chiliui/luamenu/chili/chili/controls/editbox.lua b/libs/chiliui/luamenu/chili/chili/controls/editbox.lua index eac8a4de5..14a4c3509 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/editbox.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/editbox.lua @@ -425,6 +425,21 @@ function EditBox:Update(...) end end +function EditBox:FocusUpdate() + if not Spring.SDLStartTextInput then + return + end + + if not self.state.focused then + self.textEditing = "" + Spring.SDLStopTextInput() + else + Spring.SDLStartTextInput() + local x, y = self:CorrectlyImplementedLocalToScreen(self.x, self.y) + Spring.SDLSetTextInputRect(x, y, 30, 1000) + end +end + function EditBox:_GetCursorByMousePos(x, y) local retVal = { offset = self.offset, @@ -814,6 +829,7 @@ function EditBox:TextInput(utf8char, ...) if not self.editable then return false end + self.textEditing = "" local unicode = utf8char if unicode then @@ -836,4 +852,13 @@ function EditBox:TextInput(utf8char, ...) return self end +function EditBox:TextEditing(utf8, start, length) + if not self.editable then + return false + end + + self.textEditing = utf8 + return true +end + --//============================================================================= diff --git a/libs/chiliui/luamenu/chili/chili/controls/object.lua b/libs/chiliui/luamenu/chili/chili/controls/object.lua index 79ef2349f..ce6f11837 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/object.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/object.lua @@ -49,6 +49,7 @@ Object = { OnMouseOut = {}, OnKeyPress = {}, OnTextInput = {}, + OnTextEditing = {}, OnFocusUpdate = {}, OnHide = {}, OnShow = {}, @@ -57,7 +58,7 @@ Object = { OnParentPost = {}, -- Called after parent is set disableChildrenHitTest = false, --// if set childrens are not clickable/draggable etc - their mouse events are not processed -} +} do local __lowerkeys = {} @@ -75,7 +76,7 @@ local inherited = this.inherited --//============================================================================= --// used to generate unique objects names -local cic = {} +local cic = {} local function GetUniqueId(classname) local ci = cic[classname] or 0 cic[classname] = ci + 1 @@ -172,7 +173,7 @@ function Object:Dispose(_internal) end end end - + self:CallListeners(self.OnDispose) self.disposed = true @@ -247,18 +248,18 @@ function Object:SetParent(obj) self:CallListeners(self.OnOrphan, self) return end - + self:CallListeners(self.OnParent, self) - + -- Children always appear to visible when they recieve new parents because they -- are added to the visible child list. self.visible = true self.hidden = false - + self.parent = MakeWeakLink(obj, self.parent) self:Invalidate() - + self:CallListeners(self.OnParentPost, self) end @@ -359,7 +360,7 @@ function Object:ClearChildren() local old = self.preserveChildrenOrder self.preserveChildrenOrder = false - --// remove all children + --// remove all children for c in pairs(self.children_hidden) do self:ShowChild(c) end @@ -505,7 +506,7 @@ function Object:SetChildLayer(child,layer) if layer < 0 then layer = layer + #children + 1 end - + layer = math.min(layer, #children) --// it isn't at the same pos anymore, search it! @@ -602,14 +603,14 @@ function Object:GetObjectByName(name) end ---// Climbs the family tree and returns the first parent that satisfies a +--// Climbs the family tree and returns the first parent that satisfies a --// predicate function or inherites the given class. --// Returns nil if not found. function Object:FindParent(predicate) if not self.parent then return -- not parent with such class name found, return nil elseif (type(predicate) == "string" and (self.parent):InheritsFrom(predicate)) or - (type(predicate) == "function" and predicate(self.parent)) then + (type(predicate) == "function" and predicate(self.parent)) then return self.parent else return self.parent:FindParent(predicate) @@ -809,7 +810,7 @@ function Object:LocalToClient(x,y) return x,y end --- LocalToScreen does not do what it says it does because +-- LocalToScreen does not do what it says it does because -- self:LocalToParent(x,y) = 2*self.x, 2*self.y -- However, too much chili depends on the current LocalToScreen -- so this working version exists for widgets. @@ -883,7 +884,7 @@ end function Object:HitTest(x,y) - if not self.disableChildrenHitTest then + if not self.disableChildrenHitTest then local children = self.children for i=1,#children do local c = children[i] @@ -897,7 +898,7 @@ function Object:HitTest(x,y) end end end - end + end return false end @@ -994,6 +995,15 @@ function Object:TextInput(...) end +function Object:TextEditing(...) + if (self:CallListeners(self.OnTextEditing, ...)) then + return self + end + + return false +end + + function Object:FocusUpdate(...) if (self:CallListeners(self.OnFocusUpdate, ...)) then return self @@ -1003,4 +1013,3 @@ function Object:FocusUpdate(...) end --//============================================================================= - diff --git a/libs/chiliui/luamenu/chili/chili/controls/screen.lua b/libs/chiliui/luamenu/chili/chili/controls/screen.lua index aec06e57f..a030c207d 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/screen.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/screen.lua @@ -164,7 +164,7 @@ end function Screen:IsAbove(x,y,...) if select(6, Spring.GetMouseState()) then - -- Do not register hits for offscreen mouse. + -- Do not register hits for offscreen mouse. -- See https://springrts.com/mantis/view.php?id=5671 for the good solution. return end @@ -326,4 +326,11 @@ function Screen:TextInput(...) end +function Screen:TextEditing(...) + local focusedControl = UnlinkSafe(self.focusedControl) + if focusedControl then + return (not not focusedControl:TextEditing(...)) + end + return (not not inherited:TextEditing(...)) +end --//============================================================================= diff --git a/libs/chiliui/luamenu/chili/chili/controls/tabbar.lua b/libs/chiliui/luamenu/chili/chili/controls/tabbar.lua index 89b2ade7e..c50f4e49d 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/tabbar.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/tabbar.lua @@ -26,9 +26,10 @@ function TabBar:New(obj) if (obj.tabs) then for i=1,#obj.tabs do obj:AddChild( - TabBarItem:New{ + TabBarItem:New { name = obj.tabs[i].name, caption = obj.tabs[i].caption or obj.tabs[i].name, + tooltip = obj.tabs[i].tooltip, font = obj.tabs[i].font, defaultWidth = obj.minItemWidth, defaultHeight = obj.minItemHeight, diff --git a/libs/chiliui/luamenu/chili/chili/controls/tabpanel.lua b/libs/chiliui/luamenu/chili/chili/controls/tabpanel.lua index 55ee91b8b..e4ee732cf 100644 --- a/libs/chiliui/luamenu/chili/chili/controls/tabpanel.lua +++ b/libs/chiliui/luamenu/chili/chili/controls/tabpanel.lua @@ -27,7 +27,7 @@ local inherited = this.inherited function TabPanel:New(obj) obj = inherited.New(self,obj) - + obj:AddChild( TabBar:New { tabs = obj.tabs, @@ -37,7 +37,7 @@ function TabPanel:New(obj) height = obj.barHeight, } ) - + obj.currentTab = Control:New { x = 0, y = obj.barHeight, @@ -48,7 +48,7 @@ function TabPanel:New(obj) obj:AddChild(obj.currentTab) obj.tabIndexMapping = {} for i=1, #obj.tabs do - local tabName = obj.tabs[i].name + local tabName = obj.tabs[i].name local tabFrame = Control:New { padding = {0, 0, 0, 0}, x = 0, @@ -72,9 +72,13 @@ end function TabPanel:AddTab(tab, neverSwitchTab) local tabbar = self.children[1] local switchToTab = (#tabbar.children == 0) and not neverSwitchTab - tabbar:AddChild( - TabBarItem:New{name = tab.name, caption = tab.caption or tab.name, defaultWidth = tabbar.minItemWidth, defaultHeight = tabbar.minItemHeight} --FIXME: implement an "Add Tab in TabBar too" - ) + tabbar:AddChild(TabBarItem:New { + name = tab.name, + tooltip = tab.tooltip, + caption = tab.caption or tab.name, + defaultWidth = tabbar.minItemWidth, + defaultHeight = tabbar.minItemHeight + }) --FIXME: implement an "Add Tab in TabBar too" local tabFrame = Control:New { padding = {0, 0, 0, 0}, x = 0, diff --git a/libs/chiliui/luamenu/chili/chili/headers/skinutils.lua b/libs/chiliui/luamenu/chili/chili/headers/skinutils.lua index 5a272fc09..bec25e6d1 100644 --- a/libs/chiliui/luamenu/chili/chili/headers/skinutils.lua +++ b/libs/chiliui/luamenu/chili/chili/headers/skinutils.lua @@ -590,6 +590,9 @@ function DrawEditBox(obj) gl.Texture(0,false) local text = obj.text + if text and obj.textEditing then + text = text .. obj.textEditing + end local font = obj.font local displayHint = false @@ -604,8 +607,12 @@ function DrawEditBox(obj) text = string.rep("*", #text) end - if (obj.offset > obj.cursor) and not obj.multiline then - obj.offset = obj.cursor + local cursor = obj.cursor + if obj.textEditing then + cursor = cursor + #obj.textEditing + end + if (obj.offset > cursor) and not obj.multiline then + obj.offset = cursor end local clientX,clientY,clientWidth,clientHeight = unpack4(obj.clientArea) @@ -613,9 +620,9 @@ function DrawEditBox(obj) if not obj.multiline then --// make cursor pos always visible (when text is longer than editbox!) repeat - local txt = text:sub(obj.offset, obj.cursor) + local txt = text:sub(obj.offset, cursor) local wt = font:GetTextWidth(txt) - if wt <= clientWidth or obj.offset >= obj.cursor then + if wt <= clientWidth or obj.offset >= cursor then break end obj.offset = obj.offset + 1 @@ -674,7 +681,7 @@ function DrawEditBox(obj) end if obj.state.focused and obj.editable then - local cursorTxt = text:sub(obj.offset, obj.cursor - 1) + local cursorTxt = text:sub(obj.offset, cursor - 1) local cursorX = font:GetTextWidth(cursorTxt) local dt = Spring.DiffTimers(Spring.GetTimer(), obj._interactedTime) @@ -1360,7 +1367,7 @@ function NCHitTestWithPadding(obj,mx,my) elseif (draggable) then return obj end - + if obj.noClickThrough then return obj end