├── .gitignore ├── LICENSE ├── README ├── luaui └── chili │ ├── api_chili.lua │ ├── chili │ ├── README │ ├── controls │ │ ├── README │ │ ├── button.lua │ │ ├── checkbox.lua │ │ ├── colorbars.lua │ │ ├── combobox.lua │ │ ├── control.lua │ │ ├── editbox.lua │ │ ├── font.lua │ │ ├── grid.lua │ │ ├── image.lua │ │ ├── imagelistview.lua │ │ ├── label.lua │ │ ├── layoutpanel.lua │ │ ├── line.lua │ │ ├── multiprogressbar.lua │ │ ├── object.lua │ │ ├── panel.lua │ │ ├── progressbar.lua │ │ ├── scale.lua │ │ ├── screen.lua │ │ ├── scrollpanel.lua │ │ ├── stackpanel.lua │ │ ├── tabbar.lua │ │ ├── tabbaritem.lua │ │ ├── tabpanel.lua │ │ ├── textbox.lua │ │ ├── trackbar.lua │ │ ├── treeview.lua │ │ ├── treeviewnode.lua │ │ └── window.lua │ ├── core.lua │ ├── handlers │ │ ├── backwardcompability.lua │ │ ├── debughandler.lua │ │ ├── fonthandler.lua │ │ ├── skinhandler.lua │ │ ├── taskhandler.lua │ │ ├── texturehandler.lua │ │ └── themehandler.lua │ ├── headers │ │ ├── autolocalizer.lua │ │ ├── backwardcompability.lua │ │ ├── links.lua │ │ ├── skinutils.lua │ │ ├── strict.lua │ │ ├── unicode.lua │ │ └── util.lua │ ├── skins │ │ ├── DarkGlass │ │ │ ├── combobox_wnd.png │ │ │ ├── glass.psp │ │ │ ├── glass_.png │ │ │ └── skin.lua │ │ ├── Glass │ │ │ ├── checkbox.png │ │ │ ├── checkbox.psp │ │ │ ├── checkbox_.png │ │ │ ├── checkbox_arrow.png │ │ │ ├── combobox_ctrl_arrow.png │ │ │ ├── combobox_wnd.png │ │ │ ├── glass.png │ │ │ ├── glass2.png │ │ │ ├── glass2.psp │ │ │ ├── glassBK.png │ │ │ ├── glassButton.psp │ │ │ ├── glassFG.png │ │ │ ├── glass_line.png │ │ │ ├── glass_line_vert.png │ │ │ ├── hscrollbar.png │ │ │ ├── itemlistview_item_fg.png │ │ │ ├── node_selected.png │ │ │ ├── panel.png │ │ │ ├── panel.psp │ │ │ ├── panel_.png │ │ │ ├── porgressbar_empty.png │ │ │ ├── progressbar_empty.png │ │ │ ├── progressbar_full.png │ │ │ ├── scrollbar.png │ │ │ ├── scrollbar_knob.png │ │ │ ├── scrollbar_knob.psp │ │ │ ├── skin.lua │ │ │ ├── trackbar.png │ │ │ ├── trackbar_step.png │ │ │ ├── trackbar_thumb.png │ │ │ ├── treeview_node.psp │ │ │ ├── treeview_node2.psp │ │ │ ├── treeview_node_collapsed.png │ │ │ └── treeview_node_expanded.png │ │ ├── Robocracy │ │ │ ├── combobox_ctrl.png │ │ │ ├── combobox_ctrl_arrow.png │ │ │ ├── combobox_ctrl_fg.png │ │ │ ├── combobox_wnd.png │ │ │ ├── empty.png │ │ │ ├── fonts │ │ │ │ ├── README │ │ │ │ ├── README.gentoo │ │ │ │ ├── README.gentoo.tweaks │ │ │ │ └── n019003l.pfb │ │ │ ├── glassBk.png │ │ │ ├── glassFG.png │ │ │ ├── node_selected.png │ │ │ ├── node_selected.psp │ │ │ ├── node_selected_bw.png │ │ │ ├── panel2.png │ │ │ ├── panel2.psp │ │ │ ├── panel2_bg.png │ │ │ ├── panel2_border.png │ │ │ ├── skin.lua │ │ │ ├── tech_button.png │ │ │ ├── tech_button.psp │ │ │ ├── tech_button_bk.png │ │ │ ├── tech_button_fg.png │ │ │ ├── tech_buttonbk.png │ │ │ ├── tech_checkbox.psp │ │ │ ├── tech_checkbox_checked.png │ │ │ ├── tech_checkbox_unchecked.png │ │ │ ├── tech_dragwindow.png │ │ │ ├── tech_dragwindow.psp │ │ │ ├── tech_line.png │ │ │ ├── tech_line_vert.png │ │ │ ├── tech_progressbar.psp │ │ │ ├── tech_progressbar_empty.png │ │ │ ├── tech_progressbar_full.png │ │ │ ├── tech_scrollbar.png │ │ │ ├── tech_scrollbar.psp │ │ │ ├── tech_scrollbar_knob.png │ │ │ ├── tech_scrollbar_knob.psp │ │ │ ├── tech_tabbaritem.png │ │ │ ├── tech_tabbaritem_bk.png │ │ │ ├── tech_tabbaritem_fg.png │ │ │ ├── tech_window.png │ │ │ ├── tech_window.psp │ │ │ ├── trackbar.png │ │ │ ├── trackbar_step.png │ │ │ ├── trackbar_thumb.png │ │ │ ├── treeview_node_collapsed.png │ │ │ ├── treeview_node_expanded.png │ │ │ ├── treeview_node_expanded_bw.png │ │ │ ├── window_tooltip.png │ │ │ └── window_tooltip.psp │ │ └── default │ │ │ ├── Sav33A.tmp │ │ │ ├── Sav38D.tmp │ │ │ ├── empty.png │ │ │ ├── folder.png │ │ │ ├── folder_up.png │ │ │ ├── placeholder.png │ │ │ ├── skin.lua │ │ │ ├── treeview_node_collapsed.png │ │ │ ├── treeview_node_expanded.png │ │ │ ├── tweak_overlay.png │ │ │ └── tweak_overlay_resizable.png │ ├── themes │ │ └── theme.lua │ └── todo.txt │ ├── dbg_chili_inspector.lua │ ├── dbg_chili_profiler.lua │ ├── generate_docs.sh │ ├── gui_chili_docking.lua │ └── gui_chiliguidemo.lua └── modinfo.lua /.gitignore: -------------------------------------------------------------------------------- 1 | docs 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Chili GUI 2 | 3 | A lua written GUI for Spring. 4 | -------------------------------------------------------------------------------- /luaui/chili/api_chili.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -------------------------------------------------------------------------------- 3 | 4 | function widget:GetInfo() 5 | return { 6 | name = "Chili Framework", 7 | desc = "Hot GUI Framework", 8 | author = "jK", 9 | date = "WIP", 10 | license = "GPLv2", 11 | version = "2.1", 12 | layer = -1000, 13 | enabled = true, -- loaded by default? 14 | handler = true, 15 | api = true, 16 | hidden = true, 17 | } 18 | end 19 | 20 | 21 | -------------------------------------------------------------------------------- 22 | -------------------------------------------------------------------------------- 23 | 24 | local Chili 25 | local screen0 26 | local th 27 | local tk 28 | local tf 29 | 30 | -------------------------------------------------------------------------------- 31 | -------------------------------------------------------------------------------- 32 | -- Chili's location 33 | 34 | local function GetDirectory(filepath) 35 | return filepath and filepath:gsub("(.*/)(.*)", "%1") 36 | end 37 | 38 | assert(debug) 39 | local source = debug and debug.getinfo(1).source 40 | local DIR = GetDirectory(source) or ((LUA_DIRNAME or LUAUI_DIRNAME) .."Widgets/") 41 | CHILI_DIRNAME = DIR .. "chili/" 42 | 43 | -------------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- 45 | 46 | function widget:Initialize() 47 | Chili = VFS.Include(CHILI_DIRNAME .. "core.lua", nil, VFS.RAW_FIRST) 48 | 49 | screen0 = Chili.Screen:New{} 50 | th = Chili.TextureHandler 51 | tk = Chili.TaskHandler 52 | tf = Chili.FontHandler 53 | 54 | --// Export Widget Globals 55 | WG.Chili = Chili 56 | WG.Chili.Screen0 = screen0 57 | 58 | --// do this after the export to the WG table! 59 | --// because other widgets use it with `parent=Chili.Screen0`, 60 | --// but chili itself doesn't handle wrapped tables correctly (yet) 61 | screen0 = Chili.DebugHandler.SafeWrap(screen0) 62 | end 63 | 64 | function widget:Shutdown() 65 | --table.clear(Chili) the Chili table also is the global of the widget so it contains a lot more than chili's controls (pairs,select,...) 66 | WG.Chili = nil 67 | end 68 | 69 | function widget:Dispose() 70 | screen0:Dispose() 71 | end 72 | 73 | -------------------------------------------------------------------------------- 74 | -------------------------------------------------------------------------------- 75 | 76 | function widget:DrawScreen() 77 | gl.Color(1,1,1,1) 78 | if (not screen0:IsEmpty()) then 79 | gl.PushMatrix() 80 | local vsx,vsy = gl.GetViewSizes() 81 | gl.Translate(0,vsy,0) 82 | gl.Scale(1,-1,1) 83 | screen0:Draw() 84 | gl.PopMatrix() 85 | end 86 | gl.Color(1,1,1,1) 87 | end 88 | 89 | 90 | function widget:DrawLoadScreen() 91 | gl.Color(1,1,1,1) 92 | if (not screen0:IsEmpty()) then 93 | gl.PushMatrix() 94 | local vsx,vsy = gl.GetViewSizes() 95 | gl.Scale(1/vsx,1/vsy,1) 96 | gl.Translate(0,vsy,0) 97 | gl.Scale(1,-1,1) 98 | screen0:Draw() 99 | gl.PopMatrix() 100 | end 101 | gl.Color(1,1,1,1) 102 | end 103 | 104 | 105 | function widget:TweakDrawScreen() 106 | gl.Color(1,1,1,1) 107 | if (not screen0:IsEmpty()) then 108 | gl.PushMatrix() 109 | local vsx,vsy = gl.GetViewSizes() 110 | gl.Translate(0,vsy,0) 111 | gl.Scale(1,-1,1) 112 | screen0:TweakDraw() 113 | gl.PopMatrix() 114 | end 115 | gl.Color(1,1,1,1) 116 | end 117 | 118 | 119 | function widget:DrawGenesis() 120 | gl.Color(1,1,1,1) 121 | tf.Update() 122 | th.Update() 123 | tk.Update() 124 | gl.Color(1,1,1,1) 125 | end 126 | 127 | 128 | function widget:IsAbove(x,y) 129 | if Spring.IsGUIHidden() then return false end 130 | 131 | return screen0:IsAbove(x,y) 132 | end 133 | 134 | 135 | local mods = {} 136 | function widget:MousePress(x,y,button) 137 | if Spring.IsGUIHidden() then return false end 138 | 139 | local alt, ctrl, meta, shift = Spring.GetModKeyState() 140 | mods.alt=alt; mods.ctrl=ctrl; mods.meta=meta; mods.shift=shift; 141 | return screen0:MouseDown(x,y,button,mods) 142 | end 143 | 144 | 145 | function widget:MouseRelease(x,y,button) 146 | if Spring.IsGUIHidden() then return false end 147 | 148 | local alt, ctrl, meta, shift = Spring.GetModKeyState() 149 | mods.alt=alt; mods.ctrl=ctrl; mods.meta=meta; mods.shift=shift; 150 | return screen0:MouseUp(x,y,button,mods) 151 | end 152 | 153 | 154 | function widget:MouseMove(x,y,dx,dy,button) 155 | if Spring.IsGUIHidden() then return false end 156 | 157 | local alt, ctrl, meta, shift = Spring.GetModKeyState() 158 | mods.alt=alt; mods.ctrl=ctrl; mods.meta=meta; mods.shift=shift; 159 | return screen0:MouseMove(x,y,dx,dy,button,mods) 160 | end 161 | 162 | 163 | function widget:MouseWheel(up,value) 164 | if Spring.IsGUIHidden() then return false end 165 | 166 | local x,y = Spring.GetMouseState() 167 | local alt, ctrl, meta, shift = Spring.GetModKeyState() 168 | mods.alt=alt; mods.ctrl=ctrl; mods.meta=meta; mods.shift=shift; 169 | return screen0:MouseWheel(x,y,up,value,mods) 170 | end 171 | 172 | 173 | local keyPressed = true 174 | function widget:KeyPress(key, mods, isRepeat, label, unicode) 175 | if Spring.IsGUIHidden() then return false end 176 | 177 | keyPressed = screen0:KeyPress(key, mods, isRepeat, label, unicode) 178 | return keyPressed 179 | end 180 | 181 | 182 | function widget:KeyRelease() 183 | if Spring.IsGUIHidden() then return false end 184 | 185 | local _keyPressed = keyPressed 186 | keyPressed = false 187 | return _keyPressed -- block engine actions when we processed it 188 | end 189 | 190 | function widget:TextInput(utf8, ...) 191 | if Spring.IsGUIHidden() then return false end 192 | 193 | return screen0:TextInput(utf8, ...) 194 | end 195 | 196 | 197 | function widget:ViewResize(vsx, vsy) 198 | screen0:Resize(vsx, vsy) 199 | end 200 | 201 | widget.TweakIsAbove = widget.IsAbove 202 | widget.TweakMousePress = widget.MousePress 203 | widget.TweakMouseRelease = widget.MouseRelease 204 | widget.TweakMouseMove = widget.MouseMove 205 | widget.TweakMouseWheel = widget.MouseWheel 206 | 207 | -------------------------------------------------------------------------------- 208 | -------------------------------------------------------------------------------- 209 | -------------------------------------------------------------------------------- /luaui/chili/chili/README: -------------------------------------------------------------------------------- 1 | object 2 | |_screen 3 | |_control 4 | |_window 5 | |_button 6 | |_image 7 | |_checkbox 8 | |_label 9 | |_textbox 10 | |_trackbar 11 | |_colorbars 12 | 13 | |_scrollpanel 14 | 15 | |_selectionbox 16 | 17 | |_layoutpanel 18 | |_imagelistview 19 | |_grid 20 | |_stackpanel -------------------------------------------------------------------------------- /luaui/chili/chili/controls/README: -------------------------------------------------------------------------------- 1 | object 2 | |_font 3 | |_screen 4 | |_control 5 | |_button 6 | |_image 7 | |_checkbox 8 | |_colorbars 9 | |_label 10 | |_layoutpanel 11 | |_imagelistview 12 | |_grid 13 | |_stackpanel 14 | |_treeview 15 | |_panel 16 | |_progressbar 17 | |_scrollpanel 18 | |_textbox 19 | |_trackbar 20 | |_treeview 21 | (|_treeviewnode) 22 | |_window -------------------------------------------------------------------------------- /luaui/chili/chili/controls/button.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Button module 4 | 5 | --- Button fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Button 9 | -- @string[opt="button"] caption caption to be displayed 10 | Button = Control:Inherit{ 11 | classname= "button", 12 | caption = 'button', 13 | defaultWidth = 70, 14 | defaultHeight = 20, 15 | } 16 | 17 | local this = Button 18 | local inherited = this.inherited 19 | 20 | --//============================================================================= 21 | 22 | --- Sets the caption of the button 23 | -- @string caption new caption of the button 24 | function Button:SetCaption(caption) 25 | if (self.caption == caption) then return end 26 | self.caption = caption 27 | self:Invalidate() 28 | end 29 | 30 | --//============================================================================= 31 | 32 | function Button:DrawControl() 33 | --// gets overriden by the skin/theme 34 | end 35 | 36 | --//============================================================================= 37 | 38 | function Button:HitTest(x,y) 39 | return self 40 | end 41 | 42 | function Button:MouseDown(...) 43 | self.state.pressed = true 44 | inherited.MouseDown(self, ...) 45 | self:Invalidate() 46 | return self 47 | end 48 | 49 | function Button:MouseUp(...) 50 | if (self.state.pressed) then 51 | self.state.pressed = false 52 | inherited.MouseUp(self, ...) 53 | self:Invalidate() 54 | return self 55 | end 56 | end 57 | 58 | --//============================================================================= 59 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/checkbox.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Checkbox module 4 | 5 | --- Checkbox fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Checkbox 9 | -- @bool[opt=true] checked checkbox checked state 10 | -- @string[opt="text"] caption caption to appear in the checkbox 11 | -- @string[opt="left"] textalign text alignment 12 | -- @string[opt="right"] boxalign box alignment 13 | -- @int[opt=10] boxsize box size 14 | -- @tparam {r,g,b,a} textColor text color, (default {0,0,0,1}) 15 | -- @tparam {func1,func2,...} OnChange listener functions for checked state changes, (default {}) 16 | Checkbox = Control:Inherit{ 17 | classname = "checkbox", 18 | checked = true, 19 | caption = "text", 20 | textalign = "left", 21 | boxalign = "right", 22 | boxsize = 10, 23 | 24 | textColor = {0,0,0,1}, 25 | 26 | defaultWidth = 70, 27 | defaultHeight = 18, 28 | 29 | OnChange = {} 30 | } 31 | 32 | local this = Checkbox 33 | local inherited = this.inherited 34 | 35 | --//============================================================================= 36 | 37 | function Checkbox:New(obj) 38 | obj = inherited.New(self,obj) 39 | obj.state.checked = obj.checked 40 | return obj 41 | end 42 | 43 | --//============================================================================= 44 | 45 | --- Toggles the checked state 46 | function Checkbox:Toggle() 47 | self:CallListeners(self.OnChange,not self.checked) 48 | self.checked = not self.checked 49 | self.state.checked = self.checked 50 | self:Invalidate() 51 | end 52 | 53 | --//============================================================================= 54 | 55 | function Checkbox:DrawControl() 56 | --// gets overriden by the skin/theme 57 | end 58 | 59 | --//============================================================================= 60 | 61 | function Checkbox:HitTest() 62 | return self 63 | end 64 | 65 | function Checkbox:MouseDown() 66 | self:Toggle() 67 | return self 68 | end 69 | 70 | --//============================================================================= 71 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/colorbars.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Colorbars module 4 | 5 | --- Colorbar fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Colorbars 9 | -- @tparam {r,g,b,a} color color table, (default {1,1,1,1}) 10 | -- @tparam {func1,func2,...} OnChange listener functions for color changes, (default {}) 11 | Colorbars = Control:Inherit{ 12 | classname = "colorbars", 13 | color = {1,1,1,1}, 14 | 15 | defaultWidth = 100, 16 | defaultHeight = 20, 17 | 18 | OnChange = {}, 19 | } 20 | 21 | local this = Colorbars 22 | local inherited = this.inherited 23 | 24 | --//============================================================================= 25 | 26 | --- Sets the new color 27 | -- @tparam {r,g,b,a} c color table 28 | function Colorbars:SetColor(c) 29 | self:CallListeners(self.OnChange,c) 30 | self.value = c 31 | self:Invalidate() 32 | end 33 | 34 | --//============================================================================= 35 | 36 | local GL_LINE_LOOP = GL.LINE_LOOP 37 | local GL_LINES = GL.LINES 38 | local glPushMatrix = gl.PushMatrix 39 | local glPopMatrix = gl.PopMatrix 40 | local glTranslate = gl.Translate 41 | local glVertex = gl.Vertex 42 | local glRect = gl.Rect 43 | local glColor = gl.Color 44 | local glBeginEnd = gl.BeginEnd 45 | 46 | function Colorbars:DrawControl() 47 | local barswidth = self.width - (self.height + 4) 48 | 49 | local color = self.color 50 | local step = self.height/7 51 | 52 | --bars 53 | local rX1,rY1,rX2,rY2 = 0,0*step,color[1]*barswidth,1*step 54 | local gX1,gY1,gX2,gY2 = 0,2*step,color[2]*barswidth,3*step 55 | local bX1,bY1,bX2,bY2 = 0,4*step,color[3]*barswidth,5*step 56 | local aX1,aY1,aX2,aY2 = 0,6*step,(color[4] or 1)*barswidth,7*step 57 | 58 | glColor(1,0,0,1) 59 | glRect(rX1,rY1,rX2,rY2) 60 | 61 | glColor(0,1,0,1) 62 | glRect(gX1,gY1,gX2,gY2) 63 | 64 | glColor(0,0,1,1) 65 | glRect(bX1,bY1,bX2,bY2) 66 | 67 | glColor(1,1,1,1) 68 | glRect(aX1,aY1,aX2,aY2) 69 | 70 | glColor(self.color) 71 | glRect(barswidth + 2,self.height,self.width - 2,0) 72 | 73 | gl.BeginEnd(GL.TRIANGLE_STRIP, theme.DrawBorder_, barswidth + 2,0,self.width - barswidth - 4,self.height, 1, self.borderColor, self.borderColor2) 74 | end 75 | 76 | --//============================================================================= 77 | 78 | function Colorbars:HitTest() 79 | return self 80 | end 81 | 82 | function Colorbars:MouseDown(x,y) 83 | local step = self.height/7 84 | local yp = y/step 85 | local r = yp%2 86 | local barswidth = self.width - (self.height + 4) 87 | 88 | if (x<=barswidth)and(r<=1) then 89 | local barIdx = (yp-r)/2 + 1 90 | local newvalue = x/barswidth 91 | if (newvalue>1) then newvalue=1 elseif (newvalue<0) then newvalue=0 end 92 | self.color[barIdx] = newvalue 93 | self:SetColor(self.color) 94 | return self 95 | end 96 | end 97 | 98 | function Colorbars:MouseMove(x,y,dx,dy,button) 99 | if (button==1) then 100 | return self:MouseDown(x,y) 101 | end 102 | end 103 | 104 | --//============================================================================= 105 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/combobox.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- ComboBox module 4 | 5 | --- ComboBox fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table ComboBox 9 | -- @tparam {"item1","item2",...} items table of items in the ComboBox, (default {"items"}) 10 | -- @int[opt=1] selected id of the selected item 11 | -- @tparam {func1,func2,...} OnSelect listener functions for selected item changes, (default {}) 12 | ComboBox = Button:Inherit{ 13 | classname = "combobox", 14 | caption = 'combobox', 15 | defaultWidth = 70, 16 | defaultHeight = 20, 17 | items = { "items" }, 18 | selected = 1, 19 | OnSelect = {}, 20 | maxDropDownHeight = 200, 21 | minDropDownHeight = 50, 22 | maxDropDownWidth = 500, 23 | minDropDownWidth = 50, 24 | } 25 | 26 | local ComboBoxWindow = Window:Inherit{classname = "combobox_window", resizable = false, draggable = false, } 27 | local ComboBoxScrollPanel = ScrollPanel:Inherit{classname = "combobox_scrollpanel", horizontalScrollbar = false, } 28 | local ComboBoxStackPanel = StackPanel:Inherit{classname = "combobox_stackpanel", autosize = true, resizeItems = false, borderThickness = 0, padding = {0,0,0,0}, itemPadding = {0,0,0,0}, itemMargin = {0,0,0,0}, } 29 | local ComboBoxItem = Button:Inherit{classname = "combobox_item"} 30 | 31 | local this = ComboBox 32 | local inherited = this.inherited 33 | 34 | function ComboBox:New(obj) 35 | obj = inherited.New(self,obj) 36 | obj:Select(obj.selected or 1) 37 | return obj 38 | end 39 | 40 | --- Selects an item by id 41 | -- @int itemIdx id of the item to be selected 42 | function ComboBox:Select(itemIdx) 43 | if (type(itemIdx)=="number") then 44 | local item = self.items[itemIdx] 45 | if not item then 46 | return 47 | end 48 | self.selected = itemIdx 49 | self.caption = "" 50 | 51 | if type(item) == "string" then 52 | self.caption = item 53 | end 54 | self:CallListeners(self.OnSelect, itemIdx, true) 55 | self:Invalidate() 56 | end 57 | --FIXME add Select(name) 58 | end 59 | 60 | function ComboBox:_CloseWindow() 61 | if self._dropDownWindow then 62 | self._dropDownWindow:Dispose() 63 | self._dropDownWindow = nil 64 | end 65 | if (self.state.pressed) then 66 | self.state.pressed = false 67 | self:Invalidate() 68 | return self 69 | end 70 | end 71 | 72 | function ComboBox:FocusUpdate() 73 | if not self.state.focused then 74 | self:_CloseWindow() 75 | end 76 | end 77 | 78 | function ComboBox:MouseDown(...) 79 | self.state.pressed = true 80 | if not self._dropDownWindow then 81 | local sx,sy = self:LocalToScreen(0,0) 82 | 83 | local labels = {} 84 | local labelHeight = 20 85 | 86 | local width = math.max(self.width, self.minDropDownWidth) 87 | local height = 10 88 | for i = 1, #self.items do 89 | local item = self.items[i] 90 | if type(item) == "string" then 91 | local newBtn = ComboBoxItem:New { 92 | caption = item, 93 | width = '100%', 94 | height = labelHeight, 95 | state = {focused = (i == self.selected), selected = (i == self.selected)}, 96 | OnMouseUp = { function() 97 | self:Select(i) 98 | self:_CloseWindow() 99 | end } 100 | } 101 | labels[#labels+1] = newBtn 102 | height = height + labelHeight 103 | width = math.max(width, self.font:GetTextWidth(item)) 104 | else 105 | labels[#labels+1] = item 106 | item.OnMouseUp = { function() 107 | self:Select(i) 108 | self:_CloseWindow() 109 | end } 110 | width = math.max(width, item.width + 5) 111 | height = height + item.height -- FIXME: what if this height is relative? 112 | end 113 | end 114 | 115 | height = math.max(self.minDropDownHeight, height) 116 | height = math.min(self.maxDropDownHeight, height) 117 | width = math.min(self.maxDropDownWidth, width) 118 | 119 | local screen = self:FindParent("screen") 120 | local y = sy + self.height 121 | if y + height > screen.height then 122 | y = sy - height 123 | end 124 | 125 | self._dropDownWindow = ComboBoxWindow:New{ 126 | parent = screen, 127 | width = width, 128 | height = height, 129 | x = sx - (width - self.width), 130 | y = y, 131 | children = { 132 | ComboBoxScrollPanel:New{ 133 | width = "100%", 134 | height = "100%", 135 | children = { 136 | ComboBoxStackPanel:New{ 137 | width = '100%', 138 | children = labels, 139 | }, 140 | }, 141 | } 142 | } 143 | } 144 | else 145 | self:_CloseWindow() 146 | end 147 | 148 | self:Invalidate() 149 | return self 150 | end 151 | 152 | function ComboBox:MouseUp(...) 153 | self:Invalidate() 154 | return self 155 | -- this exists to override Button:MouseUp so it doesn't modify .state.pressed 156 | end 157 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/editbox.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- EditBox module 4 | 5 | --- EditBox fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table EditBox 9 | -- @tparam {r,g,b,a} cursorColor cursor color, (default {0,0,1,0.7}) 10 | -- @tparam {r,g,b,a} selectionColor selection color, (default {0,1,1,0.3}) 11 | -- @string[opt="left"] align alignment 12 | -- @string[opt="linecenter"] valign vertical alignment 13 | -- @string[opt=""] text text contained in the editbox 14 | -- @string[opt=""] hint hint to be displayed when there is no text and the control isn't focused 15 | -- @int[opt=1] cursor cursor position 16 | -- @bool passwordInput specifies whether the text should be treated as a password 17 | EditBox = Control:Inherit{ 18 | classname= "editbox", 19 | 20 | defaultWidth = 70, 21 | defaultHeight = 20, 22 | 23 | padding = {3,3,3,3}, 24 | 25 | cursorColor = {0,0,1,0.7}, 26 | selectionColor = {0,1,1,0.3}, 27 | 28 | align = "left", 29 | valign = "linecenter", 30 | 31 | hintFont = table.merge({ color = {1,1,1,0.7} }, Control.font), 32 | 33 | text = "", 34 | hint = "", 35 | cursor = 1, 36 | offset = 1, 37 | selStart = nil, 38 | selEnd = nil, 39 | 40 | allowUnicode = true, 41 | passwordInput = false, 42 | } 43 | if Script.IsEngineMinVersion == nil or not Script.IsEngineMinVersion(97) then 44 | EditBox.allowUnicode = false 45 | end 46 | 47 | local this = EditBox 48 | local inherited = this.inherited 49 | 50 | --//============================================================================= 51 | 52 | function EditBox:New(obj) 53 | obj = inherited.New(self,obj) 54 | obj._interactedTime = Spring.GetTimer() 55 | --// create font 56 | obj.hintFont = Font:New(obj.hintFont) 57 | obj.hintFont:SetParent(obj) 58 | obj:SetText(obj.text) 59 | obj:RequestUpdate() 60 | return obj 61 | end 62 | 63 | function EditBox:Dispose(...) 64 | Control.Dispose(self) 65 | self.hintFont:SetParent() 66 | end 67 | 68 | function EditBox:HitTest(x,y) 69 | return self 70 | end 71 | 72 | --//============================================================================= 73 | 74 | --- Sets the EditBox text 75 | -- @string newtext text to be set 76 | function EditBox:SetText(newtext) 77 | if (self.text == newtext) then return end 78 | self.text = newtext 79 | self.cursor = 1 80 | self.offset = 1 81 | self.selStart = nil 82 | self.selEnd = nil 83 | self:UpdateLayout() 84 | self:Invalidate() 85 | end 86 | 87 | 88 | function EditBox:UpdateLayout() 89 | local font = self.font 90 | 91 | --FIXME 92 | if (self.autosize) then 93 | local w = font:GetTextWidth(self.text); 94 | local h, d, numLines = font:GetTextHeight(self.text); 95 | 96 | if (self.autoObeyLineHeight) then 97 | h = math.ceil(numLines * font:GetLineHeight()) 98 | else 99 | h = math.ceil(h-d) 100 | end 101 | 102 | local x = self.x 103 | local y = self.y 104 | 105 | if self.valign == "center" then 106 | y = math.round(y + (self.height - h) * 0.5) 107 | elseif self.valign == "bottom" then 108 | y = y + self.height - h 109 | elseif self.valign == "top" then 110 | else 111 | end 112 | 113 | if self.align == "left" then 114 | elseif self.align == "right" then 115 | x = x + self.width - w 116 | elseif self.align == "center" then 117 | x = math.round(x + (self.width - w) * 0.5) 118 | end 119 | 120 | w = w + self.padding[1] + self.padding[3] 121 | h = h + self.padding[2] + self.padding[4] 122 | 123 | self:_UpdateConstraints(x,y,w,h) 124 | end 125 | 126 | end 127 | 128 | --//============================================================================= 129 | 130 | function EditBox:Update(...) 131 | --FIXME add special UpdateFocus event? 132 | 133 | --// redraw every few frames for blinking cursor 134 | inherited.Update(self, ...) 135 | 136 | if self.state.focused then 137 | self:RequestUpdate() 138 | if (os.clock() >= (self._nextCursorRedraw or -math.huge)) then 139 | self._nextCursorRedraw = os.clock() + 0.1 --10FPS 140 | self:Invalidate() 141 | end 142 | end 143 | end 144 | 145 | function EditBox:_SetCursorByMousePos(x, y) 146 | local clientX = self.clientArea[1] 147 | if x - clientX < 0 then 148 | self.offset = self.offset - 1 149 | self.offset = math.max(0, self.offset) 150 | self.cursor = self.offset + 1 151 | else 152 | local text = self.text 153 | -- properly accounts for passworded text where characters are represented as "*" 154 | -- TODO: what if the passworded text is displayed differently? this is using assumptions about the skin 155 | if #text > 0 and self.passwordInput then 156 | text = string.rep("*", #text) 157 | end 158 | self.cursor = #text + 1 -- at end of text 159 | for i = self.offset, #text do 160 | local tmp = text:sub(self.offset, i) 161 | if self.font:GetTextWidth(tmp) > (x - clientX) then 162 | self.cursor = i 163 | break 164 | end 165 | end 166 | end 167 | end 168 | 169 | function EditBox:MouseDown(x, y, ...) 170 | local _, _, _, shift = Spring.GetModKeyState() 171 | local cp = self.cursor 172 | self:_SetCursorByMousePos(x, y) 173 | if shift then 174 | if not self.selStart then 175 | self.selStart = cp 176 | end 177 | self.selEnd = self.cursor 178 | elseif self.selStart then 179 | self.selStart = nil 180 | self.selEnd = nil 181 | end 182 | 183 | self._interactedTime = Spring.GetTimer() 184 | inherited.MouseDown(self, x, y, ...) 185 | self:Invalidate() 186 | return self 187 | end 188 | 189 | function EditBox:MouseMove(x, y, dx, dy, button) 190 | if button ~= 1 then 191 | return inherited.MouseMove(self, x, y, dx, dy, button) 192 | end 193 | 194 | local _, _, _, shift = Spring.GetModKeyState() 195 | local cp = self.cursor 196 | self:_SetCursorByMousePos(x, y) 197 | if not self.selStart then 198 | self.selStart = cp 199 | end 200 | self.selEnd = self.cursor 201 | 202 | self._interactedTime = Spring.GetTimer() 203 | inherited.MouseMove(self, x, y, dx, dy, button) 204 | self:Invalidate() 205 | return self 206 | end 207 | 208 | function EditBox:MouseUp(...) 209 | inherited.MouseUp(self, ...) 210 | self:Invalidate() 211 | return self 212 | end 213 | 214 | function EditBox:Select(startIndex, endIndex) 215 | self.selStart = startIndex 216 | self.selEnd = endIndex 217 | self:Invalidate() 218 | end 219 | 220 | function EditBox:ClearSelected() 221 | local left = self.selStart 222 | local right = self.selEnd 223 | if left > right then 224 | left, right = right, left 225 | end 226 | self.cursor = right 227 | local i = 0 228 | while self.cursor ~= left do 229 | self.text, self.cursor = Utf8BackspaceAt(self.text, self.cursor) 230 | i = i + 1 231 | if i > 100 then 232 | break 233 | end 234 | end 235 | self.selStart = nil 236 | self.selEnd = nil 237 | self:Invalidate() 238 | end 239 | 240 | 241 | function EditBox:KeyPress(key, mods, isRepeat, label, unicode, ...) 242 | local cp = self.cursor 243 | local txt = self.text 244 | 245 | -- enter & return 246 | if key == Spring.GetKeyCode("enter") or key == Spring.GetKeyCode("numpad_enter") then 247 | return inherited.KeyPress(self, key, mods, isRepeat, label, unicode, ...) or true 248 | 249 | -- deletions 250 | elseif key == Spring.GetKeyCode("backspace") then 251 | if self.selStart == nil then 252 | if mods.ctrl then 253 | repeat 254 | self.text, self.cursor = Utf8BackspaceAt(self.text, self.cursor) 255 | until self.cursor == 1 or (self.text:sub(self.cursor-2, self.cursor-2) ~= " " and self.text:sub(self.cursor-1, self.cursor-1) == " ") 256 | else 257 | self.text, self.cursor = Utf8BackspaceAt(self.text, self.cursor) 258 | end 259 | else 260 | self:ClearSelected() 261 | end 262 | elseif key == Spring.GetKeyCode("delete") then 263 | if self.selStart == nil then 264 | if mods.ctrl then 265 | repeat 266 | self.text = Utf8DeleteAt(self.text, self.cursor) 267 | until self.cursor >= #self.text-1 or (self.text:sub(self.cursor, self.cursor) == " " and self.text:sub(self.cursor+1, self.cursor+1) ~= " ") 268 | else 269 | self.text = Utf8DeleteAt(txt, cp) 270 | end 271 | else 272 | self:ClearSelected() 273 | end 274 | 275 | -- cursor movement 276 | elseif key == Spring.GetKeyCode("left") then 277 | if mods.ctrl then 278 | repeat 279 | self.cursor = Utf8PrevChar(txt, self.cursor) 280 | until self.cursor == 1 or (txt:sub(self.cursor-1, self.cursor-1) ~= " " and txt:sub(self.cursor, self.cursor) == " ") 281 | else 282 | self.cursor = Utf8PrevChar(txt, cp) 283 | end 284 | elseif key == Spring.GetKeyCode("right") then 285 | if mods.ctrl then 286 | repeat 287 | self.cursor = Utf8NextChar(txt, self.cursor) 288 | until self.cursor >= #txt-1 or (txt:sub(self.cursor-1, self.cursor-1) == " " and txt:sub(self.cursor, self.cursor) ~= " ") 289 | else 290 | self.cursor = Utf8NextChar(txt, cp) 291 | end 292 | elseif key == Spring.GetKeyCode("home") then 293 | self.cursor = 1 294 | elseif key == Spring.GetKeyCode("end") then 295 | self.cursor = #txt + 1 296 | 297 | -- copy & paste 298 | elseif mods.ctrl and (key == Spring.GetKeyCode("c") or key == Spring.GetKeyCode("x")) then 299 | local s = self.selStart 300 | local e = self.selEnd 301 | if s and e then 302 | s,e = math.min(s,e), math.max(s,e) 303 | Spring.SetClipboard(txt:sub(s,e-1)) 304 | end 305 | if key == Spring.GetKeyCode("x") and self.selStart ~= nil then 306 | self:ClearSelected() 307 | end 308 | elseif mods.ctrl and key == Spring.GetKeyCode("v") then 309 | self:TextInput(Spring.GetClipboard()) 310 | 311 | -- select all 312 | elseif mods.ctrl and key == Spring.GetKeyCode("a") then 313 | self.selStart = 1 314 | self.selEnd = #txt + 1 315 | -- character input 316 | elseif unicode and unicode ~= 0 then 317 | -- backward compability with Spring <97 318 | self:TextInput(unicode) 319 | end 320 | 321 | -- text selection handling 322 | if key == Spring.GetKeyCode("left") or key == Spring.GetKeyCode("right") or key == Spring.GetKeyCode("home") or key == Spring.GetKeyCode("end") then 323 | if mods.shift then 324 | if not self.selStart then 325 | self.selStart = cp 326 | end 327 | self.selEnd = self.cursor 328 | elseif self.selStart then 329 | self.selStart = nil 330 | self.selEnd = nil 331 | end 332 | end 333 | 334 | self._interactedTime = Spring.GetTimer() 335 | inherited.KeyPress(self, key, mods, isRepeat, label, unicode, ...) 336 | self:UpdateLayout() 337 | self:Invalidate() 338 | return self 339 | end 340 | 341 | 342 | function EditBox:TextInput(utf8char, ...) 343 | local unicode = utf8char 344 | if (not self.allowUnicode) then 345 | local success 346 | success, unicode = pcall(string.char, utf8char) 347 | if success then 348 | success = not unicode:find("%c") 349 | end 350 | if not success then 351 | unicode = nil 352 | end 353 | end 354 | 355 | if unicode then 356 | local cp = self.cursor 357 | local txt = self.text 358 | if self.selStart ~= nil then 359 | self:ClearSelected() 360 | txt = self.text 361 | cp = self.cursor 362 | end 363 | self.text = txt:sub(1, cp - 1) .. unicode .. txt:sub(cp, #txt) 364 | self.cursor = cp + unicode:len() 365 | end 366 | 367 | self._interactedTime = Spring.GetTimer() 368 | inherited.TextInput(self, utf8char, ...) 369 | self:UpdateLayout() 370 | self:Invalidate() 371 | return self 372 | end 373 | 374 | --//============================================================================= 375 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/font.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Font module 4 | 5 | --- Font fields 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Font 9 | -- @string[opt="FreeSansBold.otf"] font font name 10 | -- @int[opt=12] size font size 11 | -- @bool[opt=false] shadow shadow enabled 12 | -- @bool[opt=false] outline outline enabled 13 | -- @tparam {r,g,b,a} color color table (default {1,1,1,1}) 14 | -- @tparam {r,g,b,a} outlineColor outlineColor table (default {0,0,0,1}) 15 | -- @bool[opt=true] autoOutlineColor ?? 16 | Font = Object:Inherit{ 17 | classname = 'font', 18 | 19 | font = "FreeSansBold.otf", 20 | size = 12, 21 | outlineWidth = 3, 22 | outlineWeight = 3, 23 | 24 | shadow = false, 25 | outline = false, 26 | color = {1,1,1,1}, 27 | outlineColor = {0,0,0,1}, 28 | autoOutlineColor = true, 29 | } 30 | 31 | local this = Font 32 | local inherited = this.inherited 33 | 34 | --//============================================================================= 35 | 36 | function Font:New(obj) 37 | obj = inherited.New(self,obj) 38 | 39 | --// Load the font 40 | obj:_LoadFont() 41 | 42 | return obj 43 | end 44 | 45 | 46 | function Font:Dispose(...) 47 | if (not self.disposed) then 48 | FontHandler.UnloadFont(self._font) 49 | end 50 | inherited.Dispose(self,...) 51 | end 52 | 53 | --//============================================================================= 54 | 55 | function Font:_LoadFont() 56 | local oldfont = self._font 57 | self._font = FontHandler.LoadFont(self.font,self.size,self.outlineWidth,self.outlineWeight) 58 | --// do this after LoadFont because it can happen that LoadFont returns the same font again 59 | --// but if we Unload our old one before, the gc could collect it before, so the engine would have to reload it again 60 | FontHandler.UnloadFont(oldfont) 61 | end 62 | 63 | --//============================================================================= 64 | 65 | local function NotEqual(v1, v2) 66 | local t1 = type(v1) 67 | local t2 = type(v2) 68 | 69 | if (t1 ~= t2) then 70 | return true 71 | end 72 | 73 | local isindexable = (t=="table")or(t=="metatable")or(t=="userdata") 74 | if (not isindexable) then 75 | return (t1 ~= t2) 76 | end 77 | 78 | for i,v in pairs(v1) do 79 | if (v ~= v2[i]) then 80 | return true 81 | end 82 | end 83 | for i,v in pairs(v2) do 84 | if (v ~= v1[i]) then 85 | return true 86 | end 87 | end 88 | end 89 | 90 | 91 | do 92 | --// Create some Set... methods (e.g. SetColor, SetSize, SetFont, ...) 93 | 94 | local params = { 95 | font = true, 96 | size = true, 97 | outlineWidth = true, 98 | outlineWeight = true, 99 | shadow = false, 100 | outline = false, 101 | color = false, 102 | outlineColor = false, 103 | autoOutlineColor = false, 104 | } 105 | 106 | for param,recreateFont in pairs(params) do 107 | local paramWithUpperCase = param:gsub("^%l", string.upper) 108 | local funcname = "Set" .. paramWithUpperCase 109 | 110 | Font[funcname] = function(self,value,...) 111 | local t = type(value) 112 | 113 | local oldValue = self[param] 114 | 115 | if (t == "table") then 116 | self[param] = table.shallowcopy(value) 117 | else 118 | local to = type(self[param]) 119 | if (to == "table") then 120 | --// this allows :SetColor(r,g,b,a) and :SetColor({r,g,b,a}) 121 | local newtable = {value,...} 122 | table.merge(newtable,self[param]) 123 | self[param] = newtable 124 | else 125 | self[param] = value 126 | end 127 | end 128 | 129 | local p = self.parent 130 | if (recreateFont) then 131 | self:_LoadFont() 132 | if (p) then 133 | p:RequestRealign() 134 | end 135 | else 136 | if (p)and NotEqual(oldValue, self[param]) then 137 | p:Invalidate() 138 | end 139 | end 140 | end 141 | end 142 | 143 | params = nil 144 | end 145 | 146 | --//============================================================================= 147 | 148 | function Font:GetLineHeight(size) 149 | return self._font.lineheight * (size or self.size) 150 | end 151 | 152 | function Font:GetAscenderHeight(size) 153 | local font = self._font 154 | return (font.lineheight + font.descender) * (size or self.size) 155 | end 156 | 157 | function Font:GetTextWidth(text, size) 158 | return (self._font):GetTextWidth(text) * (size or self.size) 159 | end 160 | 161 | function Font:GetTextHeight(text, size) 162 | if (not size) then size = self.size end 163 | local h,descender,numlines = (self._font):GetTextHeight(text) 164 | return h*size, descender*size, numlines 165 | end 166 | 167 | function Font:WrapText(text, width, height, size) 168 | if (not size) then size = self.size end 169 | if (height < 1.5 * self._font.lineheight)or(width < size) then 170 | return text --//workaround for a bug in <=80.5.2 171 | end 172 | return (self._font):WrapText(text,width,height,size) 173 | end 174 | 175 | --//============================================================================= 176 | 177 | function Font:AdjustPosToAlignment(x, y, width, height, align, valign) 178 | local extra = '' 179 | 180 | if self.shadow then 181 | width = width - 1 - self.size * 0.1 182 | height = height - 1 - self.size * 0.1 183 | elseif self.outline then 184 | width = width - 1 - self.outlineWidth 185 | height = height - 1 - self.outlineWidth 186 | end 187 | 188 | --// vertical alignment 189 | if valign == "center" then 190 | y = y + height/2 191 | extra = 'v' 192 | elseif valign == "top" then 193 | extra = 't' 194 | elseif valign == "bottom" then 195 | y = y + height 196 | extra = 'b' 197 | elseif valign == "linecenter" then 198 | y = y + (height / 2) + (1 + self._font.descender) * self.size / 2 199 | extra = 'x' 200 | else 201 | --// ascender 202 | extra = 'a' 203 | end 204 | --FIXME add baseline 'd' 205 | 206 | --// horizontal alignment 207 | if align == "left" then 208 | --do nothing 209 | elseif align == "center" then 210 | x = x + width/2 211 | extra = extra .. 'c' 212 | elseif align == "right" then 213 | x = x + width 214 | extra = extra .. 'r' 215 | end 216 | 217 | return x,y,extra 218 | end 219 | 220 | local function _GetExtra(align, valign) 221 | local extra = '' 222 | 223 | --// vertical alignment 224 | if valign == "center" then 225 | extra = 'v' 226 | elseif valign == "top" then 227 | extra = 't' 228 | elseif valign == "bottom" then 229 | extra = 'b' 230 | else 231 | --// ascender 232 | extra = 'a' 233 | end 234 | 235 | --// horizontal alignment 236 | if align == "left" then 237 | --do nothing 238 | elseif align == "center" then 239 | extra = extra .. 'c' 240 | elseif align == "right" then 241 | extra = extra .. 'r' 242 | end 243 | 244 | return extra 245 | end 246 | 247 | --//============================================================================= 248 | 249 | function Font:_DrawText(text, x, y, extra) 250 | local font = self._font 251 | 252 | gl.PushAttrib(GL.COLOR_BUFFER_BIT) 253 | gl.PushMatrix() 254 | gl.Scale(1,-1,1) 255 | font:Begin() 256 | if AreInRTT() then 257 | gl.BlendFuncSeparate(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ZERO, GL.ONE_MINUS_SRC_ALPHA) 258 | end 259 | font:SetTextColor(self.color) 260 | font:SetOutlineColor(self.outlineColor) 261 | font:SetAutoOutlineColor(self.autoOutlineColor) 262 | font:Print(text, x, -y, self.size, extra) 263 | font:End() 264 | gl.PopMatrix() 265 | gl.PopAttrib() 266 | end 267 | 268 | 269 | function Font:Draw(text, x, y, align, valign) 270 | if (not text) then 271 | return 272 | end 273 | 274 | local extra = _GetExtra(align, valign) 275 | if self.outline then 276 | extra = extra .. 'o' 277 | elseif self.shadow then 278 | extra = extra .. 's' 279 | end 280 | 281 | self:_DrawText(text, x, y, extra) 282 | end 283 | 284 | 285 | function Font:DrawInBox(text, x, y, w, h, align, valign) 286 | if (not text) then 287 | return 288 | end 289 | 290 | local x,y,extra = self:AdjustPosToAlignment(x, y, w, h, align, valign) 291 | 292 | if self.outline then 293 | extra = extra .. 'o' 294 | elseif self.shadow then 295 | extra = extra .. 's' 296 | end 297 | 298 | y = y + 1 --// FIXME: if this isn't done some chars as 'R' get truncated at the top 299 | 300 | self:_DrawText(text, x, y, extra) 301 | end 302 | 303 | Font.Print = Font.Draw 304 | Font.PrintInBox = Font.DrawInBox 305 | 306 | --//============================================================================= 307 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/grid.lua: -------------------------------------------------------------------------------- 1 | --- Grid module 2 | 3 | --- Grid fields. 4 | -- Inherits from LayoutPanel. 5 | -- @see layoutpanel.LayoutPanel 6 | -- @table Grid 7 | Grid = LayoutPanel:Inherit{ 8 | classname = "grid", 9 | resizeItems = true, 10 | itemPadding = {0, 0, 0, 0}, 11 | } 12 | 13 | local this = Grid 14 | local inherited = this.inherited 15 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/image.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Image module 4 | 5 | --- Image fields. 6 | -- Inherits from Control. 7 | -- @see button.Button 8 | -- @table Image 9 | -- @tparam {r,g,b,a} color color, (default {1,1,1,1}) 10 | -- @string[opt=nil] file path 11 | -- @bool[opt=true] keepAspect aspect should be kept 12 | -- @tparam {func1,func2} OnClick function listeners to be invoked on click (default {}) 13 | Image = Button:Inherit{ 14 | classname= "image", 15 | 16 | defaultWidth = 64, 17 | defaultHeight = 64, 18 | padding = {0,0,0,0}, 19 | color = {1,1,1,1}, 20 | 21 | file = nil, 22 | file2 = nil, 23 | 24 | flip = true; 25 | flip2 = true; 26 | 27 | keepAspect = true; 28 | 29 | useRTT = false; 30 | 31 | OnClick = {}, 32 | } 33 | 34 | 35 | local this = Image 36 | local inherited = this.inherited 37 | 38 | --//============================================================================= 39 | 40 | local function _DrawTextureAspect(x,y,w,h ,tw,th, flipy) 41 | local twa = w/tw 42 | local tha = h/th 43 | 44 | local aspect = 1 45 | if (twa < tha) then 46 | aspect = twa 47 | y = y + h*0.5 - th*aspect*0.5 48 | h = th*aspect 49 | else 50 | aspect = tha 51 | x = x + w*0.5 - tw*aspect*0.5 52 | w = tw*aspect 53 | end 54 | 55 | local right = math.ceil(x+w) 56 | local bottom = math.ceil(y+h) 57 | x = math.ceil(x) 58 | y = math.ceil(y) 59 | 60 | gl.TexRect(x,y,right,bottom,false,flipy) 61 | end 62 | 63 | function Image:DrawControl() 64 | if (not (self.file or self.file2)) then return end 65 | gl.Color(self.color) 66 | 67 | if (self.keepAspect) then 68 | if (self.file2) then 69 | TextureHandler.LoadTexture(0,self.file2,self) 70 | local texInfo = gl.TextureInfo(self.file2) or {xsize=1, ysize=1} 71 | local tw,th = texInfo.xsize, texInfo.ysize 72 | _DrawTextureAspect(0,0,self.width,self.height, tw,th, self.flip2) 73 | end 74 | if (self.file) then 75 | TextureHandler.LoadTexture(0,self.file,self) 76 | local texInfo = gl.TextureInfo(self.file) or {xsize=1, ysize=1} 77 | local tw,th = texInfo.xsize, texInfo.ysize 78 | _DrawTextureAspect(0,0,self.width,self.height, tw,th, self.flip) 79 | end 80 | else 81 | if (self.file2) then 82 | TextureHandler.LoadTexture(0,self.file2,self) 83 | gl.TexRect(0,0,self.width,self.height,false,self.flip2) 84 | end 85 | if (self.file) then 86 | TextureHandler.LoadTexture(0,self.file,self) 87 | gl.TexRect(0,0,self.width,self.height,false,self.flip) 88 | end 89 | end 90 | gl.Texture(0,false) 91 | end 92 | 93 | --//============================================================================= 94 | 95 | function Image:IsActive() 96 | local onclick = self.OnClick 97 | if (onclick and onclick[1]) then 98 | return true 99 | end 100 | end 101 | 102 | function Image:HitTest() 103 | --FIXME check if there are any eventhandlers linked (OnClick,OnMouseUp,...) 104 | return self:IsActive() and self 105 | end 106 | 107 | function Image:MouseDown(...) 108 | --// we don't use `this` here because it would call the eventhandler of the button class, 109 | --// which always returns true, but we just want to do so if a calllistener handled the event 110 | return Control.MouseDown(self, ...) or self:IsActive() and self 111 | end 112 | 113 | function Image:MouseUp(...) 114 | return Control.MouseUp(self, ...) or self:IsActive() and self 115 | end 116 | 117 | function Image:MouseClick(...) 118 | return Control.MouseClick(self, ...) or self:IsActive() and self 119 | end 120 | 121 | --//============================================================================= 122 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/imagelistview.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- ImageListView module 4 | 5 | --- ImageListView fields. 6 | -- Inherits from LayoutPanel. 7 | -- @see layoutpanel.LayoutPanel 8 | -- @table ImageListView 9 | -- @string[opt=""] dir initial directory 10 | -- @tparam {func1,func2,...} OnDirChange table of function listeners for directory change (default {}) 11 | ImageListView = LayoutPanel:Inherit{ 12 | classname = "imagelistview", 13 | 14 | autosize = true, 15 | 16 | autoArrangeH = false, 17 | autoArrangeV = false, 18 | centerItems = false, 19 | 20 | iconX = 64, 21 | iconY = 64, 22 | 23 | itemMargin = {1, 1, 1, 1}, 24 | 25 | selectable = true, 26 | multiSelect = true, 27 | 28 | items = {}, 29 | 30 | dir = '', 31 | 32 | useRTT = false; 33 | 34 | OnDirChange = {}, 35 | } 36 | 37 | local this = ImageListView 38 | local inherited = this.inherited 39 | 40 | --//============================================================================= 41 | 42 | local image_exts = {'.jpg','.bmp','.png','.tga','.dds','.ico','.gif','.psd','.tif'} --'.psp' 43 | 44 | --//============================================================================= 45 | 46 | function ImageListView:New(obj) 47 | obj = inherited.New(self,obj) 48 | obj:SetDir(obj.dir) 49 | return obj 50 | end 51 | 52 | --//============================================================================= 53 | 54 | local function GetParentDir(dir) 55 | dir = dir:gsub("\\", "/") 56 | local lastChar = dir:sub(-1) 57 | if (lastChar == "/") then 58 | dir = dir:sub(1,-2) 59 | end 60 | local pos,b,e,match,init,n = 1,1,1,1,0,0 61 | repeat 62 | pos,init,n = b,init+1,n+1 63 | b,init,match = dir:find("/",init,true) 64 | until (not b) 65 | if (n==1) then 66 | return '' 67 | else 68 | return dir:sub(1,pos) 69 | end 70 | end 71 | 72 | 73 | local function ExtractFileName(filepath) 74 | filepath = filepath:gsub("\\", "/") 75 | local lastChar = filepath:sub(-1) 76 | if (lastChar == "/") then 77 | filepath = filepath:sub(1,-2) 78 | end 79 | local pos,b,e,match,init,n = 1,1,1,1,0,0 80 | repeat 81 | pos,init,n = b,init+1,n+1 82 | b,init,match = filepath:find("/",init,true) 83 | until (not b) 84 | if (n==1) then 85 | return filepath 86 | else 87 | return filepath:sub(pos+1) 88 | end 89 | end 90 | 91 | 92 | local function ExtractDir(filepath) 93 | filepath = filepath:gsub("\\", "/") 94 | local lastChar = filepath:sub(-1) 95 | if (lastChar == "/") then 96 | filepath = filepath:sub(1,-2) 97 | end 98 | local pos,b,e,match,init,n = 1,1,1,1,0,0 99 | repeat 100 | pos,init,n = b,init+1,n+1 101 | b,init,match = filepath:find("/",init,true) 102 | until (not b) 103 | if (n==1) then 104 | return filepath 105 | else 106 | return filepath:sub(1,pos) 107 | end 108 | end 109 | 110 | --//============================================================================= 111 | 112 | function ImageListView:_AddFile(name,imagefile) 113 | self:AddChild( LayoutPanel:New{ 114 | width = self.iconX+10, 115 | height = self.iconY+20, 116 | padding = {0,0,0,0}, 117 | itemPadding = {0,0,0,0}, 118 | itemMargin = {0,0,0,0}, 119 | rows = 2, 120 | columns = 1, 121 | useRTT = false; 122 | 123 | children = { 124 | Image:New{ 125 | width = self.iconX, 126 | height = self.iconY, 127 | passive = true, 128 | file = ':clr' .. self.iconX .. ',' .. self.iconY .. ':' .. imagefile, 129 | }, 130 | Label:New{ 131 | width = self.iconX+10, 132 | height = 20, 133 | align = 'center', 134 | autosize = false, 135 | caption = name, 136 | }, 137 | }, 138 | }) 139 | end 140 | 141 | 142 | function ImageListView:ScanDir() 143 | local files = VFS.DirList(self.dir) 144 | local dirs = VFS.SubDirs(self.dir) 145 | local imageFiles = {} 146 | for i=1,#files do 147 | local f = files[i] 148 | local ext = (f:GetExt() or ""):lower() 149 | if (table.ifind(image_exts,ext))then 150 | imageFiles[#imageFiles+1]=f 151 | end 152 | end 153 | 154 | 155 | self._dirsNum = #dirs 156 | self._dirList = dirs 157 | 158 | local n = 1 159 | local items = self.items 160 | items[n] = '..' 161 | n = n+1 162 | 163 | for i=1,#dirs do 164 | items[n],n=dirs[i],n+1 165 | end 166 | for i=1,#imageFiles do 167 | items[n],n=imageFiles[i],n+1 168 | end 169 | if (#items>n-1) then 170 | for i=n,#items do 171 | items[i] = nil 172 | end 173 | end 174 | 175 | self:DisableRealign() 176 | --// clear old 177 | self:ClearChildren() 178 | 179 | --// add ".." 180 | self:_AddFile('..',self.imageFolderUp) 181 | 182 | --// add dirs at top 183 | for i=1,#dirs do 184 | self:_AddFile(ExtractFileName(dirs[i]),self.imageFolder) 185 | end 186 | 187 | --// add files 188 | for i=1,#imageFiles do 189 | self:_AddFile(ExtractFileName(imageFiles[i]),imageFiles[i]) 190 | end 191 | self:EnableRealign() 192 | end 193 | 194 | 195 | function ImageListView:SetDir(directory) 196 | self:DeselectAll() 197 | self.dir = directory 198 | self:ScanDir() 199 | self:CallListeners(self.OnDirChange, directory) 200 | 201 | if (self.parent) then 202 | self.parent:RequestRealign() 203 | else 204 | self:UpdateLayout() 205 | self:Invalidate() 206 | end 207 | end 208 | 209 | 210 | function ImageListView:GoToParentDir() 211 | self:SetDir(GetParentDir(self.dir)) 212 | end 213 | 214 | 215 | function ImageListView:GotoFile(filepath) 216 | local dir = ExtractDir(filepath) 217 | local file = ExtractFileName(filepath) 218 | self.dir = dir 219 | self:ScanDir() 220 | self:Select(file) 221 | 222 | if (self.parent) then 223 | if (self.parent.classname == "scrollpanel") then 224 | local x,y,w,h = self:GetItemXY(next(self.selectedItems)) 225 | self.parent:SetScrollPos(x+w*0.5, y+h*0.5, true) 226 | end 227 | 228 | self.parent:RequestRealign() 229 | else 230 | self:UpdateLayout() 231 | self:Invalidate() 232 | end 233 | end 234 | 235 | --//============================================================================= 236 | 237 | function ImageListView:Select(item) 238 | if (type(item)=="number") then 239 | self:SelectItem(item) 240 | else 241 | local items = self.items 242 | for i=1,#items do 243 | if (ExtractFileName(items[i])==item) then 244 | self:SelectItem(i) 245 | return 246 | end 247 | end 248 | self:SelectItem(1) 249 | end 250 | end 251 | 252 | --//============================================================================= 253 | 254 | function ImageListView:DrawItemBkGnd(index) 255 | local cell = self._cells[index] 256 | local itemPadding = self.itemPadding 257 | 258 | if (self.selectedItems[index]) then 259 | self:DrawItemBackground(cell[1] - itemPadding[1],cell[2] - itemPadding[2],cell[3] + itemPadding[1] + itemPadding[3],cell[4] + itemPadding[2] + itemPadding[4],"selected") 260 | else 261 | self:DrawItemBackground(cell[1] - itemPadding[1],cell[2] - itemPadding[2],cell[3] + itemPadding[1] + itemPadding[3],cell[4] + itemPadding[2] + itemPadding[4],"normal") 262 | end 263 | end 264 | 265 | --//============================================================================= 266 | 267 | function ImageListView:HitTest(x,y) 268 | local cx,cy = self:LocalToClient(x,y) 269 | local obj = inherited.HitTest(self,cx,cy) 270 | if (obj) then return obj end 271 | local itemIdx = self:GetItemIndexAt(cx,cy) 272 | return (itemIdx>=0) and self 273 | end 274 | 275 | 276 | function ImageListView:MouseDblClick(x,y) 277 | local cx,cy = self:LocalToClient(x,y) 278 | local itemIdx = self:GetItemIndexAt(cx,cy) 279 | 280 | if (itemIdx<0) then return end 281 | 282 | if (itemIdx==1) then 283 | self:SetDir(GetParentDir(self.dir)) 284 | return self 285 | end 286 | 287 | if (itemIdx<=self._dirsNum+1) then 288 | self:SetDir(self._dirList[itemIdx-1]) 289 | return self 290 | else 291 | self:CallListeners(self.OnDblClickItem, self.items[itemIdx], itemIdx) 292 | return self 293 | end 294 | end 295 | 296 | --//============================================================================= 297 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/label.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Label module 4 | 5 | --- Label fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Label 9 | -- @string[opt="left"] align alignment 10 | -- @string[opt="linecenter"] valign vertical alignment 11 | -- @string[opt="no text"] caption text to be displayed 12 | Label = Control:Inherit{ 13 | classname= "label", 14 | 15 | defaultWidth = 70, 16 | defaultHeight = 20, 17 | 18 | padding = {0,0,0,0}, 19 | 20 | autosize = true, 21 | autoObeyLineHeight = true, --// (needs autosize) if true, autosize will obey the lineHeight (-> texts with the same line count will have the same height) 22 | 23 | align = "left", 24 | valign = "linecenter", --// usefull too "ascender" 25 | caption = "no text", 26 | } 27 | 28 | local this = Label 29 | local inherited = this.inherited 30 | 31 | --//============================================================================= 32 | 33 | function Label:New(obj) 34 | obj = inherited.New(self,obj) 35 | obj:SetCaption(obj.caption) 36 | return obj 37 | end 38 | 39 | --//============================================================================= 40 | 41 | --- Set the label caption 42 | -- @string newcaption new caption to be set 43 | function Label:SetCaption(newcaption) 44 | if (self.caption == newcaption) then return end 45 | self.caption = newcaption 46 | self:UpdateLayout() 47 | self:Invalidate() 48 | end 49 | 50 | 51 | function Label:UpdateLayout() 52 | local font = self.font 53 | 54 | if (self.autosize) then 55 | self._caption = self.caption 56 | local w = font:GetTextWidth(self.caption); 57 | local h, d, numLines = font:GetTextHeight(self.caption); 58 | 59 | h = h + 1 60 | if (self.autoObeyLineHeight) then 61 | h = math.ceil(numLines * font:GetLineHeight()) 62 | else 63 | h = math.ceil(h-d) 64 | end 65 | 66 | if font.shadow then 67 | w = w + 2 + font.size * 0.1 68 | h = h + 2 + font.size * 0.1 69 | elseif font.outline then 70 | w = w + 2 + font.size * font.outlineWidth 71 | h = h + 2 + font.size * font.outlineWidth 72 | end 73 | 74 | local x = self.x 75 | local y = self.y 76 | 77 | if self.valign == "center" then 78 | y = math.round(y + (self.height - h) * 0.5) 79 | elseif self.valign == "bottom" then 80 | y = y + self.height - h 81 | elseif self.valign == "top" then 82 | else 83 | end 84 | 85 | if self.align == "left" then 86 | elseif self.align == "right" then 87 | x = x + self.width - w 88 | elseif self.align == "center" then 89 | x = math.round(x + (self.width - w) * 0.5) 90 | end 91 | 92 | self:_UpdateConstraints(x,y,w,h) 93 | else 94 | self._caption = font:WrapText(self.caption, self.width, self.height) 95 | end 96 | 97 | end 98 | 99 | --//============================================================================= 100 | 101 | function Label:DrawControl() 102 | local font = self.font 103 | font:DrawInBox(self._caption,0,0,self.width,self.height,self.align,self.valign) 104 | 105 | if (self.debug) then 106 | gl.Color(0,1,0,0.5) 107 | gl.PolygonMode(GL.FRONT_AND_BACK,GL.LINE) 108 | gl.LineWidth(2) 109 | gl.Rect(0,0,self.width,self.height) 110 | gl.LineWidth(1) 111 | gl.PolygonMode(GL.FRONT_AND_BACK,GL.FILL) 112 | end 113 | end 114 | 115 | --//============================================================================= 116 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/line.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Line module 4 | 5 | --- Line fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Line 9 | -- @string[opt="line"] caption text to be displayed on the line(?) 10 | -- @string[opt="horizontal] style style of the line 11 | Line = Control:Inherit{ 12 | classname= "line", 13 | caption = 'line', 14 | defaultWidth = 100, 15 | defaultHeight = 1, 16 | style = "horizontal", 17 | } 18 | 19 | local this = Line 20 | local inherited = this.inherited 21 | 22 | --//============================================================================= 23 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/multiprogressbar.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Multiprogressbar module 4 | 5 | --- Multiprogressbar fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Multiprogressbar 9 | -- @bool[opt=false] drawBorder should the border be drawn? 10 | -- @tparam {r,g,b,a} borderColor specifies the border color (default: {1,0,0,1}) 11 | -- @string[opt="horizontal"] orientation orientation of the progress bar 12 | -- @bool[opt=false] reverse reverse drawing orientation 13 | -- @tparam fnc scaleFunction scaling function that takes 0-1 and must return 0-1 14 | Multiprogressbar = Control:Inherit{ 15 | classname = "multiprogressbar", 16 | 17 | defaultWidth = 90, 18 | defaultHeight = 20, 19 | 20 | padding = {0,0,0,0}, 21 | drawBorder = false, 22 | borderColor = {1,0,0,1}, 23 | orientation = "horizontal", 24 | reverse = false, -- draw in reversed orientation 25 | 26 | scaleFunction = nil, --- function that can be used to rescale graph - takes 0-1 and must return 0-1 27 | 28 | -- list of bar components to display 29 | bars = { 30 | { 31 | color1 = {1,0,1,1}, 32 | color2 = {0.7,0,0.7,1}, 33 | percent = 0.2, 34 | texture = nil, -- texture file name 35 | s = 1, -- tex coords 36 | t = 1, 37 | tileSize = nil, -- if set then main axis texture coord = width / tileSize 38 | }, 39 | 40 | } 41 | } 42 | 43 | local this = Multiprogressbar 44 | local inherited = this.inherited 45 | 46 | --//============================================================================= 47 | 48 | local glVertex = gl.Vertex 49 | local glColor = gl.Color 50 | local glBeginEnd = gl.BeginEnd 51 | 52 | local function drawBox(x,y,w,h) 53 | glVertex(x,y) 54 | glVertex(x+w,y) 55 | glVertex(x+w,y+h) 56 | glVertex(x,y+h) 57 | end 58 | 59 | local function drawBarH(x,y,w,h,color1, color2) 60 | glColor(color1) 61 | glVertex(x,y) 62 | glVertex(x+w,y) 63 | glColor(color2) 64 | glVertex(x+w,y+h) 65 | glVertex(x,y+h) 66 | end 67 | 68 | local function drawBarV(x,y,w,h,color1, color2) 69 | glColor(color1) 70 | glVertex(x,y) 71 | glVertex(x,y+h) 72 | glColor(color2) 73 | glVertex(x+w,y+h) 74 | glVertex(x+w,y) 75 | end 76 | 77 | 78 | function Multiprogressbar:DrawControl() 79 | local percentDone = 0 80 | local efp 81 | 82 | 83 | if (self.scaleFunction ~= nil) then -- if using non linear scale fix the bar 84 | local totalPercent = 0 85 | for _,b in ipairs(self.bars) do 86 | totalPercent = totalPercent + (b.percent or 0) 87 | end 88 | 89 | local resize = self.scaleFunction(totalPercent) / totalPercent 90 | for _,b in ipairs(self.bars) do 91 | b._drawPercent = b.percent * resize 92 | end 93 | else 94 | for _,b in ipairs(self.bars) do 95 | b._drawPercent = b.percent 96 | end 97 | end 98 | 99 | 100 | if (self.orientation=="horizontal") then 101 | for _,b in ipairs(self.bars) do 102 | if b._drawPercent > 0 then 103 | if (self.reverse) then 104 | efp = 1 - percentDone - b._drawPercent 105 | else 106 | efp = percentDone 107 | end 108 | if (b.color1 ~= nil) then 109 | glBeginEnd(GL.QUADS, drawBarH, efp * self.width, 0, self.width * b._drawPercent, self.height, b.color1, b.color2) 110 | end 111 | percentDone = percentDone + b._drawPercent 112 | 113 | if b.texture then 114 | TextureHandler.LoadTexture(b.texture,self) 115 | glColor(1,1,1,1) 116 | 117 | local bs = b.s 118 | if (b.tileSize) then 119 | bs = self.width * b._drawPercent / b.tileSize 120 | end 121 | gl.TexRect(efp * self.width, 0, (efp + b._drawPercent) * self.width, self.height, 0,0,bs,b.t) 122 | gl.Texture(false) 123 | end 124 | end 125 | end 126 | 127 | else 128 | for _,b in ipairs(self.bars) do 129 | if b._drawPercent > 0 then 130 | if (self.reverse) then 131 | efp = 1 - percentDone - b._drawPercent 132 | else 133 | efp = percentDone 134 | end 135 | 136 | if (b.color1 ~= nil) then glBeginEnd(GL.QUADS, drawBarV, 0, efp * self.height, self.width, self.height * b._drawPercent, b.color1, b.color2) end 137 | 138 | percentDone = percentDone + b._drawPercent 139 | 140 | if b.texture then 141 | TextureHandler.LoadTexture(b.texture,self) 142 | glColor(1,1,1,1) 143 | 144 | local bt = b.t 145 | if (b.tileSize) then 146 | bt = self.height * b._drawPercent / b.tileSize 147 | end 148 | gl.TexRect(0, efp * self.height, self.width, (efp + b._drawPercent) * self.height, 0,0,b.s,bt) 149 | gl.Texture(false) 150 | end 151 | end 152 | end 153 | end 154 | 155 | 156 | 157 | if self.drawBorder then 158 | glColor(self.borderColor) 159 | glBeginEnd(GL.LINE_LOOP, drawBox, 0, 0, self.width, self.height) 160 | end 161 | 162 | end 163 | 164 | --//============================================================================= 165 | 166 | function Multiprogressbar:HitTest() 167 | return self 168 | end 169 | 170 | 171 | --//============================================================================= 172 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/panel.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Panel module 4 | 5 | --- Panel fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Panel 9 | Panel = Control:Inherit{ 10 | classname= "panel", 11 | defaultWidth = 100, 12 | defaultHeight = 100, 13 | } 14 | 15 | local this = Panel 16 | local inherited = this.inherited 17 | 18 | --//============================================================================= 19 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/progressbar.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Progressbar module 4 | 5 | --- Progressbar fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Progressbar 9 | -- @int[opt=0] min minimum value of the Progressbar 10 | -- @int[opt=100] max maximum value of the Progressbar 11 | -- @int[opt=100] value value of the Progressbar 12 | -- @string[opt=""] caption text to be displayed 13 | -- @tparam {r,g,b,a} color specifies the color of the bar (default: {0,0,1,1}) 14 | -- @tparam {r,g,b,a} backgroundColor specifies the background color (default: {1,1,1,1}) 15 | -- @tparam {func1,fun2,...} OnChange function listeners for value change (default {}) 16 | Progressbar = Control:Inherit{ 17 | classname = "progressbar", 18 | 19 | defaultWidth = 90, 20 | defaultHeight = 20, 21 | 22 | min = 0, 23 | max = 100, 24 | value = 100, 25 | 26 | caption = "", 27 | 28 | color = {0,0,1,1}, 29 | backgroundColor = {1,1,1,1}, 30 | 31 | OnChange = {}, 32 | } 33 | 34 | local this = Progressbar 35 | local inherited = this.inherited 36 | 37 | --//============================================================================= 38 | 39 | function Progressbar:New(obj) 40 | obj = inherited.New(self,obj) 41 | obj:SetMinMax(obj.min,obj.max) 42 | obj:SetValue(obj.value) 43 | return obj 44 | end 45 | 46 | --//============================================================================= 47 | 48 | function Progressbar:_Clamp(v) 49 | if (self.minself.max) then 53 | v = self.max 54 | end 55 | else 56 | if (v>self.min) then 57 | v = self.min 58 | elseif (v= 0) then 95 | local scale = self.width / (self.max-self.min) 96 | font:Print(0, scale * (0 - self.min), 0, "center", "ascender") 97 | end 98 | 99 | font:Print(self.min, 0, 0, "left", "ascender") 100 | font:Print("+"..self.max, self.width, 0, "right", "ascender") 101 | end 102 | 103 | --//============================================================================= 104 | 105 | function Scale:HitTest() 106 | return false 107 | end 108 | 109 | 110 | --//============================================================================= 111 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/screen.lua: -------------------------------------------------------------------------------- 1 | --- Screen module 2 | 3 | --- Screen fields. 4 | -- Inherits from Object. 5 | -- @see object.Object 6 | -- @table Screen 7 | -- @int[opt=0] x x position 8 | -- @int[opt=0] y y position 9 | -- @int[opt=0] width width 10 | -- @int[opt=0] height height 11 | -- @tparam control.Control activeControl active control 12 | -- @tparam control.Control focusedControl focused control 13 | -- @tparam control.Control hoveredControl hovered control 14 | Screen = Object:Inherit{ 15 | --Screen = Control:Inherit{ 16 | classname = 'screen', 17 | x = 0, 18 | y = 0, 19 | width = 0, 20 | height = 0, 21 | 22 | preserveChildrenOrder = true, 23 | 24 | -- The active control is the control currently receiving mouse events 25 | activeControl = nil, 26 | -- we also store the mouse button that was clicked 27 | activeControlBtn = nil, 28 | focusedControl = nil, 29 | hoveredControl = nil, 30 | currentTooltip = nil, 31 | _lastHoveredControl = nil, 32 | 33 | _lastClicked = Spring.GetTimer(), 34 | _lastClickedX = 0, 35 | _lastClickedY = 0, 36 | } 37 | 38 | local this = Screen 39 | local inherited = this.inherited 40 | 41 | --//============================================================================= 42 | 43 | function Screen:New(obj) 44 | local vsx,vsy = gl.GetViewSizes() 45 | if ((obj.width or -1) <= 0) then 46 | obj.width = vsx 47 | end 48 | if ((obj.height or -1) <= 0) then 49 | obj.height = vsy 50 | end 51 | 52 | obj = inherited.New(self,obj) 53 | 54 | TaskHandler.RequestGlobalDispose(obj) 55 | obj:RequestUpdate() 56 | 57 | return obj 58 | end 59 | 60 | 61 | function Screen:OnGlobalDispose(obj) 62 | if CompareLinks(self.activeControl, obj) then 63 | self.activeControl = nil 64 | end 65 | 66 | if CompareLinks(self.hoveredControl, obj) then 67 | self.hoveredControl = nil 68 | end 69 | 70 | if CompareLinks(self._lastHoveredControl, obj) then 71 | self._lastHoveredControl = nil 72 | end 73 | 74 | if CompareLinks(self.focusedControl, obj) then 75 | self.focusedControl = nil 76 | end 77 | end 78 | 79 | --//============================================================================= 80 | 81 | --FIXME add new coordspace Device (which does y-invert) 82 | 83 | function Screen:ParentToLocal(x,y) 84 | return x, y 85 | end 86 | 87 | 88 | function Screen:LocalToParent(x,y) 89 | return x, y 90 | end 91 | 92 | 93 | function Screen:LocalToScreen(x,y) 94 | return x, y 95 | end 96 | 97 | 98 | function Screen:ScreenToLocal(x,y) 99 | return x, y 100 | end 101 | 102 | 103 | function Screen:ScreenToClient(x,y) 104 | return x, y 105 | end 106 | 107 | 108 | function Screen:ClientToScreen(x,y) 109 | return x, y 110 | end 111 | 112 | 113 | function Screen:IsRectInView(x,y,w,h) 114 | return 115 | (x <= self.width) and 116 | (x + w >= 0) and 117 | (y <= self.height) and 118 | (y + h >= 0) 119 | end 120 | 121 | 122 | --//============================================================================= 123 | 124 | function Screen:Resize(w,h) 125 | self.width = w 126 | self.height = h 127 | self:CallChildren("RequestRealign") 128 | end 129 | 130 | 131 | --//============================================================================= 132 | 133 | function Screen:Update(...) 134 | --//FIXME create a passive MouseMove event and use it instead? 135 | self:RequestUpdate() 136 | local hoveredControl = UnlinkSafe(self.hoveredControl) 137 | local activeControl = UnlinkSafe(self.activeControl) 138 | if hoveredControl and (not activeControl) then 139 | local x, y = Spring.GetMouseState() 140 | y = select(2,gl.GetViewSizes()) - y 141 | local cx,cy = hoveredControl:ScreenToLocal(x, y) 142 | hoveredControl:MouseMove(cx, cy, 0, 0) 143 | end 144 | end 145 | 146 | 147 | function Screen:IsAbove(x,y,...) 148 | local activeControl = UnlinkSafe(self.activeControl) 149 | if activeControl then 150 | return true 151 | end 152 | 153 | y = select(2,gl.GetViewSizes()) - y 154 | local hoveredControl = inherited.IsAbove(self,x,y,...) 155 | 156 | --// tooltip 157 | if not CompareLinks(hoveredControl, self._lastHoveredControl) then 158 | if self._lastHoveredControl then 159 | self._lastHoveredControl:MouseOut() 160 | end 161 | if hoveredControl then 162 | hoveredControl:MouseOver() 163 | end 164 | 165 | self.hoveredControl = MakeWeakLink(hoveredControl, self.hoveredControl) 166 | if (hoveredControl) then 167 | local control = hoveredControl 168 | --// find tooltip in hovered control or its parents 169 | while (not control.tooltip)and(control.parent) do 170 | control = control.parent 171 | end 172 | self.currentTooltip = control.tooltip 173 | else 174 | self.currentTooltip = nil 175 | end 176 | self._lastHoveredControl = self.hoveredControl 177 | elseif (self._lastHoveredControl) then 178 | self.currentTooltip = self._lastHoveredControl.tooltip 179 | end 180 | 181 | return (not not hoveredControl) 182 | end 183 | 184 | function Screen:FocusControl(control) 185 | --UnlinkSafe(self.activeControl) 186 | if not CompareLinks(control, self.focusedControl) then 187 | local focusedControl = UnlinkSafe(self.focusedControl) 188 | if focusedControl then 189 | focusedControl.state.focused = false 190 | focusedControl:FocusUpdate() --rename FocusLost() 191 | end 192 | self.focusedControl = nil 193 | if control then 194 | self.focusedControl = MakeWeakLink(control, self.focusedControl) 195 | self.focusedControl.state.focused = true 196 | self.focusedControl:FocusUpdate() --rename FocusGain() 197 | end 198 | end 199 | end 200 | 201 | function Screen:MouseDown(x,y,btn,...) 202 | y = select(2,gl.GetViewSizes()) - y 203 | 204 | local activeControl = inherited.MouseDown(self,x,y,btn,...) 205 | local oldActiveControl = UnlinkSafe(self.activeControl) 206 | if activeControl ~= oldActiveControl and oldActiveControl ~= nil then 207 | -- send the mouse up to controls so they know to release 208 | self:MouseUp(x,y,self.activeControlBtn,...) 209 | end 210 | self:FocusControl(activeControl) 211 | self.activeControl = MakeWeakLink(activeControl, self.activeControl) 212 | self.activeControlBtn = btn 213 | return (not not activeControl) 214 | end 215 | 216 | 217 | function Screen:MouseUp(x,y,...) 218 | y = select(2,gl.GetViewSizes()) - y 219 | 220 | local activeControl = UnlinkSafe(self.activeControl) 221 | if activeControl then 222 | local cx,cy = activeControl:ScreenToLocal(x,y) 223 | local now = Spring.GetTimer() 224 | local obj 225 | 226 | local hoveredControl = inherited.IsAbove(self,x,y,...) 227 | 228 | if CompareLinks(hoveredControl, activeControl) then 229 | --//FIXME send this to controls too, when they didn't `return self` in MouseDown! 230 | if (math.abs(x - self._lastClickedX)<3) and 231 | (math.abs(y - self._lastClickedY)<3) and 232 | (Spring.DiffTimers(now,self._lastClicked) < 0.45 ) --FIXME 0.45 := doubleClick time (use spring config?) 233 | then 234 | obj = activeControl:MouseDblClick(cx,cy,...) 235 | end 236 | if (obj == nil) then 237 | obj = activeControl:MouseClick(cx,cy,...) 238 | end 239 | end 240 | self._lastClicked = now 241 | self._lastClickedX = x 242 | self._lastClickedY = y 243 | 244 | obj = activeControl:MouseUp(cx,cy,...) or obj 245 | self.activeControl = nil 246 | return (not not obj) 247 | else 248 | return (not not inherited.MouseUp(self,x,y,...)) 249 | end 250 | end 251 | 252 | 253 | function Screen:MouseMove(x,y,dx,dy,...) 254 | y = select(2,gl.GetViewSizes()) - y 255 | local activeControl = UnlinkSafe(self.activeControl) 256 | if activeControl then 257 | local cx,cy = activeControl:ScreenToLocal(x,y) 258 | local obj = activeControl:MouseMove(cx,cy,dx,-dy,...) 259 | if (obj==false) then 260 | self.activeControl = nil 261 | elseif (not not obj)and(obj ~= activeControl) then 262 | self.activeControl = MakeWeakLink(obj, self.activeControl) 263 | return true 264 | else 265 | return true 266 | end 267 | end 268 | 269 | return (not not inherited.MouseMove(self,x,y,dx,-dy,...)) 270 | end 271 | 272 | 273 | function Screen:MouseWheel(x,y,...) 274 | y = select(2,gl.GetViewSizes()) - y 275 | local activeControl = UnlinkSafe(self.activeControl) 276 | if activeControl then 277 | local cx,cy = activeControl:ScreenToLocal(x,y) 278 | local obj = activeControl:MouseWheel(cx,cy,...) 279 | if not obj then 280 | return false 281 | elseif obj ~= activeControl then 282 | self.activeControl = MakeWeakLink(obj, self.activeControl) 283 | return true 284 | else 285 | return true 286 | end 287 | end 288 | 289 | return (not not inherited.MouseWheel(self,x,y,...)) 290 | end 291 | 292 | 293 | function Screen:KeyPress(...) 294 | local focusedControl = UnlinkSafe(self.focusedControl) 295 | if focusedControl then 296 | return (not not focusedControl:KeyPress(...)) 297 | end 298 | return (not not inherited:KeyPress(...)) 299 | end 300 | 301 | 302 | function Screen:TextInput(...) 303 | local focusedControl = UnlinkSafe(self.focusedControl) 304 | if focusedControl then 305 | return (not not focusedControl:TextInput(...)) 306 | end 307 | return (not not inherited:TextInput(...)) 308 | end 309 | 310 | 311 | --//============================================================================= 312 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/stackpanel.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- StackPanel module 4 | 5 | --- StackPanel fields. 6 | -- Inherits from LayoutPanel. 7 | -- @see layoutpanel.LayoutPanel 8 | -- @table StackPanel 9 | StackPanel = LayoutPanel:Inherit{ 10 | classname = "stackpanel", 11 | orientation = "vertical", 12 | resizeItems = true, 13 | itemPadding = {0, 0, 0, 0}, 14 | itemMargin = {5, 5, 5, 5}, 15 | } 16 | 17 | local this = StackPanel 18 | local inherited = this.inherited 19 | 20 | --//============================================================================= 21 | 22 | function StackPanel:New(obj) 23 | if (obj.orientation=="horizontal") then 24 | obj.rows,obj.columns = 1,nil 25 | else 26 | obj.rows,obj.columns = nil,1 27 | end 28 | obj = inherited.New(self,obj) 29 | return obj 30 | end 31 | 32 | --//============================================================================= 33 | 34 | function StackPanel:SetOrientation(orientation) 35 | if (orientation == "horizontal") then 36 | self.rows,self.columns = 1,nil 37 | else 38 | self.rows,self.columns = nil,1 39 | end 40 | 41 | inherited.SetOrientation(self,orientation) 42 | end 43 | 44 | --//============================================================================= 45 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/tabbar.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | TabBar = LayoutPanel:Inherit{ 4 | classname = "tabbar", 5 | orientation = "horizontal", 6 | resizeItems = false, 7 | centerItems = false, 8 | padding = {0, 0, 0, 0}, 9 | itemPadding = {0, 0, 0, 0}, 10 | itemMargin = {0, 0, 0, 0}, 11 | minItemWidth = 70, 12 | minItemHeight = 20, 13 | tabs = {}, 14 | selected = nil, 15 | OnChange = {}, 16 | } 17 | 18 | local this = TabBar 19 | local inherited = this.inherited 20 | 21 | --//============================================================================= 22 | 23 | function TabBar:New(obj) 24 | obj = inherited.New(self,obj) 25 | if (obj.tabs) then 26 | for i=1,#obj.tabs do 27 | obj:AddChild( 28 | TabBarItem:New{caption = obj.tabs[i], defaultWidth = obj.minItemWidth, defaultHeight = obj.minItemHeight} --FIXME inherit font too 29 | ) 30 | end 31 | end 32 | 33 | if not obj.children[1] then 34 | obj:AddChild( 35 | TabBarItem:New{caption = "tab"} 36 | ) 37 | end 38 | 39 | obj:Select(obj.selected) 40 | 41 | return obj 42 | end 43 | 44 | --//============================================================================= 45 | 46 | function TabBar:SetOrientation(orientation) 47 | inherited.SetOrientation(self,orientation) 48 | end 49 | 50 | --//============================================================================= 51 | 52 | function TabBar:Select(tabname) 53 | for i=1,#self.children do 54 | local c = self.children[i] 55 | if c.caption == tabname then 56 | if self.selected_obj then 57 | self.selected_obj.state.selected = false 58 | self.selected_obj:Invalidate() 59 | end 60 | c.state.selected = true 61 | self.selected_obj = c 62 | c:Invalidate() 63 | self:CallListeners(self.OnChange, tabname) 64 | return true 65 | end 66 | end 67 | 68 | if not self.selected_obj then 69 | local c = self.children[1] 70 | c.state.selected = true 71 | self.selected_obj = c 72 | self.selected_obj:Invalidate() 73 | self:CallListeners(self.OnChange, c.caption) 74 | end 75 | 76 | return false 77 | end 78 | 79 | 80 | function TabBar:Remove(tabname) 81 | if #self.children < 2 then 82 | return false 83 | end 84 | 85 | for i = 1, #self.children do 86 | local c = self.children[i] 87 | if c.caption == tabname then 88 | c:Dispose() 89 | -- selects next tab 90 | c = self.children[math.min(i, #self.children)] 91 | self:Select(c.caption) 92 | return true 93 | end 94 | end 95 | 96 | return false 97 | end 98 | --//============================================================================= 99 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/tabbaritem.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | TabBarItem = Button:Inherit{ 4 | classname= "tabbaritem", 5 | caption = 'tab', 6 | height = "100%", 7 | } 8 | 9 | local this = TabBarItem 10 | local inherited = this.inherited 11 | 12 | --//============================================================================= 13 | 14 | function TabBarItem:SetCaption(caption) 15 | --FIXME inform parent 16 | if (self.caption == caption) then return end 17 | self.caption = caption 18 | self:Invalidate() 19 | end 20 | 21 | --//============================================================================= 22 | 23 | function TabBarItem:MouseDown(...) 24 | if not self.parent then return end 25 | self.parent:Select(self.caption) 26 | inherited.MouseDown(self, ...) 27 | return self 28 | end 29 | 30 | --//============================================================================= 31 | 32 | function TabBarItem:Remove() 33 | if not self.parent then return end 34 | self.parent:Remove(self.caption) 35 | return self 36 | end 37 | 38 | --//============================================================================= 39 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/tabpanel.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- TabPanel module 4 | 5 | --- TabPanel fields. 6 | -- Inherits from LayoutPanel. 7 | -- @see layoutpanel.LayoutPanel 8 | -- @table TabPanel 9 | -- @tparam {tab1,tab2,...} tabs contained in the tab panel, each tab has a .name (string) and a .children field (table of Controls)(default {}) 10 | -- @tparam chili.Control currentTab currently visible tab 11 | TabPanel = LayoutPanel:Inherit{ 12 | classname = "tabpanel", 13 | orientation = "vertical", 14 | resizeItems = false, 15 | itemPadding = {0, 0, 0, 0}, 16 | itemMargin = {0, 0, 0, 0}, 17 | barHeight = 40, 18 | tabs = {}, 19 | currentTab = {}, 20 | } 21 | 22 | local this = TabPanel 23 | local inherited = this.inherited 24 | 25 | --//============================================================================= 26 | 27 | function TabPanel:New(obj) 28 | obj = inherited.New(self,obj) 29 | 30 | local tabNames = {} 31 | for i=1,#obj.tabs do 32 | tabNames[i] = obj.tabs[i].name 33 | end 34 | obj:AddChild( 35 | TabBar:New { 36 | tabs = tabNames, 37 | x = 0, 38 | y = 0, 39 | right = 0, 40 | height = obj.barHeight, 41 | } 42 | ) 43 | 44 | obj.currentTab = Control:New { 45 | x = 0, 46 | y = obj.barHeight, 47 | right = 0, 48 | bottom = 0, 49 | padding = {0, 0, 0, 0}, 50 | } 51 | obj:AddChild(obj.currentTab) 52 | obj.tabIndexMapping = {} 53 | for i=1, #obj.tabs do 54 | local tabName = obj.tabs[i].name 55 | local tabFrame = Control:New { 56 | padding = {0, 0, 0, 0}, 57 | x = 0, 58 | y = 0, 59 | right = 0, 60 | bottom = 0, 61 | children = obj.tabs[i].children 62 | } 63 | obj.tabIndexMapping[tabName] = tabFrame 64 | obj.currentTab:AddChild(tabFrame) 65 | if i == 1 then 66 | obj.currentFrame = tabFrame 67 | else 68 | tabFrame:SetVisibility(false) 69 | end 70 | end 71 | obj.children[1].OnChange = { function(tabbar, tabname) obj:ChangeTab(tabname) end } 72 | return obj 73 | end 74 | 75 | function TabPanel:AddTab(tab) 76 | local tabbar = self.children[1] 77 | tabbar:AddChild( 78 | TabBarItem:New{caption = tab.name, defaultWidth = tabbar.minItemWidth, defaultHeight = tabbar.minItemHeight} --FIXME: implement an "Add Tab in TabBar too" 79 | ) 80 | local tabFrame = Control:New { 81 | padding = {0, 0, 0, 0}, 82 | x = 0, 83 | y = 0, 84 | right = 0, 85 | bottom = 0, 86 | children = tab.children 87 | } 88 | self.tabIndexMapping[tab.name] = tabFrame 89 | self.currentTab:AddChild(tabFrame) 90 | tabFrame:SetVisibility(false) 91 | end 92 | 93 | --//============================================================================= 94 | 95 | function TabPanel:ChangeTab(tabname) 96 | if not tabname or not self.tabIndexMapping[tabname] then 97 | return 98 | end 99 | self.currentFrame:SetVisibility(false) 100 | self.currentFrame = self.tabIndexMapping[tabname] 101 | self.currentFrame:SetVisibility(true) 102 | end 103 | --//============================================================================= 104 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/textbox.lua: -------------------------------------------------------------------------------- 1 | --- TextBox module 2 | 3 | --- TextBox fields. 4 | -- Inherits from Control. 5 | -- @see control.Control 6 | -- @table TextBox 7 | -- @string[opt=""] text text contained in the editbox 8 | -- @bool[opt=true] autoHeight sets height to text size, useful for embedding in scrollboxes 9 | -- @bool[opt=true] autoObeyLineHeight (needs autoHeight) if true, autoHeight will obey the lineHeight (-> texts with the same line count will have the same height) 10 | -- @int[opt=12] fontSize font size 11 | TextBox = Control:Inherit{ 12 | classname = "textbox", 13 | 14 | padding = {0,0,0,0}, 15 | 16 | text = "line1\nline2", 17 | autoHeight = true, 18 | autoObeyLineHeight = true, 19 | fontsize = 12, 20 | 21 | _lines = {}, 22 | } 23 | 24 | local this = TextBox 25 | local inherited = this.inherited 26 | 27 | -------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- 29 | 30 | --- Set text 31 | -- @string t sets the text 32 | function TextBox:SetText(t) 33 | if (self.text == t) then 34 | return 35 | end 36 | self.text = t 37 | self:RequestRealign() 38 | self:Invalidate() -- seems RequestRealign() doesn't always cause an invalidate 39 | end 40 | 41 | -------------------------------------------------------------------------------- 42 | -------------------------------------------------------------------------------- 43 | 44 | local function Split(s, separator) 45 | local results = {} 46 | for part in s:gmatch("[^"..separator.."]+") do 47 | results[#results + 1] = part 48 | end 49 | return results 50 | end 51 | 52 | -- remove first n elemets from t, return them 53 | local function Take(t, n) 54 | local removed = {} 55 | for i=1, n do 56 | removed[#removed+1] = table.remove(t, 1) 57 | end 58 | return removed 59 | end 60 | 61 | -- appends t1 to t2 in-place 62 | local function Append(t1, t2) 63 | local l = #t1 64 | for i = 1, #t2 do 65 | t1[i + l] = t2[i] 66 | end 67 | end 68 | 69 | -------------------------------------------------------------------------------- 70 | -------------------------------------------------------------------------------- 71 | 72 | function TextBox:UpdateLayout() 73 | local font = self.font 74 | local padding = self.padding 75 | local width = self.width - padding[1] - padding[3] 76 | local height = self.height - padding[2] - padding[4] 77 | if self.autoHeight then 78 | height = 1e9 79 | end 80 | 81 | self._wrappedText = font:WrapText(self.text, width, height) 82 | 83 | if self.autoHeight then 84 | local textHeight,textDescender,numLines = font:GetTextHeight(self._wrappedText) 85 | textHeight = textHeight-textDescender 86 | 87 | if (self.autoObeyLineHeight) then 88 | if (numLines>1) then 89 | textHeight = numLines * font:GetLineHeight() 90 | else 91 | --// AscenderHeight = LineHeight w/o such deep chars as 'g','p',... 92 | textHeight = math.min( math.max(textHeight, font:GetAscenderHeight()), font:GetLineHeight()) 93 | end 94 | end 95 | 96 | self:Resize(nil, textHeight, true, true) 97 | end 98 | end 99 | 100 | 101 | function TextBox:DrawControl() 102 | local paddx, paddy = unpack4(self.clientArea) 103 | local x = paddx 104 | local y = paddy 105 | 106 | local font = self.font 107 | font:Draw(self._wrappedText, x, y) 108 | 109 | if (self.debug) then 110 | gl.Color(0,1,0,0.5) 111 | gl.PolygonMode(GL.FRONT_AND_BACK,GL.LINE) 112 | gl.LineWidth(2) 113 | gl.Rect(0,0,self.width,self.height) 114 | gl.LineWidth(1) 115 | gl.PolygonMode(GL.FRONT_AND_BACK,GL.FILL) 116 | end 117 | end 118 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/trackbar.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- Trackbar module 4 | 5 | --- Trackbar fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table Trackbar 9 | -- @int[opt=0] min minimum value of the Trackbar 10 | -- @int[opt=100] max maximum value of the Trackbar 11 | -- @int[opt=50] value value of the Trackbar 12 | -- @int[opt=50] step step value 13 | -- @tparam {func1,fun2,...} OnChange function listeners for value change (default {}) 14 | Trackbar = Control:Inherit{ 15 | classname = "trackbar", 16 | value = 50, 17 | min = 0, 18 | max = 100, 19 | step = 1, 20 | useValueTooltip = nil, 21 | 22 | defaultWidth = 90, 23 | defaultHeight = 20, 24 | 25 | hitpadding = {0, 0, 0, 0}, 26 | 27 | OnChange = {}, 28 | } 29 | 30 | local this = Trackbar 31 | local inherited = this.inherited 32 | 33 | --//============================================================================= 34 | 35 | local function FormatNum(num) 36 | if (num == 0) then 37 | return "0" 38 | else 39 | local strFormat = string.format 40 | local absNum = math.abs(num) 41 | if (absNum < 0.01) then 42 | return strFormat("%.3f", num) 43 | elseif (absNum < 1) then 44 | return strFormat("%.2f", num) 45 | elseif (absNum < 10) then 46 | return strFormat("%.1f", num) 47 | else 48 | return strFormat("%.0f", num) 49 | end 50 | end 51 | end 52 | 53 | 54 | function Trackbar:New(obj) 55 | obj = inherited.New(self,obj) 56 | 57 | if ((not obj.tooltip) or (obj.tooltip == '')) and (obj.useValueTooltip ~= false) then 58 | obj.useValueTooltip = true 59 | end 60 | 61 | obj:SetMinMax(obj.min,obj.max) 62 | obj:SetValue(obj.value) 63 | 64 | return obj 65 | end 66 | 67 | --//============================================================================= 68 | 69 | function Trackbar:_Clamp(v) 70 | if (self.minself.max) then 74 | v = self.max 75 | end 76 | else 77 | if (v>self.min) then 78 | v = self.min 79 | elseif (vself.width-pr) then 95 | return 1 96 | end 97 | 98 | local cx = x - pl 99 | local barWidth = self.width - (pl + pr) 100 | 101 | return (cx/barWidth) 102 | else 103 | return (self.value-self.min)/(self.max-self.min) 104 | end 105 | end 106 | 107 | --//============================================================================= 108 | 109 | --- Sets the minimum and maximum value of the track bar 110 | -- @int[opt=0] min minimum value 111 | -- @int[opt=1] max maximum value (why is 1 the default?) 112 | function Trackbar:SetMinMax(min,max) 113 | self.min = tonumber(min) or 0 114 | self.max = tonumber(max) or 1 115 | self:SetValue(self.value) 116 | end 117 | 118 | 119 | --- Sets the value of the track bar 120 | -- @int v value of the track abr 121 | function Trackbar:SetValue(v) 122 | if type(v) ~= "number" then 123 | Spring.Log("Chili", "error", "Wrong param to Trackbar:SetValue(number v)") 124 | return 125 | end 126 | local r = v % self.step 127 | if (r > 0.5*self.step) then 128 | v = v + self.step - r 129 | else 130 | v = v - r 131 | end 132 | v = self:_Clamp(v) 133 | local oldvalue = self.value 134 | self.value = v 135 | if self.useValueTooltip then 136 | self.tooltip = "Current: "..FormatNum(self.value) 137 | end 138 | self:CallListeners(self.OnChange,v,oldvalue) 139 | self:Invalidate() 140 | end 141 | 142 | --//============================================================================= 143 | 144 | function Trackbar:DrawControl() 145 | end 146 | 147 | --//============================================================================= 148 | 149 | function Trackbar:HitTest() 150 | return self 151 | end 152 | 153 | function Trackbar:MouseDown(x,y,button) 154 | if (button==1) then 155 | inherited.MouseDown(self,x,y) 156 | local percent = self:_GetPercent(x,y) 157 | self:SetValue(self.min + percent*(self.max-self.min)) 158 | end 159 | return self 160 | end 161 | 162 | function Trackbar:MouseMove(x,y,dx,dy,button) 163 | if (button==1) then 164 | inherited.MouseMove(self,x,y,dx,dy,button) 165 | local percent = self:_GetPercent(x,y) 166 | self:SetValue(self.min + percent*(self.max-self.min)) 167 | end 168 | return self 169 | end 170 | 171 | --//============================================================================= 172 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/treeview.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | --- TreeView module 4 | 5 | --- TreeView fields. 6 | -- Inherits from Control. 7 | -- @see control.Control 8 | -- @table TreeView 9 | -- @bool[opt=true] autosize whether size is automatically determined 10 | -- @int[opt=1] selected selected item 11 | -- @tparam {TreeNode1,TreeNode2,...} nodes nodes of the tree 12 | -- @tparam {func1,fun2,...} OnSelectNode function listeners for node selection (default {}) 13 | TreeView = Control:Inherit{ 14 | classname = "treeview", 15 | 16 | autosize = true, 17 | 18 | minItemHeight = 16, 19 | 20 | defaultWidth = "100%", 21 | defaultHeight = "100%", 22 | 23 | selected = 1, 24 | root = nil, 25 | nodes = {}, 26 | 27 | defaultExpanded = false, 28 | 29 | OnSelectNode = {}, 30 | } 31 | 32 | local this = TreeView 33 | local inherited = this.inherited 34 | 35 | --//============================================================================= 36 | 37 | local function ParseInitTable(node, nodes) 38 | local lastnode = node 39 | for i=1,#nodes do 40 | local data = nodes[i] 41 | if (type(data)=="table") then 42 | ParseInitTable(lastnode, data) 43 | else 44 | lastnode = node:Add(data) 45 | end 46 | end 47 | end 48 | 49 | 50 | function TreeView:New(obj) 51 | local nodes = obj.nodes 52 | if (nodes) then 53 | obj.children = {} 54 | end 55 | 56 | obj = inherited.New(self,obj) 57 | 58 | obj.root = TreeViewNode:New{treeview = obj, root = true; minHeight = obj.minItemHeight; expanded = obj.defaultExpanded} 59 | if (nodes) then 60 | ParseInitTable(obj.root, nodes) 61 | end 62 | obj:AddChild(obj.root) 63 | 64 | obj:UpdateLayout() 65 | 66 | local sel = obj.selected 67 | obj.selected = false 68 | if ((sel or 0)>0) then 69 | obj:Select(sel) 70 | end 71 | 72 | return obj 73 | end 74 | 75 | --//============================================================================= 76 | 77 | function TreeView:GetNodeByCaption(caption) 78 | return self.root:GetNodeByCaption(caption) 79 | end 80 | 81 | 82 | function TreeView:GetNodeByIndex(index) 83 | local result = self.root:GetNodeByIndex(index, 0) 84 | return (not IsNumber(result)) and result 85 | end 86 | 87 | --//============================================================================= 88 | 89 | function TreeView:Select(item) 90 | local obj = UnlinkSafe(item) 91 | 92 | if (type(item) == "number") then 93 | obj = self:GetNodeByIndex(item) 94 | end 95 | 96 | if (obj and obj:InheritsFrom("treeviewnode")) then 97 | local oldSelected = self.selected 98 | self.selected = MakeWeakLink(obj) 99 | self.selected:Invalidate() 100 | if (oldSelected) then 101 | oldSelected:Invalidate() 102 | end 103 | 104 | obj:CallListeners(obj.OnSelectChange, true) 105 | if (oldSelected) then oldSelected:CallListeners(oldSelected.OnSelectChange, false) end 106 | self:CallListeners(self.OnSelectNode, self.selected, oldSelected) 107 | end 108 | end 109 | 110 | --//============================================================================= 111 | 112 | function TreeView:UpdateLayout() 113 | local c = self.root 114 | c:_UpdateConstraints(0, 0, self.clientWidth) 115 | c:Realign() 116 | 117 | if (self.autosize) then 118 | self:Resize(nil, c.height, true, true) 119 | end 120 | 121 | return true 122 | end 123 | 124 | --//============================================================================= 125 | -------------------------------------------------------------------------------- /luaui/chili/chili/controls/treeviewnode.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | TreeViewNode = Control:Inherit{ 4 | classname = "treeviewnode", 5 | 6 | padding = {16,0,0,0}, 7 | 8 | autosize = true, 9 | caption = "node", 10 | expanded = true, 11 | 12 | root = false, 13 | nodes = {}, 14 | 15 | treeview = nil, 16 | 17 | _nodes_hidden = {}, 18 | 19 | OnSelectChange = {}, 20 | OnCollapse = {}, 21 | OnExpand = {}, 22 | OnDraw = {}, 23 | } 24 | 25 | local this = TreeViewNode 26 | local inherited = this.inherited 27 | 28 | --//============================================================================= 29 | 30 | function TreeViewNode:New(obj) 31 | if (obj.root) then 32 | obj.padding = {0,0,0,0} 33 | end 34 | 35 | assert(obj.treeview) 36 | obj.treeview = MakeWeakLink(obj.treeview) 37 | obj = inherited.New(self,obj) 38 | return obj 39 | end 40 | 41 | 42 | function TreeViewNode:SetParent(obj) 43 | obj = UnlinkSafe(obj) 44 | local typ = type(obj) 45 | 46 | if (typ ~= "table") then 47 | self.treeview = nil --FIXME code below in this file doesn't check for nil! 48 | end 49 | 50 | inherited.SetParent(self, obj) 51 | end 52 | 53 | 54 | function TreeViewNode:AddChild(obj, isNode) 55 | if (isNode~=false) then 56 | self.nodes[#self.nodes+1] = MakeWeakLink(obj) 57 | end 58 | if self.parent and self.parent.RequestRealign then self.parent:RequestRealign() end 59 | return inherited.AddChild(self,obj) 60 | end 61 | 62 | 63 | function TreeViewNode:RemoveChild(obj) 64 | local result = inherited.RemoveChild(self,obj) 65 | 66 | local nodes = self.nodes 67 | for i=1,#nodes do 68 | if CompareLinks(nodes[i],obj) then 69 | table.remove(nodes, i) 70 | return result 71 | end 72 | end 73 | 74 | return result 75 | end 76 | 77 | 78 | function TreeViewNode:ClearChildren() 79 | local caption 80 | if not(self.root) then 81 | caption = self.children[1] 82 | self.children[1] = self.children[#self.children] 83 | self.children[#self.children] = nil 84 | end 85 | 86 | local collapsed = not self.expanded 87 | self:Expand() 88 | inherited.ClearChildren(self) 89 | if (collapsed) then self:Collapse() end 90 | 91 | if not(self.root) then 92 | self.children[1] = caption 93 | end 94 | end 95 | 96 | TreeViewNode.Clear = TreeViewNode.ClearChildren 97 | 98 | --//============================================================================= 99 | 100 | function TreeViewNode:Add(item) 101 | local newnode 102 | if (type(item) == "string") then 103 | local lbl = TextBox:New{text = item; width = "100%"; padding = {2,3,2,2}; minHeight = self.minHeight;} 104 | newnode = TreeViewNode:New{caption = item; treeview = self.treeview; minHeight = self.minHeight; expanded = self.expanded;} 105 | newnode:AddChild(lbl, false) 106 | self:AddChild(newnode) 107 | elseif (IsObject(item)) then 108 | newnode = TreeViewNode:New{caption = ""; treeview = self.treeview; minHeight = self.minHeight; expanded = self.expanded;} 109 | newnode:AddChild(item, false) 110 | self:AddChild(newnode) 111 | end 112 | return newnode 113 | end 114 | 115 | 116 | function TreeViewNode:Select() 117 | if (self.root)or(not self.treeview) then 118 | return 119 | end 120 | 121 | if (not CompareLinks(self.treeview.selected,self)) then 122 | --// treeview itself calls node:OnSelectChange ! 123 | self.treeview:Select(self) 124 | end 125 | end 126 | 127 | 128 | function TreeViewNode:Toggle() 129 | if (self.root)or(not self.treeview) then 130 | return 131 | end 132 | 133 | if (self.expanded) then 134 | self:Collapse() 135 | else 136 | self:Expand() 137 | end 138 | end 139 | 140 | 141 | function TreeViewNode:Expand() 142 | if (self.root)or(not self.treeview) then 143 | return 144 | end 145 | 146 | self:CallListeners(self.OnExpand) 147 | self.expanded = true 148 | self.treeview:RequestRealign() 149 | 150 | for i=#self._nodes_hidden, 1, -1 do 151 | local c = self._nodes_hidden[i] 152 | self.children[#self.children + 1] = c 153 | end 154 | 155 | for i=#self._nodes_hidden, 1, -1 do 156 | self._nodes_hidden[i] = nil 157 | end 158 | end 159 | 160 | 161 | function TreeViewNode:Collapse() 162 | if (self.root)or(not self.treeview) then 163 | return 164 | end 165 | 166 | self:CallListeners(self.OnCollapse) 167 | self.expanded = false 168 | self.treeview:RequestRealign() 169 | 170 | for i=#self.children, 2, -1 do 171 | local c = self.children[i] 172 | self.children[i] = nil 173 | self._nodes_hidden[#self._nodes_hidden + 1] = c 174 | end 175 | end 176 | 177 | --//============================================================================= 178 | 179 | function TreeViewNode:GetNodeByCaption(caption) 180 | for i=1,#self.nodes do 181 | local n = self.nodes[i] 182 | if (n.caption == caption) then 183 | return n 184 | end 185 | 186 | local result = n:GetNodeByCaption(caption) 187 | if (result) then 188 | return result 189 | end 190 | end 191 | end 192 | 193 | function TreeViewNode:GetNodeByIndex(index, _i) 194 | for i=1,#self.nodes do 195 | _i = _i + 1 196 | if (_i == index) then 197 | return self.nodes[i] 198 | end 199 | 200 | local result = self.nodes[i]:GetNodeByIndex(index, _i) 201 | if (IsNumber(result)) then 202 | _i = result 203 | else 204 | return result 205 | end 206 | end 207 | 208 | return _i 209 | end 210 | 211 | --//============================================================================= 212 | 213 | function TreeViewNode:UpdateLayout() 214 | local clientWidth = self.clientWidth 215 | local children = self.children 216 | 217 | if (not self.expanded)and(not self.root) then 218 | if (children[1]) then 219 | local c = children[1] 220 | c:_UpdateConstraints(0, 0, clientWidth) 221 | c:Realign() 222 | self:Resize(nil, c.height, true, true) 223 | else 224 | self:Resize(nil, 10, true, true) 225 | end 226 | 227 | return true 228 | end 229 | 230 | 231 | local y = 0 232 | for i=1, #children do 233 | local c = children[i] 234 | c:_UpdateConstraints(0, y, clientWidth) 235 | c:Realign() 236 | y = y + c.height 237 | end 238 | 239 | self:Resize(nil, y, true, true) 240 | return true 241 | end 242 | 243 | --//============================================================================= 244 | 245 | function TreeViewNode:_InNodeButton(x,y) 246 | if (self.root) then 247 | return false 248 | end 249 | 250 | if (x>=self.padding[1]) then 251 | return false 252 | end 253 | 254 | local nodeTop = (self.children[1].height - self.padding[1])*0.5 255 | return (nodeTop<=y)and(y-nodeTop fail 274 | if (self:_InNodeButton(x,y)) then 275 | return self 276 | end 277 | 278 | if (x>=self.padding[1])then 279 | --[[ FIXME inherited.MouseDown should be executed before Select()! 280 | local obj = inherited.MouseDown(self, x, y, ...) 281 | return obj 282 | --]] 283 | 284 | if (y < self.padding[2]+self.children[1].height) then 285 | self:Select() 286 | end 287 | 288 | local obj = inherited.MouseDown(self, x, y, ...) 289 | return obj 290 | end 291 | end 292 | 293 | 294 | function TreeViewNode:MouseClick(x,y, ...) 295 | if (self.root) then 296 | return inherited.MouseClick(self, x, y, ...) 297 | end 298 | 299 | if (self:_InNodeButton(x,y)) then 300 | self:Toggle() 301 | return self 302 | end 303 | 304 | local obj = inherited.MouseClick(self, x, y, ...) 305 | return obj 306 | end 307 | 308 | 309 | function TreeViewNode:MouseDblClick(x,y, ...) 310 | --//FIXME doesn't get called, related to the FIXME above! 311 | if (self.root) then 312 | return inherited.MouseDblClick(self, x, y, ...) 313 | end 314 | 315 | local obj = inherited.MouseDblClick(self, x, y, ...) 316 | if (not obj) then 317 | self:Toggle() 318 | obj = self 319 | end 320 | 321 | return obj 322 | end 323 | 324 | --//============================================================================= 325 | 326 | function TreeViewNode:DrawNode() 327 | if (self.treeview) then 328 | self.treeview.DrawNode(self) 329 | end 330 | end 331 | 332 | 333 | function TreeViewNode:DrawNodeTree() 334 | if (self.treeview) then 335 | self.treeview.DrawNodeTree(self) 336 | end 337 | end 338 | 339 | 340 | function TreeViewNode:DrawControl() 341 | if (self.root) then 342 | return 343 | end 344 | 345 | local dontDraw = self:CallListeners(self.OnDraw, self) 346 | if (not dontDraw) then 347 | self:DrawNode() 348 | end 349 | self:DrawNodeTree() 350 | end 351 | 352 | 353 | function TreeViewNode:DrawChildren() 354 | if not (self.expanded or self.root) then 355 | self:_DrawInClientArea(self.children[1].Draw,self.children[1]) 356 | return 357 | end 358 | 359 | if (next(self.children)) then 360 | self:_DrawChildrenInClientArea('Draw') 361 | end 362 | end 363 | 364 | 365 | function TreeViewNode:DrawChildrenForList() 366 | if not (self.expanded or self.root) then 367 | self:_DrawInClientArea(self.children[1].DrawForList,self.children[1]) 368 | return 369 | end 370 | 371 | if (next(self.children)) then 372 | self:_DrawChildrenInClientArea('DrawForList') 373 | end 374 | end 375 | 376 | --//============================================================================= -------------------------------------------------------------------------------- /luaui/chili/chili/controls/window.lua: -------------------------------------------------------------------------------- 1 | --- Window module 2 | 3 | --- Window fields. 4 | -- Inherits from Control. 5 | -- @see control.Control 6 | -- @table Window 7 | Window = Control:Inherit{ 8 | classname = 'window', 9 | resizable = true, 10 | draggable = true, 11 | 12 | minWidth = 50, 13 | minHeight = 50, 14 | defaultWidth = 400, 15 | defaultHeight = 300, 16 | } 17 | 18 | local this = Window 19 | local inherited = this.inherited 20 | 21 | --//============================================================================= 22 | --[[ 23 | function Window:UpdateClientArea() 24 | inherited.UpdateClientArea(self) 25 | 26 | if (not WG['blur_api']) then return end 27 | 28 | if (self.blurId) then 29 | WG['blur_api'].RemoveBlurRect(self.blurId) 30 | end 31 | 32 | local screeny = select(2,gl.GetViewSizes()) - self.y 33 | 34 | self.blurId = WG['blur_api'].InsertBlurRect(self.x,screeny,self.x+self.width,screeny-self.height) 35 | end 36 | --]] 37 | --//============================================================================= 38 | 39 | function Window:New(obj) 40 | obj = inherited.New(self,obj) 41 | obj:BringToFront() 42 | return obj 43 | end 44 | 45 | function Window:DrawControl() 46 | --// gets overriden by the skin/theme 47 | end 48 | 49 | function Window:MouseDown(...) 50 | self:BringToFront() 51 | return inherited.MouseDown(self,...) 52 | end 53 | 54 | VFS.Include(CHILI_DIRNAME .. "headers/skinutils.lua", nil, VFS.RAW_FIRST) 55 | 56 | function Window:TweakDraw() 57 | gl.Color(0.6,1,0.6,0.65) 58 | 59 | local w = self.width 60 | local h = self.height 61 | 62 | if (self.resizable or self.tweakResizable) then 63 | TextureHandler.LoadTexture(0,"LuaUI/Widgets/chili/skins/default/tweak_overlay_resizable.png",self) 64 | else 65 | TextureHandler.LoadTexture(0,"LuaUI/Widgets/chili/skins/default/tweak_overlay.png",self) 66 | end 67 | local texInfo = gl.TextureInfo("LuaUI/Widgets/chili/skins/default/tweak_overlay.png") or {xsize=1, ysize=1} 68 | local tw,th = texInfo.xsize, texInfo.ysize 69 | 70 | gl.BeginEnd(GL.TRIANGLE_STRIP, _DrawTiledTexture, self.x,self.y,w,h, 31,31,31,31, tw,th, 0) 71 | gl.Texture(0,false) 72 | end 73 | -------------------------------------------------------------------------------- /luaui/chili/chili/core.lua: -------------------------------------------------------------------------------- 1 | local includes = { 2 | --"headers/autolocalizer.lua", 3 | "headers/util.lua", 4 | "headers/links.lua", 5 | "headers/backwardcompability.lua", 6 | "headers/unicode.lua", 7 | 8 | "handlers/debughandler.lua", 9 | "handlers/taskhandler.lua", 10 | "handlers/skinhandler.lua", 11 | "handlers/themehandler.lua", 12 | "handlers/fonthandler.lua", 13 | "handlers/texturehandler.lua", 14 | 15 | "controls/object.lua", 16 | "controls/font.lua", 17 | "controls/control.lua", 18 | "controls/screen.lua", 19 | "controls/window.lua", 20 | "controls/label.lua", 21 | "controls/button.lua", 22 | "controls/textbox.lua", 23 | "controls/checkbox.lua", 24 | "controls/trackbar.lua", 25 | "controls/colorbars.lua", 26 | "controls/scrollpanel.lua", 27 | "controls/image.lua", 28 | "controls/textbox.lua", 29 | "controls/layoutpanel.lua", 30 | "controls/grid.lua", 31 | "controls/stackpanel.lua", 32 | "controls/imagelistview.lua", 33 | "controls/progressbar.lua", 34 | "controls/multiprogressbar.lua", 35 | "controls/scale.lua", 36 | "controls/panel.lua", 37 | "controls/treeviewnode.lua", 38 | "controls/treeview.lua", 39 | "controls/editbox.lua", 40 | "controls/line.lua", 41 | "controls/combobox.lua", 42 | "controls/tabbaritem.lua", 43 | "controls/tabbar.lua", 44 | "controls/tabpanel.lua", 45 | } 46 | 47 | local Chili = widget 48 | 49 | Chili.CHILI_DIRNAME = CHILI_DIRNAME or (LUAUI_DIRNAME .. "Widgets/chili/") 50 | Chili.SKIN_DIRNAME = SKIN_DIRNAME or (CHILI_DIRNAME .. "skins/") 51 | 52 | if (-1>0) then 53 | Chili = {} 54 | -- make the table strict 55 | VFS.Include(Chili.CHILI_DIRNAME .. "headers/strict.lua")(Chili, widget) 56 | end 57 | 58 | for _, file in ipairs(includes) do 59 | VFS.Include(Chili.CHILI_DIRNAME .. file, Chili, VFS.RAW_FIRST) 60 | end 61 | 62 | 63 | return Chili 64 | -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/backwardcompability.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// 3 | 4 | function BackwardCompa(obj) 5 | obj.font = obj.font or {} 6 | obj.font.outline = obj.font.outline or obj.fontOutline 7 | obj.font.color = obj.font.color or obj.captionColor 8 | obj.font.color = obj.font.color or obj.textColor 9 | obj.font.size = obj.font.size or obj.fontSize 10 | obj.font.size = obj.font.size or obj.fontsize 11 | obj.font.shadow = obj.font.shadow or obj.fontShadow 12 | obj.fontOutline = nil 13 | obj.textColor = nil 14 | obj.captionColor = nil 15 | obj.fontSize = nil 16 | obj.fontsize = nil 17 | obj.fontShadow = nil 18 | 19 | local minimumSize = obj.minimumSize or {} 20 | obj.minWidth = obj.minWidth or minimumSize[1] 21 | obj.minHeight = obj.minHeight or minimumSize[2] 22 | end 23 | -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/fonthandler.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// FontSystem 3 | 4 | FontHandler = {} 5 | 6 | 7 | --//============================================================================= 8 | --// cache loaded fonts 9 | 10 | local loadedFonts = {} 11 | local refCounts = {} 12 | 13 | --// maximum fontsize difference 14 | --// when we don't find the wanted font rendered with the wanted fontsize 15 | --// (in respect to this threshold) then recreate a new one 16 | local fontsize_threshold = 2 17 | 18 | --//============================================================================= 19 | --// Destroy 20 | 21 | FontHandler._scream = Script.CreateScream() 22 | FontHandler._scream.func = function() 23 | for i=1,#loadedFonts do 24 | gl.DeleteFont(loadedFonts[i]) 25 | end 26 | loadedFonts = {} 27 | end 28 | 29 | 30 | local n = 0 31 | function FontHandler.Update() 32 | n = n + 1 33 | if (n <= 100) then 34 | return 35 | end 36 | n = 0 37 | 38 | local last_idx = #loadedFonts 39 | for i=last_idx, 1, -1 do 40 | if (refCounts[i] <= 0) then 41 | --// the font isn't in use anymore, free it 42 | gl.DeleteFont(loadedFonts[i]) 43 | loadedFonts[i] = loadedFonts[last_idx] 44 | loadedFonts[last_idx] = nil 45 | refCounts[i] = refCounts[last_idx] 46 | refCounts[last_idx] = nil 47 | last_idx = last_idx - 1 48 | end 49 | end 50 | end 51 | 52 | --//============================================================================= 53 | --// API 54 | 55 | function FontHandler.UnloadFont(font) 56 | for i=1,#loadedFonts do 57 | local font2 = loadedFonts[i] 58 | if (font == font2) then 59 | refCounts[i] = refCounts[i] - 1 60 | return 61 | end 62 | end 63 | end 64 | 65 | function FontHandler.LoadFont(fontname,size,outwidth,outweight) 66 | for i=1,#loadedFonts do 67 | local font = loadedFonts[i] 68 | if 69 | ((font.path == fontname)or(font.path == 'fonts/'..fontname)) 70 | and(font.size - size >= 0) and (font.size - size <= fontsize_threshold) 71 | and((not outwidth)or(font.outlinewidth == outwidth)) 72 | and((not outweight)or(font.outlineweight == outweight)) 73 | then 74 | refCounts[i] = refCounts[i] + 1 75 | return font 76 | end 77 | end 78 | 79 | local idx = #loadedFonts+1 80 | local font = gl.LoadFont(fontname,size,outwidth,outweight) 81 | loadedFonts[idx] = font 82 | refCounts[idx] = 1 83 | return font 84 | end -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/skinhandler.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// Theme 3 | 4 | SkinHandler = {} 5 | 6 | --//============================================================================= 7 | --// load shared skin utils 8 | 9 | local SkinUtilsEnv = {} 10 | setmetatable(SkinUtilsEnv,{__index = getfenv()}) 11 | VFS.Include(CHILI_DIRNAME .. "headers/skinutils.lua", SkinUtilsEnv) 12 | 13 | --//============================================================================= 14 | --// translates the skin's FileNames to the correct FilePaths 15 | --// (skins just define the name not the path!) 16 | 17 | local function SplitImageOptions(str) 18 | local options, str2 = str:match "^(:.*:)(.*)" 19 | if (options) then 20 | return options, str2 21 | else 22 | return "", str 23 | end 24 | end 25 | 26 | local function TranslateFilePaths(skinConfig, dirs) 27 | for i,v in pairs(skinConfig) do 28 | if (i == "info") then 29 | --// nothing 30 | elseif istable(v) then 31 | TranslateFilePaths(v, dirs) 32 | elseif isstring(v) then 33 | local opt, fileName = SplitImageOptions(v) 34 | 35 | for _,dir in ipairs(dirs) do 36 | local filePath = dir .. fileName 37 | if VFS.FileExists(filePath) then 38 | skinConfig[i] = opt .. filePath 39 | break 40 | end 41 | end 42 | 43 | end 44 | end 45 | end 46 | 47 | --//============================================================================= 48 | --// load all skins 49 | 50 | knownSkins = {} 51 | SkinHandler.knownSkins = knownSkins 52 | 53 | local n = 1 54 | local skinDirs = VFS.SubDirs(SKIN_DIRNAME , "*", VFS.RAW_FIRST) 55 | for i,dir in ipairs(skinDirs) do 56 | local skinCfgFile = dir .. 'skin.lua' 57 | 58 | if (VFS.FileExists(skinCfgFile, VFS.RAW_FIRST)) then 59 | 60 | --// use a custom enviroment (safety + auto loads skin utils) 61 | local senv = {SKINDIR = dir} 62 | setmetatable(senv,{__index = SkinUtilsEnv}) 63 | 64 | --// load the skin 65 | local skinConfig = VFS.Include(skinCfgFile,senv, VFS.RAW_FIRST) 66 | if (skinConfig)and(type(skinConfig)=="table")and(type(skinConfig.info)=="table") then 67 | skinConfig.info.dir = dir 68 | SkinHandler.knownSkins[n] = skinConfig 69 | SkinHandler.knownSkins[skinConfig.info.name:lower()] = skinConfig 70 | n = n + 1 71 | end 72 | end 73 | end 74 | 75 | --//FIXME handle multiple-dependencies correctly! (atm it just works with 1 level!) 76 | --// translate filepaths and handle dependencies 77 | for i,skinConfig in ipairs(SkinHandler.knownSkins) do 78 | local dirs = { skinConfig.info.dir } 79 | 80 | --// translate skinName -> skinDir and remove broken dependencies 81 | local brokenDependencies = {} 82 | for i,dependSkinName in ipairs(skinConfig.info.depend or {}) do 83 | local dependSkin = SkinHandler.knownSkins[dependSkinName:lower()] 84 | if (dependSkin) then 85 | dirs[#dirs+1] = dependSkin.info.dir 86 | table.merge(skinConfig, dependSkin) 87 | else 88 | Spring.Log("Chili", "error", "Skin " .. skinConfig.info.name .. " depends on an unknown skin named " .. dependSkinName .. ".") 89 | end 90 | end 91 | 92 | --// add the default skindir to the end 93 | dirs[#dirs+1] = SKIN_DIRNAME .. 'default/' 94 | 95 | --// finally translate all paths 96 | TranslateFilePaths(skinConfig, dirs) 97 | end 98 | 99 | --//============================================================================= 100 | --// Internal 101 | 102 | local function GetSkin(skinname) 103 | return SkinHandler.knownSkins[tostring(skinname):lower()] 104 | end 105 | 106 | SkinHandler.defaultSkin = GetSkin('default') 107 | 108 | --//============================================================================= 109 | --// API 110 | 111 | function SkinHandler.IsValidSkin(skinname) 112 | return (not not GetSkin(skinname)) 113 | end 114 | 115 | 116 | function SkinHandler.GetSkinInfo() 117 | local sk = GetSkin(skinname) 118 | if (sk) then 119 | return table.shallowcopy(sk.info) 120 | end 121 | return {} 122 | end 123 | 124 | 125 | function SkinHandler.GetAvailableSkins() 126 | local skins = {} 127 | local knownSkins = SkinHandler.knownSkins 128 | for i=1,#knownSkins do 129 | skins[i] = knownSkins[i].info.name 130 | end 131 | return skins 132 | end 133 | 134 | 135 | local function MergeProperties(obj, skin, classname) 136 | local skinclass = skin[classname] 137 | if not skinclass then return end 138 | BackwardCompa(skinclass) 139 | table.merge(obj, skinclass) 140 | MergeProperties(obj, skin, skinclass.clone) 141 | end 142 | 143 | 144 | function SkinHandler.LoadSkin(control, class) 145 | local skin = GetSkin(control.skinName) 146 | local defskin = SkinHandler.defaultSkin 147 | 148 | local found = false 149 | local inherited = class.inherited 150 | local classname = control.classname 151 | repeat 152 | --FIXME scan whole `depend` table 153 | 154 | if (skin) then 155 | --if (skin[classname]) then 156 | MergeProperties(control, skin, classname) -- per-class defaults 157 | MergeProperties(control, skin, "general") 158 | if (skin[classname]) then 159 | found = true 160 | end 161 | end 162 | 163 | 164 | if (defskin[classname]) then 165 | MergeProperties(control, defskin, classname) -- per-class defaults 166 | MergeProperties(control, defskin, "general") 167 | found = true 168 | end 169 | 170 | if inherited then 171 | classname = inherited.classname 172 | inherited = inherited.inherited 173 | else 174 | found = true 175 | end 176 | until (found) 177 | end -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/taskhandler.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// TaskHandler 3 | 4 | TaskHandler = {} 5 | 6 | --// type1: use use 2 tables so we can iterate and update at the same time 7 | local objects = {} 8 | local objects2 = {} 9 | local objectsCount = 0 10 | 11 | --// type2 12 | local objectsInAnInstant = {} 13 | local objectsInAnInstant2 = {} 14 | local objectsInAnInstantCount = 0 15 | 16 | --// make it a weak table (values) 17 | do 18 | local m = {__mode = "v"} 19 | setmetatable(objects, m) 20 | setmetatable(objects2, m) 21 | setmetatable(objectsInAnInstant, m) 22 | setmetatable(objectsInAnInstant2, m) 23 | end 24 | 25 | --//============================================================================= 26 | 27 | --// Global Event for when an object gets destructed 28 | local globalDisposeListeners = {} 29 | setmetatable(globalDisposeListeners, {__mode = "k"}) 30 | 31 | local function CallListenersByKey(listeners, ...) 32 | for obj in pairs(listeners) do 33 | obj:OnGlobalDispose(...); 34 | end 35 | end 36 | 37 | 38 | function TaskHandler.RequestGlobalDispose(obj) 39 | globalDisposeListeners[obj] = true 40 | end 41 | 42 | --//============================================================================= 43 | 44 | function TaskHandler.RequestUpdate(obj) 45 | obj = UnlinkSafe(obj) 46 | if (not obj.__inUpdateQueue) then 47 | obj.__inUpdateQueue = true 48 | objectsCount = objectsCount + 1 49 | objects[objectsCount] = obj 50 | end 51 | end 52 | 53 | 54 | function TaskHandler.RemoveObject(obj) 55 | obj = UnlinkSafe(obj) 56 | 57 | CallListenersByKey(globalDisposeListeners, obj) 58 | 59 | if (obj.__inUpdateQueue) then 60 | obj.__inUpdateQueue = false 61 | for i=1,objectsCount do 62 | if (objects[i]==obj) then 63 | objects[i] = objects[objectsCount] 64 | objects[objectsCount] = nil 65 | objectsCount = objectsCount - 1 66 | return true 67 | end 68 | end 69 | return false 70 | end 71 | end 72 | 73 | 74 | function TaskHandler.RequestInstantUpdate(obj) 75 | obj = UnlinkSafe(obj) 76 | if (not obj.__inUpdateQueue) then 77 | obj.__inUpdateQueue = true 78 | objectsInAnInstantCount = objectsInAnInstantCount + 1 79 | objectsInAnInstant[objectsInAnInstantCount] = obj 80 | end 81 | end 82 | 83 | --//============================================================================= 84 | 85 | function TaskHandler.Update() 86 | --// type1: run it for all current tasks 87 | local cnt = objectsCount 88 | objectsCount = 0 --// clear the array, so all objects needs to reinsert themselves when they want to get called again 89 | objects,objects2 = objects2,objects 90 | for i=1,cnt do 91 | local obj = objects2[i] 92 | if (obj)and(not obj.disposed) then 93 | obj.__inUpdateQueue = false 94 | local Update = obj.Update 95 | if (Update) then 96 | SafeCall(Update, obj) 97 | end 98 | end 99 | end 100 | 101 | --// type2: endless loop until job is done 102 | local runCounter = 0 103 | while (objectsInAnInstantCount > 0) do 104 | local cnt = objectsInAnInstantCount 105 | objectsInAnInstantCount = 0 106 | objectsInAnInstant,objectsInAnInstant2 = objectsInAnInstant2,objectsInAnInstant 107 | for i=1,cnt do 108 | local obj = objectsInAnInstant2[i] 109 | if (obj)and(not obj.disposed) then 110 | obj.__inUpdateQueue = false 111 | local InstantUpdate = obj.InstantUpdate 112 | if (InstantUpdate) then 113 | SafeCall(InstantUpdate, obj) 114 | end 115 | end 116 | end 117 | end 118 | end 119 | 120 | --//============================================================================= 121 | -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/texturehandler.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// 3 | 4 | TextureHandler = {} 5 | 6 | 7 | --//============================================================================= 8 | --//TWEAKING 9 | 10 | local timeLimit = 0.2/15 --//time per second / desiredFPS 11 | 12 | 13 | --//============================================================================= 14 | --// SpeedUp 15 | 16 | local next = next 17 | local spGetTimer = Spring.GetTimer 18 | local spDiffTimers = Spring.DiffTimers 19 | local glActiveTexture = gl.ActiveTexture 20 | local glCallList = gl.CallList 21 | 22 | local weakMetaTable = {__mode="k"} 23 | 24 | 25 | --//============================================================================= 26 | --// local 27 | 28 | local loaded = {} 29 | local requested = {} 30 | 31 | local placeholderFilename = theme.skin.icons.imageplaceholder 32 | local placeholderDL = gl.CreateList(gl.Texture,CHILI_DIRNAME .. "skins/default/empty.png") 33 | --local placeholderDL = gl.CreateList(gl.Texture,placeholderFilename) 34 | 35 | local isEngineTexture = { [string.byte("!")] = true, [string.byte("%")] = true, [string.byte("#")] = true, [string.byte("$")] = true, [string.byte("^")] = true } 36 | 37 | local function AddRequest(filename,obj) 38 | local req = requested 39 | if (req[filename]) then 40 | local t = req[filename] 41 | t[obj] = true 42 | else 43 | req[filename] = setmetatable({[obj]=true}, weakMetaTable) 44 | end 45 | end 46 | 47 | 48 | --//============================================================================= 49 | --// Destroy 50 | 51 | TextureHandler._scream = Script.CreateScream() 52 | TextureHandler._scream.func = function() 53 | requested = {} 54 | for filename,tex in pairs(loaded) do 55 | gl.DeleteList(tex.dl) 56 | gl.DeleteTexture(filename) 57 | end 58 | loaded = {} 59 | end 60 | 61 | 62 | --//============================================================================= 63 | --// 64 | 65 | function TextureHandler.LoadTexture(arg1,arg2,arg3) 66 | local activeTexID,filename,obj 67 | if (type(arg1)=='number') then 68 | activeTexID = arg1 69 | filename = arg2 70 | obj = arg3 71 | else 72 | activeTexID = 0 73 | filename = arg1 74 | obj = arg2 75 | end 76 | 77 | local tex = loaded[filename] 78 | if (tex) then 79 | glActiveTexture(activeTexID,glCallList,tex.dl) 80 | else 81 | AddRequest(filename,obj) 82 | if isEngineTexture[filename:byte(1)] then 83 | gl.Texture(activeTexID, filename) 84 | else 85 | glActiveTexture(activeTexID,glCallList,placeholderDL) 86 | end 87 | end 88 | end 89 | 90 | 91 | function TextureHandler.DeleteTexture(filename) 92 | local tex = loaded[filename] 93 | if (tex) then 94 | tex.references = tex.references - 1 95 | if (tex.references==0) then 96 | gl.DeleteList(tex.dl) 97 | gl.DeleteTexture(filename) 98 | loaded[filename] = nil 99 | end 100 | end 101 | end 102 | 103 | 104 | --//============================================================================= 105 | --// 106 | 107 | local usedTime = 0 108 | local lastCall = spGetTimer() 109 | local nullInfo = {xsize=0} 110 | 111 | 112 | function TextureHandler.Update() 113 | if (not next(requested)) then return end 114 | 115 | if (usedTime>0) then 116 | thisCall = spGetTimer() 117 | 118 | usedTime = usedTime - spDiffTimers(thisCall,lastCall) 119 | lastCall = thisCall 120 | 121 | if (usedTime<0) then usedTime = 0 end 122 | end 123 | 124 | local broken = {} 125 | local timerStart = spGetTimer() 126 | local finished = false 127 | while (usedTime < timeLimit)and(not finished) do 128 | local filename,objs = next(requested) 129 | 130 | if (filename) then 131 | gl.Texture(filename) 132 | gl.Texture(false) 133 | 134 | if (gl.TextureInfo(filename) or nullInfo).xsize > 0 then 135 | local texture = {} 136 | texture.dl = gl.CreateList(gl.Texture,filename) 137 | loaded[filename] = texture 138 | 139 | for obj in pairs(objs) do 140 | obj:Invalidate() 141 | texture.references = (texture.references or 0) + 1 142 | end 143 | else 144 | broken[filename] = objs 145 | end 146 | 147 | requested[filename] = nil 148 | 149 | local timerEnd = spGetTimer() 150 | usedTime = usedTime + spDiffTimers(timerEnd,timerStart) 151 | timerStart = timerEnd 152 | else 153 | finished = true 154 | end 155 | end 156 | 157 | for i,v in pairs(broken) do 158 | requested[i] = v 159 | end 160 | 161 | lastCall = spGetTimer() 162 | end 163 | 164 | --//============================================================================= 165 | -------------------------------------------------------------------------------- /luaui/chili/chili/handlers/themehandler.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// Theme Handler 3 | 4 | --// TODO: WRITE ME 5 | VFS.Include(CHILI_DIRNAME .. "themes/theme.lua", nil, VFS.RAW_FIRST) 6 | -------------------------------------------------------------------------------- /luaui/chili/chili/headers/autolocalizer.lua: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------- 2 | -- 3 | -- Lua Namespace Localizer 4 | -- 5 | -- author: jK (2009) 6 | -- 7 | -- License: GPLv2 8 | -- 9 | -- Info: 10 | -- overrides VFS.Include with a function that autolocalize the used namespaces 11 | -- 12 | 13 | -- Settings 14 | local maxLocals = 50 15 | 16 | local namespaces = { 17 | {"Spring.MoveCtrl", "mc"}, 18 | {"Spring", "sp"}, 19 | {"Script", "sc"}, 20 | {"gl", "gl"}, 21 | {"GL", "GL_"}, 22 | {"math", ""}, 23 | {"CMD", "CMD_"}, 24 | {"CMDTYPE", "CMDTYPE_"}, 25 | {"Game", "Game"}, 26 | {"table", "tb"}, 27 | } 28 | 29 | 30 | --//TODO 31 | local globalFuncs = { 32 | "pairs", 33 | "ipairs", 34 | "select", 35 | "unpack", 36 | "UnitDefs", 37 | "UnitDefNames", 38 | "FeatureDefs", 39 | "WeaponDefs", 40 | } 41 | 42 | --------------------------------------------------------------------------- 43 | -- 44 | 45 | if (Spring.GetConfigInt("AutoLocalizeLua", 1) == 0) then 46 | return 47 | end 48 | 49 | --------------------------------------------------------------------------- 50 | -- 51 | 52 | local used_funcs = {} 53 | local numLocals = 0 54 | 55 | local function CreateLocal(prefix) 56 | local _G = getfenv() 57 | return function(fnc_prefix,fnc_name) 58 | local longname = fnc_prefix .. "." .. fnc_name 59 | local shortname = prefix..fnc_name 60 | 61 | --// if it's not in the current global namespace (perhaps it gets added later?) 62 | --// then don't localize it 63 | local gn = _G[fnc_prefix] 64 | if (type(gn)~="table")or(not gn[fnc_name]) then 65 | return longname 66 | end 67 | 68 | if (used_funcs[longname]) then 69 | return shortname 70 | else 71 | if (numLocals40) then 133 | filename = filename:sub(-40) 134 | end 135 | 136 | repeat 137 | str2 = LocalizeString(str) 138 | 139 | chunk, err = loadstring(str2, filename) 140 | 141 | if (not chunk) then 142 | if (err:find("has more than %d+ upvalues")) then 143 | maxLocals = maxLocals - 10 144 | end 145 | error(err) 146 | end 147 | 148 | until (chunk)or(maxLocals==0) 149 | 150 | maxLocals = oldMaxLocals 151 | 152 | return chunk,str2 153 | end 154 | 155 | 156 | function VFS.Include(filename, enviroment, mode) 157 | local str = LoadFileSafe(filename, mode) 158 | 159 | if (not str) then 160 | return 161 | end 162 | 163 | if (not enviroment) then 164 | local status 165 | status,enviroment = pcall(getfenv,3) 166 | if (not status) then 167 | status,enviroment = pcall(getfenv,2) 168 | if (not status) then 169 | enviroment = getfenv() 170 | end 171 | end 172 | end 173 | 174 | local chunk = MyLoadString(str, filename) 175 | setfenv(chunk, enviroment) 176 | 177 | return chunk() 178 | end 179 | 180 | 181 | function VFS.LoadFile(filename, mode) 182 | local str = LoadFileSafe(filename, mode) 183 | 184 | if (str)and(filename:find(".lua", 1, true)) then 185 | _,str = MyLoadString(str, filename) 186 | end 187 | 188 | return str 189 | end -------------------------------------------------------------------------------- /luaui/chili/chili/headers/backwardcompability.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// 3 | 4 | local function CheckNoneNil(x, fallback) 5 | if (x ~= nil) then 6 | return x 7 | else 8 | return fallback 9 | end 10 | end 11 | 12 | 13 | function BackwardCompa(obj) 14 | obj.font = obj.font or {} 15 | obj.font.outline = CheckNoneNil(obj.font.outline, obj.fontOutline) 16 | obj.font.color = CheckNoneNil(obj.font.color, obj.captionColor) 17 | obj.font.color = CheckNoneNil(obj.font.color, obj.textColor) 18 | obj.font.size = CheckNoneNil(obj.font.size, obj.fontSize) 19 | obj.font.size = CheckNoneNil(obj.font.size, obj.fontsize) 20 | obj.font.shadow = CheckNoneNil(obj.font.shadow, obj.fontShadow) 21 | obj.bolderColor = CheckNoneNil(obj.borderColor, obj.borderColor1) 22 | obj.fontOutline = nil 23 | obj.textColor = nil 24 | obj.captionColor = nil 25 | obj.fontSize = nil 26 | obj.fontsize = nil 27 | obj.fontShadow = nil 28 | end 29 | -------------------------------------------------------------------------------- /luaui/chili/chili/headers/links.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// SHORT INFO WHY WE DO THIS: 3 | --// Cause of the reference based system in lua we can't 4 | --// destroy objects yourself, instead we have to tell 5 | --// the GarbageCollector somehow that an object isn't 6 | --// in use anymore. 7 | --// Now we have a quite complex class system in Chili 8 | --// with parent and children links between objects. Those 9 | --// circles make it normally impossible for the GC to 10 | --// detect if an object (and all its children) can be 11 | --// destructed. 12 | --// This is the point where so called WeakLinks come 13 | --// into play. Instead of saving direct references to the 14 | --// objects in the parent field, we created a weaktable 15 | --// (use google, if you aren't familiar with this name) 16 | --// which directs to the parent-object. So now the link 17 | --// between children and its parent is 'weak' (the GC can 18 | --// catch the parent), and the link between the parent 19 | --// and its children is 'hard', so the GC won't catch the 20 | --// children as long as there is a parent object. 21 | --//============================================================================= 22 | 23 | local wmeta = {__mode = "v"} 24 | local newproxy = newproxy or getfenv(0).newproxy 25 | 26 | function MakeWeakLink(obj,wlink) 27 | --// 2nd argument is optional, if it's given it will reuse the given link (-> less garbage) 28 | 29 | obj = UnlinkSafe(obj) --// unlink hard-/weak-links -> faster (else it would have to go through multiple metatables) 30 | 31 | if (not isindexable(obj)) then 32 | return obj 33 | end 34 | 35 | local mtab 36 | if (type(wlink) == "userdata") then 37 | mtab = getmetatable(wlink) 38 | end 39 | if (not mtab) then 40 | wlink = newproxy(true) 41 | mtab = getmetatable(wlink) 42 | setmetatable(mtab, wmeta) 43 | end 44 | local getRealObject = function() return mtab._obj end --// note: we are using mtab._obj here, so it is a weaklink -> it can return nil! 45 | mtab._islink = true 46 | mtab._isweak = true 47 | mtab._obj = obj 48 | mtab.__index = obj 49 | mtab.__newindex = obj 50 | mtab.__call = getRealObject --// values are weak, so we need to make it gc-safe 51 | mtab[getRealObject] = true --// and buffer it in a key, too 52 | 53 | if (not obj._wlinks) then 54 | local t = {} 55 | setmetatable(t,{__mode="v"}) 56 | obj._wlinks = t 57 | end 58 | obj._wlinks[#obj._wlinks+1] = wlink 59 | 60 | return wlink 61 | end 62 | 63 | 64 | function MakeHardLink(obj,gc) 65 | obj = UnlinkSafe(obj) --// unlink hard-/weak-links -> faster (else it would have to go through multiple metatables) 66 | 67 | if (not isindexable(obj)) then 68 | return obj 69 | end 70 | 71 | local hlink = newproxy(true) 72 | local mtab = getmetatable(hlink) 73 | mtab._islink = true 74 | mtab._ishard = true 75 | mtab._obj = obj 76 | mtab.__gc = gc or function() if not obj._hlinks or not next(obj._hlinks) then obj:AutoDispose() end end 77 | mtab.__index = obj 78 | mtab.__newindex = obj 79 | mtab.__call = function() return mtab._obj end 80 | 81 | if (not obj._hlinks) then 82 | local t = {} 83 | setmetatable(t,{__mode="v"}) 84 | obj._hlinks = t 85 | end 86 | obj._hlinks[#obj._hlinks+1] = hlink 87 | 88 | return hlink 89 | end 90 | 91 | 92 | function UnlinkSafe(link) 93 | local link = link 94 | while (type(link) == "userdata") do 95 | link = link() 96 | end 97 | return link 98 | end 99 | 100 | 101 | function CompareLinks(link1,link2) 102 | return UnlinkSafe(link1) == UnlinkSafe(link2) 103 | end 104 | 105 | 106 | function CheckWeakLink(link) 107 | return (type(link) == "userdata") and link() 108 | end 109 | 110 | --//============================================================================= 111 | -------------------------------------------------------------------------------- /luaui/chili/chili/headers/strict.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- strict.lua 3 | -- checks uses of undeclared global variables 4 | -- All global variables must be 'declared' through a regular assignment 5 | -- (even assigning nil will do) in a main chunk before being used 6 | -- anywhere or assigned to inside a function. 7 | -- 8 | 9 | -- backup table works like a normal __index table 10 | local function MakeStrict(env, backup) 11 | local mt = getmetatable(env) 12 | if mt == nil then 13 | mt = {} 14 | setmetatable(env, mt) 15 | end 16 | 17 | mt.__index = function (t, n) 18 | if (backup[n]==nil) then 19 | error("variable '"..n.."' is not declared (strict mode)", 2) 20 | end 21 | return backup[n] 22 | end 23 | end 24 | 25 | return MakeStrict 26 | -------------------------------------------------------------------------------- /luaui/chili/chili/headers/unicode.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// 3 | 4 | -- shift left 5 | local function lsh(value,shift) 6 | return (value*(2^shift)) % 2^24 7 | end 8 | -- shift right 9 | local function rsh(value,shift) 10 | return math.floor(value/2^shift) % 2^24 11 | end 12 | 13 | 14 | function UnicodeToUtf8(ch) 15 | if (ch == 0) then 16 | return nil 17 | end 18 | 19 | if (ch < lsh(1,7)) then 20 | return string.char(ch) 21 | elseif (ch < lsh(1,11)) then 22 | return string.char( 23 | math.bit_or(0xC0, rsh(ch,6)), 24 | math.bit_or(0x80, math.bit_and(ch, 0x3F)) 25 | ) 26 | elseif (ch < lsh(1,16)) then 27 | return string.char( 28 | math.bit_or(0xE0, rsh(ch,12)), 29 | math.bit_or(0x80, math.bit_and(rsh(ch,6), 0x3F)), 30 | math.bit_or(0x80, math.bit_and( ch, 0x3F)) 31 | ) 32 | elseif (ch < lsh(1,21)) then 33 | return string.char( 34 | math.bit_or(0xF0, rsh(ch,18)), 35 | math.bit_or(0x80, math.bit_and(rsh(ch,12), 0x3F)), 36 | math.bit_or(0x80, math.bit_and( rsh(ch,6), 0x3F)), 37 | math.bit_or(0x80, math.bit_and( ch, 0x3F)) 38 | ) 39 | end 40 | 41 | return nil 42 | end 43 | 44 | 45 | local function count_leading_ones(num) 46 | return 47 | ((math.bit_and(num, 0xF0) == 0xF0) and 4) 48 | or ((math.bit_and(num, 0xE0) == 0xE0) and 3) 49 | or ((math.bit_and(num, 0xC0) == 0xC0) and 2) 50 | or ((math.bit_and(num, 0x80) == 0x80) and 1) 51 | or 0 52 | end 53 | 54 | 55 | local function Utf8GetCharByteLength(text, pos) 56 | --// UTF8 looks like this 57 | --// 1Byte == ASCII: 0xxxxxxxxx 58 | --// 2Bytes encoded char: 110xxxxxxx 10xxxxxx 59 | --// 3Bytes encoded char: 1110xxxxxx 10xxxxxx 10xxxxxx 60 | --// 4Bytes encoded char: 11110xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 61 | --// Originaly there were 5&6 byte versions too, but they were dropped in RFC 3629. 62 | --// So UTF8 maps to UTF16 range only 63 | 64 | local UTF8_CONT_MASK = 0xC0 --// 11xxxxxx 65 | local UTF8_CONT_OKAY = 0x80 --// 10xxxxxx 66 | 67 | if (pos <= 0) then 68 | return 0 69 | end 70 | 71 | --// read next 4bytes and check if it is an utf8 sequence 72 | local remainingChars = (text:len() + 1) - pos --FIXME 73 | if (remainingChars <= 0) then 74 | return 0 75 | end 76 | 77 | --// how many bytes are requested for our multi-byte utf8 sequence 78 | local clo = count_leading_ones(string.byte(text, pos, pos)) --FIXME 79 | if (clo>4) or (clo==0) then clo = 1 end --// ignore >=5 byte ones cause of RFC 3629 80 | 81 | --// how many healthy utf8 bytes are following 82 | local numValidUtf8Bytes = 1; --// first char is always valid 83 | if (math.bit_and(string.byte(text, pos + 1, pos + 1) or 0, UTF8_CONT_MASK) == UTF8_CONT_OKAY) then numValidUtf8Bytes = numValidUtf8Bytes + 1 end 84 | if (math.bit_and(string.byte(text, pos + 2, pos + 2) or 0, UTF8_CONT_MASK) == UTF8_CONT_OKAY) then numValidUtf8Bytes = numValidUtf8Bytes + 1 end 85 | if (math.bit_and(string.byte(text, pos + 3, pos + 3) or 0, UTF8_CONT_MASK) == UTF8_CONT_OKAY) then numValidUtf8Bytes = numValidUtf8Bytes + 1 end 86 | 87 | --// check if enough trailing utf8 bytes are healthy 88 | --// else ignore utf8 and parse it as 8bit Latin-1 char (extended ASCII) 89 | --// this adds backwardcompatibility with the old renderer 90 | --// which supported extended ASCII with umlauts etc. 91 | if (clo > numValidUtf8Bytes) then 92 | return 1 93 | end 94 | return clo 95 | end 96 | 97 | 98 | function Utf8PrevChar(s, startPos) 99 | local pos = math.max(startPos - 4, 1) 100 | local oldPos = pos 101 | while (pos < startPos) do 102 | oldPos = pos 103 | pos = pos + Utf8GetCharByteLength(s, pos) 104 | end 105 | return oldPos 106 | end 107 | function Utf8NextChar(s, pos) 108 | return pos + Utf8GetCharByteLength(s, pos) 109 | end 110 | 111 | function Utf8BackspaceAt(s, pos) 112 | if pos <= 1 then return s, pos end 113 | local p = Utf8PrevChar(s, pos) 114 | return Utf8DeleteAt(s, p), p 115 | end 116 | function Utf8DeleteAt(s, pos) 117 | local l = Utf8GetCharByteLength(s, pos) 118 | return s:sub(1, pos - 1) .. s:sub(pos + l) 119 | end 120 | -------------------------------------------------------------------------------- /luaui/chili/chili/headers/util.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | 3 | function IsTweakMode() 4 | return widgetHandler.tweakMode 5 | end 6 | 7 | --//============================================================================= 8 | 9 | --// some needed gl constants 10 | GL_DEPTH24_STENCIL8 = 0x88F0 11 | GL_KEEP = 0x1E00 12 | GL_INCR_WRAP = 0x8507 13 | GL_DECR_WRAP = 0x8508 14 | 15 | --//============================================================================= 16 | 17 | function unpack4(t) 18 | return t[1], t[2], t[3], t[4] 19 | end 20 | 21 | function clamp(min,max,num) 22 | if (nummax) then 25 | return max 26 | end 27 | return num 28 | end 29 | 30 | function ExpandRect(rect,margin) 31 | return { 32 | rect[1] - margin[1], --//left 33 | rect[2] - margin[2], --//top 34 | rect[3] + margin[1] + margin[3], --//width 35 | rect[4] + margin[2] + margin[4], --//height 36 | } 37 | end 38 | 39 | function InRect(rect,x,y) 40 | return x>=rect[1] and y>=rect[2] and 41 | x<=rect[1]+rect[3] and y<=rect[2]+rect[4] 42 | end 43 | 44 | function ProcessRelativeCoord(code, total) 45 | local num = tonumber(code) 46 | 47 | if (type(code) == "string") then 48 | local percent = tonumber(code:sub(1,-2)) or 0 49 | if (percent<0) then 50 | percent = 0 51 | elseif (percent>100) then 52 | percent = 100 53 | end 54 | return math.floor(total * percent/100) 55 | elseif (num)and((1/num)<0) then 56 | return math.floor(total + num) 57 | else 58 | return math.floor(num or 0) 59 | end 60 | end 61 | 62 | function IsRelativeCoord(code) 63 | local num = tonumber(code) 64 | 65 | if (type(code) == "string") then 66 | return true 67 | elseif (num)and((1/num)<0) then 68 | return true 69 | else 70 | return false 71 | end 72 | end 73 | 74 | function IsRelativeCoordType(code) 75 | local num = tonumber(code) 76 | 77 | if (type(code) == "string") then 78 | return "relative" 79 | elseif (num)and((1/num)<0) then 80 | return "negative" 81 | else 82 | return "default" 83 | end 84 | end 85 | 86 | --//============================================================================= 87 | 88 | function IsObject(v) 89 | return ((type(v)=="metatable")or(type(v)=="userdata")) and(v.classname) 90 | end 91 | 92 | 93 | function IsNumber(v) 94 | return (type(v)=="number") 95 | end 96 | 97 | function isnumber(v) 98 | return (type(v)=="number") 99 | end 100 | 101 | function istable(v) 102 | return (type(v)=="table") 103 | end 104 | 105 | function isstring(v) 106 | return (type(v)=="string") 107 | end 108 | 109 | function isindexable(v) 110 | local t = type(v) 111 | return (t=="table")or(t=="metatable")or(t=="userdata") 112 | end 113 | 114 | function isfunc(v) 115 | return (type(v)=="function") 116 | end 117 | 118 | --//============================================================================= 119 | 120 | local curScissor = {1,1,1e9,1e9} 121 | local stack = {curScissor} 122 | local stackN = 1 123 | 124 | local pool = {} 125 | local function GetVector4() 126 | if not pool[1] then 127 | return {0,0,0,0} 128 | end 129 | local t = pool[#pool] 130 | pool[#pool] = nil 131 | return t 132 | end 133 | local function FreeVector4(t) 134 | pool[#pool + 1] = t 135 | end 136 | 137 | local function PushScissor(_,x,y,w,h) 138 | local right = x + w 139 | local bottom = y + h 140 | if (right > curScissor[3]) then right = curScissor[3] end 141 | if (bottom > curScissor[4]) then bottom = curScissor[4] end 142 | if (x < curScissor[1]) then x = curScissor[1] end 143 | if (y < curScissor[2]) then y = curScissor[2] end 144 | 145 | w = right - x 146 | h = bottom - y 147 | if (w < 0) or (h < 0) then 148 | --// scissor is null space -> don't render at all 149 | return false 150 | end 151 | 152 | --curScissor = {x,y,right,bottom} 153 | curScissor = GetVector4() 154 | curScissor[1] = x; curScissor[2] = y; curScissor[3] = right; curScissor[4] = bottom; 155 | stackN = stackN + 1 156 | stack[stackN] = curScissor 157 | 158 | gl.Scissor(x,y,w,h) 159 | return true 160 | end 161 | 162 | 163 | local function PopScissor() 164 | FreeVector4(curScissor) 165 | stack[stackN] = nil 166 | stackN = stackN - 1 167 | curScissor = stack[stackN] 168 | assert(stackN >= 1) 169 | if (stackN == 1) then 170 | gl.Scissor(false) 171 | else 172 | local x,y, right,bottom = unpack4(curScissor) 173 | local w = right - x 174 | local h = bottom - y 175 | gl.Scissor(x,y,w,h) 176 | end 177 | end 178 | 179 | 180 | 181 | local function PushStencilMask(obj, x,y,w,h) 182 | obj._stencilMask = (obj.parent._stencilMask or 0) + 1 183 | if (obj._stencilMask > 255) then 184 | obj._stencilMask = 0 185 | end 186 | 187 | gl.ColorMask(false) 188 | 189 | gl.StencilFunc(GL.ALWAYS, 0, 0xFF) 190 | gl.StencilOp(GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP) 191 | 192 | if not obj.scrollPosY then 193 | gl.Rect(0, 0, w, h) 194 | else 195 | local contentX,contentY,contentWidth,contentHeight = unpack4(obj.contentArea) 196 | gl.Rect(0, 0, contentWidth,contentHeight) 197 | end 198 | 199 | gl.ColorMask(true) 200 | gl.StencilFunc(GL.EQUAL, obj._stencilMask, 0xFF) 201 | gl.StencilOp(GL_KEEP, GL_KEEP, GL_KEEP) 202 | return true 203 | end 204 | 205 | local function PopStencilMask(obj, x,y,w,h) 206 | gl.ColorMask(false) 207 | 208 | gl.StencilFunc(GL.ALWAYS, 0, 0xFF) 209 | gl.StencilOp(GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP) 210 | 211 | if not obj.scrollPosY then 212 | gl.Rect(0, 0, w, h) 213 | else 214 | local contentX,contentY,contentWidth,contentHeight = unpack4(obj.contentArea) 215 | gl.Rect(0, 0, contentWidth,contentHeight) 216 | end 217 | 218 | gl.ColorMask(true) 219 | gl.StencilFunc(GL.EQUAL, obj.parent._stencilMask or 0, 0xFF) 220 | gl.StencilOp(GL_KEEP, GL_KEEP, GL_KEEP) 221 | --gl.StencilTest(false) 222 | 223 | obj._stencilMask = nil 224 | end 225 | 226 | 227 | local inRTT = false 228 | 229 | function EnterRTT() 230 | inRTT = true 231 | end 232 | 233 | function LeaveRTT() 234 | inRTT = false 235 | end 236 | 237 | function AreInRTT() 238 | return inRTT 239 | end 240 | 241 | 242 | function PushLimitRenderRegion(...) 243 | if inRTT then 244 | return PushStencilMask(...) 245 | else 246 | return PushScissor(...) 247 | end 248 | end 249 | 250 | function PopLimitRenderRegion(...) 251 | if inRTT then 252 | PopStencilMask(...) 253 | else 254 | PopScissor(...) 255 | end 256 | end 257 | 258 | 259 | --//============================================================================= 260 | 261 | function AreRectsOverlapping(rect1,rect2) 262 | return 263 | (rect1[1] <= rect2[1] + rect2[3]) and 264 | (rect1[1] + rect1[3] >= rect2[1]) and 265 | (rect1[2] <= rect2[2] + rect2[4]) and 266 | (rect1[2] + rect1[4] >= rect2[2]) 267 | end 268 | 269 | --//============================================================================= 270 | 271 | local oldPrint = print 272 | function print(...) 273 | oldPrint(...) 274 | io.flush() 275 | end 276 | 277 | --//============================================================================= 278 | 279 | function _ParseColorArgs(r,g,b,a) 280 | local t = type(r) 281 | 282 | if (t == "table") then 283 | return r 284 | else 285 | return {r,g,b,a} 286 | end 287 | end 288 | 289 | --//============================================================================= 290 | 291 | function string:findlast(str) 292 | local i 293 | local j = 0 294 | repeat 295 | i = j 296 | j = self:find(str,i+1,true) 297 | until (not j) 298 | return i 299 | end 300 | 301 | function string:GetExt() 302 | local i = self:findlast('.') 303 | if (i) then 304 | return self:sub(i) 305 | end 306 | end 307 | 308 | --//============================================================================= 309 | 310 | local type = type 311 | local pairs = pairs 312 | 313 | function table:clear() 314 | for i,_ in pairs(self) do 315 | self[i] = nil 316 | end 317 | end 318 | 319 | function table:map(fun) 320 | local newTable = {} 321 | for key, value in pairs(self) do 322 | newTable[key] = fun(key, value) 323 | end 324 | return newTable 325 | end 326 | 327 | function table:shallowcopy() 328 | local newTable = {} 329 | for k, v in pairs(self) do 330 | newTable[k] = v 331 | end 332 | return newTable 333 | end 334 | 335 | function table:arrayshallowcopy() 336 | local newArray = {} 337 | for i=1, #self do 338 | newArray[i] = self[i] 339 | end 340 | return newTable 341 | end 342 | 343 | function table:arrayappend(t) 344 | for i=1, #t do 345 | self[#self+1] = t[i] 346 | end 347 | end 348 | 349 | function table:arraymap(fun) 350 | for i=1, #self do 351 | newTable[i] = fun(self[i]) 352 | end 353 | end 354 | 355 | function table:fold(fun, state) 356 | for key, value in pairs(self) do 357 | fun(state, key, value) 358 | end 359 | end 360 | 361 | function table:arrayreduce(fun) 362 | local state = self[1] 363 | for i=2, #self do 364 | state = fun(state , self[i]) 365 | end 366 | return state 367 | end 368 | 369 | -- removes and returns element from array 370 | -- array, T element -> T element 371 | function table:arrayremovefirst(element) 372 | for i=1, #self do 373 | if self[i] == element then 374 | return self:remove(i) 375 | end 376 | end 377 | end 378 | 379 | function table:ifind(element) 380 | for i=1, #self do 381 | if self[i] == element then 382 | return i 383 | end 384 | end 385 | return false 386 | end 387 | 388 | function table:sum() 389 | local r = 0 390 | for i=1, #self do 391 | r = r + self[i] 392 | end 393 | return r 394 | end 395 | 396 | function table:merge(table2) 397 | for i,v in pairs(table2) do 398 | if (type(v)=='table') then 399 | local sv = type(self[i]) 400 | if (sv == 'table')or(sv == 'nil') then 401 | if (sv == 'nil') then self[i] = {} end 402 | table.merge(self[i],v) 403 | end 404 | elseif (self[i] == nil) then 405 | self[i] = v 406 | end 407 | end 408 | return self 409 | end 410 | 411 | function table:iequal(table2) 412 | for i,v in pairs(self) do 413 | if (table2[i] ~= v) then 414 | return false 415 | end 416 | end 417 | 418 | for i,v in pairs(table2) do 419 | if (self[i] ~= v) then 420 | return false 421 | end 422 | end 423 | 424 | return true 425 | end 426 | 427 | function table:iequal(table2) 428 | local length = #self 429 | if (length ~= #table2) then 430 | return false 431 | end 432 | 433 | for i=1,length do 434 | if (self[i] ~= table2[i]) then 435 | return false 436 | end 437 | end 438 | 439 | return true 440 | end 441 | 442 | function table:size() 443 | local cnt = 0 444 | for _ in pairs(self) do 445 | cnt = cnt + 1 446 | end 447 | return cnt 448 | end 449 | 450 | --//============================================================================= 451 | 452 | local weak_meta = {__mode='v'} 453 | function CreateWeakTable() 454 | local m = {} 455 | setmetatable(m, weak_meta) 456 | return m 457 | end 458 | 459 | --//============================================================================= 460 | 461 | function math.round(num,idp) 462 | if (not idp) then 463 | return math.floor(num+.5) 464 | else 465 | return ("%." .. idp .. "f"):format(num) 466 | --local mult = 10^(idp or 0) 467 | --return math.floor(num * mult + 0.5) / mult 468 | end 469 | end 470 | 471 | --//============================================================================= 472 | 473 | function InvertColor(c) 474 | return {1 - c[1], 1 - c[2], 1 - c[3], c[4]} 475 | end 476 | 477 | function math.mix(x, y, a) 478 | return y * a + x * (1 - a) 479 | end 480 | 481 | function mulColor(c, s) 482 | return {s * c[1], s * c[2], s * c[3], c[4]} 483 | end 484 | 485 | function mulColors(c1, c2) 486 | return {c1[1] * c2[1], c1[2] * c2[2], c1[3] * c2[3], c1[4] * c2[4]} 487 | end 488 | 489 | function mixColors(c1, c2, a) 490 | return { 491 | math.mix(c1[1], c2[1], a), 492 | math.mix(c1[2], c2[2], a), 493 | math.mix(c1[3], c2[3], a), 494 | math.mix(c1[4], c2[4], a) 495 | } 496 | end 497 | 498 | function color2incolor(r,g,b,a) 499 | if type(r) == 'table' then 500 | r,g,b,a = unpack4(r) 501 | end 502 | 503 | local inColor = '\255\255\255\255' 504 | if r then 505 | inColor = string.char(255, r*255, g*255, b*255) 506 | end 507 | return inColor 508 | end 509 | 510 | function incolor2color(inColor) 511 | local a = 255 512 | local r,g,b = inColor:sub(2,4):byte(1,3) 513 | return r/255, g/255, b/255, a/255 514 | end 515 | 516 | --//============================================================================= 517 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/DarkGlass/combobox_wnd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/DarkGlass/combobox_wnd.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/DarkGlass/glass.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/DarkGlass/glass.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/DarkGlass/glass_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/DarkGlass/glass_.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/DarkGlass/skin.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// GlassSkin 3 | 4 | local skin = { 5 | info = { 6 | name = "DarkGlass", 7 | version = "0.11", 8 | author = "jK", 9 | 10 | depend = { 11 | "Glass", 12 | }, 13 | } 14 | } 15 | 16 | --//============================================================================= 17 | --// 18 | 19 | skin.general = { 20 | textColor = {1,1,1,1}, 21 | } 22 | 23 | skin.window = { 24 | TileImage = ":cl:glass_.png", 25 | tiles = {22, 24, 22, 23}, --// tile widths: left,top,right,bottom 26 | padding = {14, 23, 14, 14}, 27 | hitpadding = {10, 4, 10, 10}, 28 | 29 | captionColor = {1, 1, 1, 0.55}, 30 | 31 | boxes = { 32 | resize = {-25, -25, -14, -14}, 33 | drag = {0, 0, "100%", 24}, 34 | }, 35 | 36 | NCHitTest = NCHitTestWithPadding, 37 | NCMouseDown = WindowNCMouseDown, 38 | NCMouseDownPostChildren = WindowNCMouseDownPostChildren, 39 | 40 | DrawControl = DrawWindow, 41 | DrawDragGrip = DrawDragGrip, 42 | DrawResizeGrip = DrawResizeGrip, 43 | } 44 | 45 | skin.combobox_window = { 46 | clone = "window"; 47 | TileImage = ":cl:combobox_wnd.png", 48 | padding = {4, 3, 3, 4}; 49 | } 50 | 51 | --//============================================================================= 52 | --// 53 | 54 | return skin 55 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/checkbox.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/checkbox.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/checkbox.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/checkbox_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/checkbox_.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/checkbox_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/checkbox_arrow.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/combobox_ctrl_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/combobox_ctrl_arrow.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/combobox_wnd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/combobox_wnd.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glass.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glass2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glass2.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glass2.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glass2.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glassBK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glassBK.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glassButton.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glassButton.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glassFG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glassFG.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glass_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glass_line.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/glass_line_vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/glass_line_vert.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/hscrollbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/hscrollbar.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/itemlistview_item_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/itemlistview_item_fg.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/node_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/node_selected.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/panel.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/panel.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/panel.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/panel_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/panel_.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/porgressbar_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/porgressbar_empty.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/progressbar_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/progressbar_empty.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/progressbar_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/progressbar_full.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/scrollbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/scrollbar.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/scrollbar_knob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/scrollbar_knob.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/scrollbar_knob.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/scrollbar_knob.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/skin.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// GlassSkin 3 | 4 | local skin = { 5 | info = { 6 | name = "Glass", 7 | version = "0.2", 8 | author = "jK", 9 | } 10 | } 11 | 12 | --//============================================================================= 13 | --// 14 | 15 | skin.general = { 16 | --font = "FreeSansBold.ttf", 17 | fontsize = 13, 18 | textColor = {0.1,0.1,0.1,1}, 19 | focusColor = {0.35, 0.35, 1.0, 0.9}, 20 | borderColor = {1.0, 1.0, 1.0, 1.0}, 21 | 22 | --padding = {5, 5, 5, 5}, --// padding: left, top, right, bottom 23 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 24 | 25 | font = { 26 | outlineColor = {0.2,0.2,0.2,0.3}, 27 | --autoOutlineColor = false, 28 | --shadow = true, 29 | }, 30 | } 31 | 32 | skin.icons = { 33 | imageplaceholder = ":cl:placeholder.png", 34 | } 35 | 36 | skin.button = { 37 | TileImageFG = ":cl:glassFG.png", 38 | TileImageBK = ":cl:glassBK.png", 39 | tiles = {17,15,17,20}, 40 | 41 | textColor = {1,1,1,1}, 42 | 43 | padding = {12, 12, 12, 12}, 44 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 45 | 46 | DrawControl = DrawButton, 47 | } 48 | 49 | 50 | skin.combobox = { 51 | TileImageFG = ":cl:glassFG.png", 52 | TileImageBK = ":cl:glassBK.png", 53 | TileImageArrow = ":cl:combobox_ctrl_arrow.png", 54 | tiles = {17,15,17,20}, 55 | padding = {10, 10, 26, 10}, 56 | 57 | textColor = {1,1,1,1}, 58 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 59 | 60 | DrawControl = DrawComboBox, 61 | } 62 | 63 | 64 | skin.combobox_window = { 65 | clone = "window"; 66 | TileImage = ":cl:combobox_wnd.png", 67 | padding = {4, 3, 3, 4}; 68 | } 69 | 70 | 71 | skin.combobox_scrollpanel = { 72 | clone = "scrollpanel"; 73 | borderColor = {1, 1, 1, 0}; 74 | padding = {0, 0, 0, 0}; 75 | } 76 | 77 | 78 | skin.combobox_item = { 79 | clone = "button"; 80 | } 81 | 82 | 83 | skin.editbox = { 84 | textColor = {1.0, 1.0, 1.0, 1.0}, 85 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 86 | cursorColor = {0.35, 0.35, 1.0, 0.9}, 87 | } 88 | 89 | skin.checkbox = { 90 | TileImageFG = ":cl:checkbox_arrow.png", 91 | TileImageBK = ":cl:checkbox.png", 92 | tiles = {3,3,3,3}, 93 | boxsize = 13, 94 | 95 | DrawControl = DrawCheckbox, 96 | } 97 | 98 | 99 | skin.imagelistview = { 100 | imageFolder = "folder.png", 101 | imageFolderUp = "folder_up.png", 102 | 103 | --DrawControl = DrawBackground, 104 | 105 | colorFG = {0.75,0.75,0.75,0.65}, 106 | colorFG_selected = {1,1,1,0.65}, 107 | imageFG = ":cl:itemlistview_item_fg.png", 108 | 109 | colorBK = {0.5, 0.5, 0.5, 0.1}, 110 | colorBK_selected = {0.35,0.35,1,0.9}, 111 | imageBK = ":cl:glassBK.png", 112 | 113 | tiles = {17,15,17,20}, 114 | 115 | DrawItemBackground = DrawItemBkGnd, 116 | } 117 | --[[ 118 | skin.imagelistviewitem = { 119 | imageFG = ":cl:glassFG.png", 120 | imageBK = ":cl:glassBK.png", 121 | tiles = {17,15,17,20}, 122 | 123 | padding = {12, 12, 12, 12}, 124 | 125 | DrawSelectionItemBkGnd = DrawSelectionItemBkGnd, 126 | } 127 | --]] 128 | 129 | skin.panel = { 130 | TileImageFG = ":cl:glassFG.png", 131 | TileImageBK = ":cl:glassBK.png", 132 | tiles = {17,15,17,20}, 133 | 134 | DrawControl = DrawPanel, 135 | } 136 | 137 | skin.progressbar = { 138 | TileImageFG = ":cl:progressbar_full.png", 139 | TileImageBK = ":cl:progressbar_empty.png", 140 | tiles = {3,3,3,3}, 141 | 142 | DrawControl = DrawProgressbar, 143 | } 144 | 145 | skin.scrollpanel = { 146 | BorderTileImage = ":cl:panel.png", 147 | bordertiles = {14,10,14,8}, 148 | 149 | TileImage = ":cl:scrollbar.png", 150 | tiles = {6,3,6,3}, 151 | KnobTileImage = ":cl:scrollbar_knob.png", 152 | KnobTiles = {6,7,6,7}, 153 | 154 | HTileImage = ":cl:hscrollbar.png", 155 | htiles = {3,6,3,6}, 156 | HKnobTileImage = ":cl:scrollbar_knob.png", 157 | HKnobTiles = {6,7,6,9}, 158 | 159 | KnobColorSelected = {0.35, 0.35, 1.0, 0.9}, 160 | 161 | padding = {1,1,1,1}, 162 | 163 | scrollbarSize = 11, 164 | DrawControl = DrawScrollPanel, 165 | DrawControlPostChildren = DrawScrollPanelBorder, 166 | } 167 | 168 | skin.trackbar = { 169 | TileImage = ":cl:trackbar.png", 170 | tiles = {6, 3, 6, 3}, --// tile widths: left,top,right,bottom 171 | 172 | ThumbImage = ":cl:trackbar_thumb.png", 173 | StepImage = ":cl:trackbar_step.png", 174 | 175 | hitpadding = {4, 4, 4, 4}, 176 | 177 | DrawControl = DrawTrackbar, 178 | } 179 | 180 | skin.treeview = { 181 | ImageNodeSelected = ":cl:node_selected.png", 182 | tiles = {10,9,10,22}, 183 | 184 | ImageExpanded = ":cl:treeview_node_expanded.png", 185 | ImageCollapsed = ":cl:treeview_node_collapsed.png", 186 | treeColor = {0,0,0,0.4}, 187 | 188 | DrawNode = DrawTreeviewNode, 189 | DrawNodeTree = DrawTreeviewNodeTree, 190 | } 191 | 192 | skin.window = { 193 | TileImage = ":cl:glass.png", 194 | tiles = {22, 24, 22, 23}, --// tile widths: left,top,right,bottom 195 | padding = {14, 23, 14, 14}, 196 | hitpadding = {10, 4, 10, 10}, 197 | 198 | captionColor = {0, 0, 0, 0.55}, 199 | 200 | boxes = { 201 | resize = {-25, -25, -14, -14}, 202 | drag = {0, 0, "100%", 24}, 203 | }, 204 | 205 | NCHitTest = NCHitTestWithPadding, 206 | NCMouseDown = WindowNCMouseDown, 207 | NCMouseDownPostChildren = WindowNCMouseDownPostChildren, 208 | 209 | DrawControl = DrawWindow, 210 | DrawDragGrip = DrawDragGrip, 211 | DrawResizeGrip = DrawResizeGrip, 212 | } 213 | 214 | skin.line = { 215 | TileImage = ":cl:glass_line.png", 216 | tiles = {0, 0, 0, 0}, 217 | TileImageV = ":cl:glass_line_vert.png", 218 | tilesV = {0, 0, 0, 0}, 219 | DrawControl = DrawLine, 220 | } 221 | 222 | skin.control = skin.general 223 | 224 | 225 | --//============================================================================= 226 | --// 227 | 228 | return skin 229 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/trackbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/trackbar.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/trackbar_step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/trackbar_step.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/trackbar_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/trackbar_thumb.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/treeview_node.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/treeview_node.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/treeview_node2.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/treeview_node2.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/treeview_node_collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/treeview_node_collapsed.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Glass/treeview_node_expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Glass/treeview_node_expanded.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/combobox_ctrl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/combobox_ctrl.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/combobox_ctrl_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/combobox_ctrl_arrow.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/combobox_ctrl_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/combobox_ctrl_fg.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/combobox_wnd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/combobox_wnd.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/empty.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/fonts/README: -------------------------------------------------------------------------------- 1 | 2 | The included font "Nimbus Sans L" with the filename "n019003l.pfb", 3 | located next to this README, is retrieved from the Gentoo portage 4 | (media-fonts/urw-fonts) including their modifications. 5 | It is licensed under GPL with an addition as discribed in README.gentoo. 6 | 7 | Thanks to URW for releasing the font(s) under it. 8 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/fonts/README.gentoo: -------------------------------------------------------------------------------- 1 | Cyrillized free URW fonts. 2 | 3 | These fonts were made from the free URW fonts distributed with ghostcript. 4 | There are NO changes in the latin part of them (I hope). 5 | Cyrillic glyphs were added by copying suitable latin ones 6 | and painting oulines of unique cyrillic glyphs in same style as the others. 7 | For all modification pfaedit was used. 8 | The license for result is (of course) same as for original fonts, 9 | i.e. GPL with an exception that you can put these fonts in your own non-GPLed 10 | documents. (Looks like LGPL from my point of view =). 11 | 12 | The "sources" of these fonts in the native pfaedit format are available 13 | at ftp://ftp.gnome.ru/fonts/sources 14 | 15 | The great font editor pfaedit is available at http://pfaedit.sf.net. 16 | That page also includes some links to fonts created by 17 | George Williams -- the author of pfaedit. 18 | 19 | Acknowledgements: 20 | I would like to thank George Williams, the pfaedit's author and developer. 21 | He is the most bug-reporter/feature-requester friendly developer 22 | I ever saw in my not so short life. At some moment in the future 23 | I must write a book about him: "George Williams and my best experience 24 | in bug-reporting." George also greatly helped me bug-hunting these fonts, 25 | explained to me some very important things about fonts and font design, 26 | quickly adopted pfaedit to my needs (or pointed me to The Right Place in 27 | documentation where I found better way of doing things). 28 | 29 | I would like to thank Alexey Novodvorsky (aka AEN), who 30 | pointed me to pfaedit and George Williams' fonts, explained 31 | The Task to me. He is also one of the main participators in the 32 | development of Sysiphus -- free repository of free software. 33 | I didn't loose my time for compiling/installing and supporting 34 | my linux box coz I used the result of Sysiphus developers' works. 35 | 36 | I would like to thank Sergey Vlasov, who tested these fonts and reported 37 | about bugs. Also he help me to make some bug-reports to George about 38 | pfaedit bugs. 39 | 40 | I would like Dmitry 40in, who did big QA for some font outlines, drawn some glyphs, 41 | and explain some The Truths for me. 42 | 43 | I would like to thank Vlad Harchev (aka hvv), who 44 | proofread this text for me. 45 | 46 | Also I have to thank RMS for GPL and URW for releasing the fonts 47 | under it. 48 | 49 | Thank you very much! 50 | Valek Filippov frob@df.ru 51 | (C)opyLeft 2001 -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/fonts/README.gentoo.tweaks: -------------------------------------------------------------------------------- 1 | Nimbus Sans L Regular, Nimbus Mono L Regular, Nimbus Mono L Oblique 2 | all come from a more recent version of the cyrillic URW fonts. 3 | 4 | The hints on Nimbus Sans Regular have been modified in the 5 | following ways: 6 | 7 | 25 June 2002 8 | 9 | - Added ghost hint to the top of 4 to keep it from being 10 | taller than the other digits. 11 | - Reduced the width of the left stem hint for H to 83 12 | (probably no real differences) 13 | - Changed the StemSnapV values from [78 85 94] to [78 83 92] 14 | (and fixed up StdVW accordingly) 15 | This corresponds to the values in the font (which are 83/93 16 | for lower case and upper case stems) better and makes 17 | the width-88 stems on M and N snap to to upper case 18 | widths not lower-case widths. 19 | 20 | 29 June 2002 21 | 22 | - Removed odd vertical stem hints (width of horizontal 23 | stems) from f, F, t, E, yen sign, fi ligature, 24 | fl ligature, AE ligature, R, Lstroke, OE ligature, 25 | lstroke, E" variants, t, variants, Eth, Dstoke, etc. 26 | - Fixed hints on 1 to be two ghost hints instead of one 27 | hint the height of the font 28 | - fix bottom stem of u to have integer coordinates 29 | - fixed hints on | 30 | - fixed hints on inverted exclamation mark 31 | 32 | The hints on Nimbus Mono L Oblique have been modified in the 33 | following ways: 34 | 35 | - Removed vertical stem hints from horizontal serifs on 36 | roman characters. 37 | 38 | Owen Taylor 39 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/fonts/n019003l.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/fonts/n019003l.pfb -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/glassBk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/glassBk.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/glassFG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/glassFG.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/node_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/node_selected.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/node_selected.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/node_selected.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/node_selected_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/node_selected_bw.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/panel2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/panel2.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/panel2.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/panel2.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/panel2_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/panel2_bg.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/panel2_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/panel2_border.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/skin.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// Skin 3 | 4 | local skin = { 5 | info = { 6 | name = "Robocracy", 7 | version = "0.3", 8 | author = "jK", 9 | } 10 | } 11 | 12 | --//============================================================================= 13 | --// 14 | 15 | skin.general = { 16 | focusColor = {1.0, 0.7, 0.1, 0.8}, 17 | borderColor = {1.0, 1.0, 1.0, 1.0}, 18 | 19 | font = { 20 | font = SKINDIR .. "fonts/n019003l.pfb", 21 | color = {1,1,1,1}, 22 | outlineColor = {0.05,0.05,0.05,0.9}, 23 | outline = false, 24 | shadow = true, 25 | size = 14, 26 | }, 27 | 28 | --padding = {5, 5, 5, 5}, --// padding: left, top, right, bottom 29 | } 30 | 31 | 32 | skin.icons = { 33 | imageplaceholder = ":cl:placeholder.png", 34 | } 35 | 36 | skin.button = { 37 | TileImageBK = ":cl:tech_button_bk.png", 38 | TileImageFG = ":cl:tech_button_fg.png", 39 | tiles = {22, 22, 22, 22}, --// tile widths: left,top,right,bottom 40 | padding = {10, 10, 10, 10}, 41 | 42 | backgroundColor = {1, 1, 1, 0.7}, 43 | borderColor = {1,1,1,0}, 44 | 45 | DrawControl = DrawButton, 46 | } 47 | 48 | skin.combobox = { 49 | TileImageBK = ":cl:combobox_ctrl.png", 50 | TileImageFG = ":cl:combobox_ctrl_fg.png", 51 | TileImageArrow = ":cl:combobox_ctrl_arrow.png", 52 | tiles = {22, 22, 48, 22}, 53 | padding = {10, 10, 24, 10}, 54 | 55 | backgroundColor = {1, 1, 1, 0.7}, 56 | borderColor = {1,1,1,0}, 57 | 58 | DrawControl = DrawComboBox, 59 | } 60 | 61 | 62 | skin.combobox_window = { 63 | clone = "window"; 64 | TileImage = ":cl:combobox_wnd.png"; 65 | tiles = {10, 10, 10, 10}; 66 | padding = {4, 3, 3, 4}; 67 | } 68 | 69 | 70 | skin.combobox_scrollpanel = { 71 | clone = "scrollpanel"; 72 | borderColor = {1, 1, 1, 0}; 73 | padding = {0, 0, 0, 0}; 74 | } 75 | 76 | 77 | skin.combobox_item = { 78 | clone = "button"; 79 | borderColor = {1, 1, 1, 0}; 80 | } 81 | 82 | 83 | skin.checkbox = { 84 | TileImageFG = ":cl:tech_checkbox_checked.png", 85 | TileImageBK = ":cl:tech_checkbox_unchecked.png", 86 | tiles = {3,3,3,3}, 87 | boxsize = 13, 88 | 89 | DrawControl = DrawCheckbox, 90 | } 91 | 92 | skin.editbox = { 93 | hintFont = table.merge({color = {1,1,1,0.7}}, skin.general.font), 94 | 95 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 96 | cursorColor = {1.0, 0.7, 0.1, 0.8}, 97 | 98 | TileImageBK = ":cl:panel2_bg.png", 99 | TileImageFG = ":cl:panel2_border.png", 100 | tiles = {14,14,14,14}, 101 | 102 | DrawControl = DrawEditBox, 103 | } 104 | 105 | skin.imagelistview = { 106 | imageFolder = "folder.png", 107 | imageFolderUp = "folder_up.png", 108 | 109 | --DrawControl = DrawBackground, 110 | 111 | colorBK = {1,1,1,0.3}, 112 | colorBK_selected = {1,0.7,0.1,0.8}, 113 | 114 | colorFG = {0, 0, 0, 0}, 115 | colorFG_selected = {1,1,1,1}, 116 | 117 | imageBK = ":cl:node_selected_bw.png", 118 | imageFG = ":cl:node_selected.png", 119 | tiles = {9, 9, 9, 9}, 120 | 121 | DrawItemBackground = DrawItemBkGnd, 122 | } 123 | --[[ 124 | skin.imagelistviewitem = { 125 | imageFG = ":cl:glassFG.png", 126 | imageBK = ":cl:glassBK.png", 127 | tiles = {17,15,17,20}, 128 | 129 | padding = {12, 12, 12, 12}, 130 | 131 | DrawSelectionItemBkGnd = DrawSelectionItemBkGnd, 132 | } 133 | --]] 134 | 135 | skin.panel = { 136 | TileImageBK = ":cl:tech_button.png", 137 | TileImageFG = ":cl:empty.png", 138 | tiles = {22, 22, 22, 22}, 139 | 140 | DrawControl = DrawPanel, 141 | } 142 | 143 | skin.progressbar = { 144 | TileImageFG = ":cl:tech_progressbar_full.png", 145 | TileImageBK = ":cl:tech_progressbar_empty.png", 146 | tiles = {10, 10, 10, 10}, 147 | 148 | font = { 149 | shadow = true, 150 | }, 151 | 152 | backgroundColor = {1,1,1,1}, 153 | 154 | DrawControl = DrawProgressbar, 155 | } 156 | 157 | skin.scrollpanel = { 158 | BorderTileImage = ":cl:panel2_border.png", 159 | bordertiles = {14,14,14,14}, 160 | 161 | BackgroundTileImage = ":cl:panel2_bg.png", 162 | bkgndtiles = {14,14,14,14}, 163 | 164 | TileImage = ":cl:tech_scrollbar.png", 165 | tiles = {7,7,7,7}, 166 | KnobTileImage = ":cl:tech_scrollbar_knob.png", 167 | KnobTiles = {6,8,6,8}, 168 | 169 | HTileImage = ":cl:tech_scrollbar.png", 170 | htiles = {7,7,7,7}, 171 | HKnobTileImage = ":cl:tech_scrollbar_knob.png", 172 | HKnobTiles = {6,8,6,8}, 173 | 174 | KnobColorSelected = {1,0.7,0.1,0.8}, 175 | 176 | padding = {5, 5, 5, 0}, 177 | 178 | scrollbarSize = 11, 179 | DrawControl = DrawScrollPanel, 180 | DrawControlPostChildren = DrawScrollPanelBorder, 181 | } 182 | 183 | skin.trackbar = { 184 | TileImage = ":cn:trackbar.png", 185 | tiles = {10, 14, 10, 14}, --// tile widths: left,top,right,bottom 186 | 187 | ThumbImage = ":cl:trackbar_thumb.png", 188 | StepImage = ":cl:trackbar_step.png", 189 | 190 | hitpadding = {4, 4, 5, 4}, 191 | 192 | DrawControl = DrawTrackbar, 193 | } 194 | 195 | skin.treeview = { 196 | --ImageNode = ":cl:node.png", 197 | ImageNodeSelected = ":cl:node_selected.png", 198 | tiles = {9, 9, 9, 9}, 199 | 200 | ImageExpanded = ":cl:treeview_node_expanded.png", 201 | ImageCollapsed = ":cl:treeview_node_collapsed.png", 202 | treeColor = {1,1,1,0.1}, 203 | 204 | DrawNode = DrawTreeviewNode, 205 | DrawNodeTree = DrawTreeviewNodeTree, 206 | } 207 | 208 | skin.window = { 209 | TileImage = ":c:tech_dragwindow.png", 210 | --TileImage = ":cl:tech_window.png", 211 | --TileImage = ":cl:window_tooltip.png", 212 | --tiles = {25, 25, 25, 25}, --// tile widths: left,top,right,bottom 213 | tiles = {62, 62, 62, 62}, --// tile widths: left,top,right,bottom 214 | padding = {13, 13, 13, 13}, 215 | hitpadding = {4, 4, 4, 4}, 216 | 217 | captionColor = {1, 1, 1, 0.45}, 218 | 219 | backgroundColor = {0.1, 0.1, 0.1, 0.7}, 220 | 221 | boxes = { 222 | resize = {-21, -21, -10, -10}, 223 | drag = {0, 0, "100%", 10}, 224 | }, 225 | 226 | NCHitTest = NCHitTestWithPadding, 227 | NCMouseDown = WindowNCMouseDown, 228 | NCMouseDownPostChildren = WindowNCMouseDownPostChildren, 229 | 230 | DrawControl = DrawWindow, 231 | DrawDragGrip = function() end, 232 | DrawResizeGrip = DrawResizeGrip, 233 | } 234 | 235 | skin.line = { 236 | TileImage = ":cl:tech_line.png", 237 | tiles = {0, 0, 0, 0}, 238 | TileImageV = ":cl:tech_line_vert.png", 239 | tilesV = {0, 0, 0, 0}, 240 | DrawControl = DrawLine, 241 | } 242 | 243 | skin.tabbar = { 244 | padding = {3, 1, 1, 0}, 245 | } 246 | 247 | skin.tabbaritem = { 248 | TileImageBK = ":cl:tech_tabbaritem_bk.png", 249 | TileImageFG = ":cl:tech_tabbaritem_fg.png", 250 | tiles = {10, 10, 10, 0}, --// tile widths: left,top,right,bottom 251 | padding = {5, 3, 3, 2}, 252 | backgroundColor = {1, 1, 1, 1.0}, 253 | 254 | DrawControl = DrawTabBarItem, 255 | } 256 | 257 | 258 | skin.control = skin.general 259 | 260 | 261 | --//============================================================================= 262 | --// 263 | 264 | return skin 265 | -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_button.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_button.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_button.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_button_bk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_button_bk.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_button_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_button_fg.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_buttonbk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_buttonbk.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_checkbox.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_checkbox.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_checkbox_checked.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_checkbox_unchecked.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_dragwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_dragwindow.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_dragwindow.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_dragwindow.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_line.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_line_vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_line_vert.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_progressbar.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_progressbar.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_progressbar_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_progressbar_empty.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_progressbar_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_progressbar_full.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_scrollbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_scrollbar.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_scrollbar.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_scrollbar.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_scrollbar_knob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_scrollbar_knob.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_scrollbar_knob.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_scrollbar_knob.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_tabbaritem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_tabbaritem.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_tabbaritem_bk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_tabbaritem_bk.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_tabbaritem_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_tabbaritem_fg.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_window.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/tech_window.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/tech_window.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/trackbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/trackbar.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/trackbar_step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/trackbar_step.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/trackbar_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/trackbar_thumb.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/treeview_node_collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/treeview_node_collapsed.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/treeview_node_expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/treeview_node_expanded.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/treeview_node_expanded_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/treeview_node_expanded_bw.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/window_tooltip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/window_tooltip.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/Robocracy/window_tooltip.psp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/Robocracy/window_tooltip.psp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/Sav33A.tmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/Sav33A.tmp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/Sav38D.tmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/Sav38D.tmp -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/empty.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/folder.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/folder_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/folder_up.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/placeholder.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/treeview_node_collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/treeview_node_collapsed.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/treeview_node_expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/treeview_node_expanded.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/tweak_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/tweak_overlay.png -------------------------------------------------------------------------------- /luaui/chili/chili/skins/default/tweak_overlay_resizable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jk3064/chiliui/a3a239637077b602c3531b14c2cac4fe12418953/luaui/chili/chili/skins/default/tweak_overlay_resizable.png -------------------------------------------------------------------------------- /luaui/chili/chili/themes/theme.lua: -------------------------------------------------------------------------------- 1 | --//============================================================================= 2 | --// Theme 3 | 4 | theme = {} 5 | 6 | theme.name = "default" 7 | 8 | 9 | --//============================================================================= 10 | --// Define default skins 11 | 12 | local defaultSkin = "Robocracy" 13 | --local defaultSkin = "DarkGlass" 14 | 15 | theme.skin = { 16 | general = { 17 | skinName = defaultSkin, 18 | }, 19 | 20 | imagelistview = { 21 | -- imageFolder = "luaui/images/folder.png", 22 | -- imageFolderUp = "luaui/images/folder_up.png", 23 | }, 24 | 25 | icons = { 26 | -- imageplaceholder = "luaui/images/placeholder.png", 27 | }, 28 | } 29 | 30 | 31 | --//============================================================================= 32 | --// Theme 33 | 34 | function theme.GetDefaultSkin(class) 35 | local skinName 36 | 37 | repeat 38 | skinName = theme.skin[class.classname].skinName 39 | class = class.inherited 40 | --FIXME check if the skin contains the current control class! if not use inherit the theme table before doing so in the skin 41 | until ((skinName)and(SkinHandler.IsValidSkin(skinName)))or(not class); 42 | 43 | if (not skinName)or(not SkinHandler.IsValidSkin(skinName)) then 44 | skinName = theme.skin.general.skinName 45 | end 46 | 47 | if (not skinName)or(not SkinHandler.IsValidSkin(skinName)) then 48 | skinName = "default" 49 | end 50 | 51 | return skinName 52 | end 53 | 54 | 55 | function theme.LoadThemeDefaults(control) 56 | if (theme.skin[control.classname]) 57 | then table.merge(control,theme.skin[control.classname]) end -- per-class defaults 58 | table.merge(control,theme.skin.general) 59 | end 60 | 61 | -------------------------------------------------------------------------------- /luaui/chili/chili/todo.txt: -------------------------------------------------------------------------------- 1 | - fix fixedRatio 1 pixel jumping 2 | 3 | - check all listeners if they use chili objects (doing so might break the garbage collection), if so replace them with weaklinks (debug.getupvalue & debug.setupvalue) 4 | 5 | - self:Resize(), OnResize 6 | - RenderToTexture 7 | - masks for HitTest (depending on linked textures-> alpha channel) 8 | - more different window controls -> background textures 9 | - use matrices for clientspace transformations 10 | - theme & layout handler 11 | 12 | controls: 13 | - combobox -------------------------------------------------------------------------------- /luaui/chili/dbg_chili_inspector.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -------------------------------------------------------------------------------- 3 | 4 | function widget:GetInfo() 5 | return { 6 | name = "ChiliInspector", 7 | desc = "", 8 | author = "", 9 | date = "2013", 10 | license = "GPLv2", 11 | layer = 3, 12 | enabled = false -- loaded by default? 13 | } 14 | end 15 | 16 | 17 | -------------------------------------------------------------------------------- 18 | -------------------------------------------------------------------------------- 19 | 20 | local Chili 21 | local window0 22 | local tree0 23 | local label0 24 | 25 | -------------------------------------------------------------------------------- 26 | -------------------------------------------------------------------------------- 27 | 28 | local function GetBooleanStr(b) 29 | return (b and "true") or "false" 30 | end 31 | 32 | local function trace(children, node, level, max_level) 33 | if not node then return end 34 | if (level or 0) > (max_level or math.huge) then return end 35 | for i=1,#children do 36 | local obj = children[i] 37 | if obj and (obj.name ~= "wnd_inspector") then 38 | local caption = ("%s: %s (redrawn: %i/%i)"):format(obj.classname, obj.name, obj._redrawSelfCounter or 0, obj._redrawCounter or 0) 39 | local nodec = node:Add(caption) 40 | trace(obj.children, nodec, (level or 0) + 1, max_level) 41 | end 42 | end 43 | end 44 | 45 | 46 | local function traceLost(node) 47 | 48 | for i,obj in pairs(Chili.DebugHandler.allObjects) do 49 | if obj.name ~= "wnd_inspector" then 50 | if (not obj.parent)and(not obj:InheritsFrom("screen")) then 51 | local caption = ("%s: %s (redrawn: %i; disposed: %s)"):format(obj.classname, obj.name, obj._redrawCounter or 0, GetBooleanStr(obj.disposed)) 52 | local nodec = node:Add(caption) 53 | trace(obj.children, nodec, 1, 1) 54 | end 55 | end 56 | end 57 | end 58 | 59 | 60 | local function tracePerWidget(node) 61 | collectgarbage("collect") 62 | for w,t in pairs(Chili.DebugHandler.objectsOwnedByWidgets) do 63 | if (w.whInfo.name ~= widget.whInfo.name) then 64 | local caption = ("%s"):format(w.whInfo.name) 65 | local nodec = node:Add(caption) 66 | for i,obj in pairs(t) do 67 | local caption = ("%s: %s (redrawn: %i)"):format(obj.classname, obj.name, obj._redrawCounter or 0) 68 | local nodec2 = nodec:Add(caption) 69 | end 70 | end 71 | end 72 | end 73 | 74 | -------------------------------------------------------------------------------- 75 | -------------------------------------------------------------------------------- 76 | 77 | function widget:Initialize() 78 | Chili = WG.Chili 79 | 80 | if (not Chili) then 81 | widgetHandler:RemoveWidget() 82 | return 83 | end 84 | 85 | window0 = Chili.Window:New{ 86 | name = "wnd_inspector", 87 | caption = "Chili Inspector", 88 | x = 1200, 89 | y = 250, 90 | width = 400, 91 | height = 400, 92 | parent = Chili.Screen0, 93 | 94 | children = { 95 | Chili.Label:New{ 96 | name = "lbl_inspector_memusage", 97 | x=0, right = 50, 98 | y=0, bottom=-25, 99 | align = "right", valign = "bottom", 100 | caption = "Lua MemUsage: 0MB", 101 | 102 | }, 103 | Chili.Button:New{ 104 | right = 0, width = 50, 105 | y=5, bottom=-25, 106 | caption="gc", 107 | OnMouseUp = {function() collectgarbage("collect") end}, 108 | }, 109 | Chili.ScrollPanel:New{ 110 | x=0, right=0, 111 | y=25, bottom=20, 112 | children = { 113 | Chili.TreeView:New{ 114 | name = "tree_inspector"; 115 | width="100%"; 116 | height="100%"; 117 | }, 118 | }, 119 | }, 120 | Chili.StackPanel:New{ 121 | x=0, right=0, 122 | y=-20, bottom=0, 123 | orientation = "horizontal", 124 | padding = {0,0,0,0}, 125 | itemMargin = {0,0,0,0}, 126 | itemPadding = {0,0,0,0}, 127 | children = { 128 | Chili.Button:New{ 129 | caption="visible objects", 130 | OnMouseUp = {function() tree0.root:Clear(); trace(Chili.Screen0.children, tree0.root) end}, 131 | }, 132 | Chili.Button:New{ 133 | caption="lost objects", 134 | OnMouseUp = {function() tree0.root:Clear(); traceLost(tree0.root) end}, 135 | }, 136 | Chili.Button:New{ 137 | caption="per widget", 138 | OnMouseUp = {function() tree0.root:Clear(); tracePerWidget(tree0.root) end}, 139 | }, 140 | }, 141 | }, 142 | }, 143 | } 144 | 145 | tree0 = window0:GetObjectByName("tree_inspector") 146 | label0 = window0:GetObjectByName("lbl_inspector_memusage") 147 | 148 | trace(Chili.Screen0.children, tree0.root) 149 | end 150 | 151 | function widget:Shutdown() 152 | if (window0) then 153 | window0:Dispose() 154 | end 155 | end 156 | 157 | local next = -math.huge 158 | function widget:Update() 159 | if (os.clock() <= next) then 160 | return 161 | end 162 | next = os.clock() + 3 163 | 164 | local curUsage, gcLimit = gcinfo() 165 | local caption = ("Lua MemUsage: %.2fMB"):format(curUsage / 1024) 166 | label0:SetCaption(caption) 167 | end 168 | -------------------------------------------------------------------------------- /luaui/chili/dbg_chili_profiler.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -------------------------------------------------------------------------------- 3 | 4 | function widget:GetInfo() 5 | return { 6 | name = "ChiliProfiler", 7 | desc = "", 8 | author = "", 9 | date = "2013", 10 | license = "GPLv2", 11 | layer = 2, 12 | enabled = false -- loaded by default? 13 | } 14 | end 15 | 16 | 17 | -------------------------------------------------------------------------------- 18 | -------------------------------------------------------------------------------- 19 | 20 | local window0 21 | local tree0 22 | local label0 23 | local Chili 24 | local profiling = false 25 | 26 | local sample_tree = {} 27 | local samples = 0 28 | 29 | local min_usage = 0.01 30 | 31 | -------------------------------------------------------------------------------- 32 | -------------------------------------------------------------------------------- 33 | 34 | local n = 0 35 | local s = 0 36 | local function trace(event, line) 37 | n = n + 1 38 | if (n < 25) then 39 | return 40 | end 41 | n = 0 42 | 43 | samples = samples + 1 44 | 45 | s = s + 1 46 | if (s > 10) then 47 | label0:SetCaption("Samples: " .. samples) 48 | s = 0 49 | end 50 | 51 | local j = 2 52 | local i = 666 53 | local top = true 54 | 55 | local alreadySampled = {} 56 | 57 | while (i) do 58 | repeat 59 | i = debug.getinfo(j, "nS") 60 | j = j + 1 61 | if (not i) then return end 62 | until not((not i.name) or i.what == "C" or i.what == "main" or i.source:find("\n") or i.source:find("(tail call)")) 63 | 64 | local s = i.source or "???" 65 | local n = i.name or "???" 66 | local l = i.linedefined or "???" 67 | n = ("%s (line: %s)"):format(n, l) 68 | 69 | local sampleName = ("%s%s%s"):format(s, n, l) 70 | if not alreadySampled[sampleName] then 71 | alreadySampled[sampleName] = true 72 | 73 | sample_tree[s] = sample_tree[s] or {} 74 | sample_tree[s][n] = sample_tree[s][n] or {0,0} 75 | sample_tree[s][n][1] = sample_tree[s][n][1] + 1 76 | if top and (j - 1 == 2) then 77 | sample_tree[s][n][2] = sample_tree[s][n][2] + 1 78 | top = false 79 | end 80 | end 81 | end 82 | end 83 | 84 | local function rendertree() 85 | tree0.root:ClearChildren() 86 | for s,t in pairs(sample_tree) do 87 | local node_file 88 | for f,c in pairs(t) do 89 | if (c[1]/samples > min_usage)or(c[2]/samples > min_usage) then 90 | local cap = ("%.1f%% (%.1f%%): %s"):format(100 * (c[1]/samples), 100 * (c[2]/samples), f) 91 | if not(node_file) then node_file = tree0.root:Add(s) end 92 | local nf = node_file:Add(cap) 93 | end 94 | end 95 | end 96 | end 97 | 98 | local function AddProfiler() 99 | if profiling then return end 100 | profiling = true 101 | debug.sethook(trace, "l", 16000000) 102 | end 103 | 104 | -------------------------------------------------------------------------------- 105 | -------------------------------------------------------------------------------- 106 | 107 | function widget:Initialize() 108 | Chili = WG.Chili 109 | 110 | if (not Chili) then 111 | widgetHandler:RemoveWidget() 112 | return 113 | end 114 | 115 | window0 = Chili.Window:New{ 116 | name = "wnd_profiler", 117 | caption = "Profiler"; 118 | x = 200, 119 | y = 450, 120 | width = 400, 121 | height = 400, 122 | parent = Chili.Screen0, 123 | layer = 1, 124 | 125 | children = { 126 | Chili.Label:New{ 127 | name = "lbl_profiler_samples", 128 | x=0, right=0, 129 | y=0, bottom=-20, 130 | align = "right", valign = "bottom", 131 | caption = "Samples: 0", 132 | }, 133 | Chili.ScrollPanel:New{ 134 | x=0, right=0, 135 | y=20, bottom=20, 136 | children = { 137 | Chili.TreeView:New{ 138 | name = "tree_profiler", 139 | x=0, right=0, 140 | y=0, bottom=0, 141 | defaultExpanded = true, 142 | }, 143 | }, 144 | }, 145 | Chili.Button:New{ 146 | x=0, right="50%", 147 | y=-20, bottom=0, 148 | caption="start", 149 | OnMouseUp = {AddProfiler}, 150 | }, 151 | Chili.Button:New{ 152 | x="50%", right=0, 153 | y=-20, bottom=0, 154 | caption = "stop", 155 | OnMouseUp = {function() debug.sethook( nil ); profiling = false; rendertree() end}, 156 | }, 157 | }, 158 | } 159 | 160 | tree0 = window0:GetObjectByName("tree_profiler") 161 | label0 = window0:GetObjectByName("lbl_profiler_samples") 162 | end 163 | 164 | function widget:Shutdown() 165 | debug.sethook( nil ) 166 | if (window0) then 167 | window0:Dispose() 168 | end 169 | end 170 | -------------------------------------------------------------------------------- /luaui/chili/generate_docs.sh: -------------------------------------------------------------------------------- 1 | ldoc chili 2 | -------------------------------------------------------------------------------- /modinfo.lua: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | name='Chili Framework', 4 | description="a GUI framework", 5 | version='$VERSION', 6 | modtype=0, 7 | } 8 | --------------------------------------------------------------------------------