diff --git a/TODO b/TODO index 3a01d48d..c5c23024 100644 --- a/TODO +++ b/TODO @@ -16,6 +16,7 @@ == Lua [bart] make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) [bart] bind every global lua function in static classes +[bart] review usage of x,y/width,height in lua instead of point/size == Platform [bart] port to MacOs and iphone @@ -101,4 +102,7 @@ if a spell is used while pressing arrows keys the walk is canceled and it doesnt game map text message boxes is not displayed like tibia name/shields doesnt follow the creature when walking on parcels hotkeys wont work with caps lock -hotkeys works while windows are locked, it shouldnt \ No newline at end of file +hotkeys works while windows are locked, it shouldnt + +-- current todo +allow usage of background width alone \ No newline at end of file diff --git a/modules/addon_mapeffects/mapeffects.lua b/modules/addon_mapeffects/mapeffects.lua index b6afd12c..152290b6 100644 --- a/modules/addon_mapeffects/mapeffects.lua +++ b/modules/addon_mapeffects/mapeffects.lua @@ -2,13 +2,15 @@ MapEffects = {} function MapEffects.init() --[[ - local box = createWidget('ComboBox') - box:moveTo({x=100, y=8}) + local box = createWidget('ComboBox', 'leftButtonsPanel') + box:addAnchor(AnchorLeft, 'prev', AnchorRight) + box:addAnchor(AnchorTop, 'parent', AnchorTop) + box:setMargin(6, 6) box:addOption('Normal') box:addOption('Bloom') box:addOption('TV') displayUI(box) - ]]-- +]]-- end function MapEffects.terminate() diff --git a/modules/addon_pingbar/pingbar.lua b/modules/addon_pingbar/pingbar.lua index c3b23c03..88e1dc22 100644 --- a/modules/addon_pingbar/pingbar.lua +++ b/modules/addon_pingbar/pingbar.lua @@ -21,7 +21,7 @@ end -- hooked events local function onGamePingUpdate(ping) - pingLabel:setText('Walk Ping: ' .. ping .. ' ms') + pingLabel:setText('Ping: ' .. ping .. ' ms') end connect(Game, { onWalkPingUpdate = onGamePingUpdate }) \ No newline at end of file diff --git a/modules/addon_terminal/terminal.otui b/modules/addon_terminal/terminal.otui index 0d6eec95..4437a644 100644 --- a/modules/addon_terminal/terminal.otui +++ b/modules/addon_terminal/terminal.otui @@ -2,10 +2,10 @@ TerminalLabel < UILabel font: terminus-14px-bold height: 16 -RectPanel +Panel id: terminalPanel background-color: #000000 - opacity: 216 + opacity: 0.85 anchors.fill: parent @onEscape: Terminal.hide() diff --git a/modules/client_background/background.otui b/modules/client_background/background.otui index c456e845..e9b13332 100644 --- a/modules/client_background/background.otui +++ b/modules/client_background/background.otui @@ -1,9 +1,8 @@ Panel id: background - image: - source: /client_background/background.png - smooth: true - fixed ratio: true + image-source: /client_background/background.png + image-smooth: true + image-fixed-ratio: true anchors.top: topMenu.bottom anchors.left: parent.left anchors.right: parent.right diff --git a/modules/client_entergame/characterlist.otui b/modules/client_entergame/characterlist.otui index bfbeea74..bf459cd8 100644 --- a/modules/client_entergame/characterlist.otui +++ b/modules/client_entergame/characterlist.otui @@ -1,12 +1,8 @@ CharacterListLabel < Label - image: /core_styles/images/empty_rect.png font: verdana-11px-monochrome - background-color: #00000000 + background-color: alpha text-offset: 2 0 focusable: true - margin-left: 1 - margin-right: 1 - margin-top: 1 $focus: background-color: #ffffff22 diff --git a/modules/client_topmenu/topmenu.otui b/modules/client_topmenu/topmenu.otui index 5a4c2b37..6a9b82b3 100644 --- a/modules/client_topmenu/topmenu.otui +++ b/modules/client_topmenu/topmenu.otui @@ -1,27 +1,22 @@ TopButton < UIButton - background-color: white size: 26 26 - text-translate: 0 0 - border-image: - source: /core_styles/images/top_button.png - clip: 0 0 26 26 - border: 3 + image-color: white + image-source: /core_styles/images/top_button.png + image-clip: 0 0 26 26 + image-border: 3 $hover: - border-image: - source: /core_styles/images/top_button.png - clip: 26 0 26 26 - border: 3 + image-source: /core_styles/images/top_button.png + image-clip: 26 0 26 26 + image-border: 3 $pressed: - text-translate: 1 1 - border-image: - source: /core_styles/images/top_button.png - clip: 52 0 26 26 - border: 3 + image-source: /core_styles/images/top_button.png + image-clip: 52 0 26 26 + image-border: 3 $disabled: - background-color: #ffffff66 + image-color: #ffffff66 TopLeftButton < TopButton $first: diff --git a/modules/core_lib/globals.lua b/modules/core_lib/globals.lua index 603699d2..65a58911 100644 --- a/modules/core_lib/globals.lua +++ b/modules/core_lib/globals.lua @@ -66,6 +66,9 @@ function createWidget(style, parent) local widget = class.create() if parent then + if type(parent) == 'string' then + parent = rootWidget:recursiveGetChildById(parent) + end parent:addChild(widget) end widget:setStyle(style) diff --git a/modules/core_styles/core_styles.otmod b/modules/core_styles/core_styles.otmod index 64707446..21515d05 100644 --- a/modules/core_styles/core_styles.otmod +++ b/modules/core_styles/core_styles.otmod @@ -11,6 +11,7 @@ Module importStyle 'styles/separators.otui' importStyle 'styles/lineedits.otui' importStyle 'styles/checkboxes.otui' + importStyle 'styles/progressbars.otui' importStyle 'styles/windows.otui' importStyle 'styles/listboxes.otui' importStyle 'styles/items.otui' diff --git a/modules/core_styles/icons/say.png b/modules/core_styles/icons/say.png new file mode 100644 index 00000000..adfa4a65 Binary files /dev/null and b/modules/core_styles/icons/say.png differ diff --git a/modules/core_styles/icons/whisper.png b/modules/core_styles/icons/whisper.png new file mode 100644 index 00000000..3da8e18c Binary files /dev/null and b/modules/core_styles/icons/whisper.png differ diff --git a/modules/core_styles/icons/yell.png b/modules/core_styles/icons/yell.png new file mode 100644 index 00000000..0c913a78 Binary files /dev/null and b/modules/core_styles/icons/yell.png differ diff --git a/modules/core_styles/images/empty_rect.png b/modules/core_styles/images/empty_rect.png deleted file mode 100644 index 3c087667..00000000 Binary files a/modules/core_styles/images/empty_rect.png and /dev/null differ diff --git a/modules/core_styles/images/empty_rounded_rect.png b/modules/core_styles/images/empty_rounded_rect.png deleted file mode 100644 index 62bd7055..00000000 Binary files a/modules/core_styles/images/empty_rounded_rect.png and /dev/null differ diff --git a/modules/core_styles/styles/buttons.otui b/modules/core_styles/styles/buttons.otui index d302568f..228f49ab 100644 --- a/modules/core_styles/styles/buttons.otui +++ b/modules/core_styles/styles/buttons.otui @@ -1,26 +1,23 @@ Button < UIButton font: verdana-11px-antialised - background-color: white color: #f0ad4dff size: 106 24 - text-translate: 0 0 + text-offset: 0 0 - border-image: - source: /core_styles/images/button.png - border: 5 + image-color: white + image-source: /core_styles/images/button.png + image-border: 5 $hover: - border-image: - source: /core_styles/images/button_hover.png - border: 5 + image-source: /core_styles/images/button_hover.png + image-border: 5 $pressed: - text-translate: 1 1 - border-image: - source: /core_styles/images/button_down.png - border: 5 + text-offset: 1 1 + image-source: /core_styles/images/button_down.png + image-border: 5 $disabled: color: #f0ad4d88 - background-color: #ffffff88 + image-color: #ffffff88 diff --git a/modules/core_styles/styles/checkboxes.otui b/modules/core_styles/styles/checkboxes.otui index dad43c63..0f675d17 100644 --- a/modules/core_styles/styles/checkboxes.otui +++ b/modules/core_styles/styles/checkboxes.otui @@ -2,41 +2,38 @@ CheckBox < UICheckBox size: 12 12 box-size: 12 12 text-align: left - text-offset: 16 -1 + text-offset: 16 0 color: #aaaaaa - background-color: #ffffffff + image-color: #ffffffff + image-rect: 0 0 12 12 $hover: color: #cccccc $!checked: - image: - source: /core_styles/images/checkbox.png - clip: 0 0 12 12 + image-source: /core_styles/images/checkbox.png + image-clip: 0 0 12 12 $hover !checked: - image: - source: /core_styles/images/checkbox.png - clip: 0 12 12 12 + image-source: /core_styles/images/checkbox.png + image-clip: 0 12 12 12 $checked: - image: - source: /core_styles/images/checkbox.png - clip: 0 24 12 12 + image-source: /core_styles/images/checkbox.png + image-clip: 0 24 12 12 $hover checked: - image: - source: /core_styles/images/checkbox.png - clip: 0 36 12 12 + image-source: /core_styles/images/checkbox.png + image-clip: 0 36 12 12 $disabled: - background-color: #ffffff88 + image-color: #ffffff88 color: #aaaaaa88 ColorBox < UICheckBox size: 16 16 box-size: 16 16 - background-color: #ffffffff + image-color: #ffffffff $checked: image: @@ -50,28 +47,25 @@ ColorBox < UICheckBox ButtonBox < UICheckBox font: verdana-11px-antialised - background-color: white color: #f0ad4dff size: 106 24 box-size: 106 24 text-offset: 0 0 text-align: center - border-image: - source: /core_styles/images/button.png - border: 5 + image-color: white + image-source: /core_styles/images/button.png + image-border: 5 $hover: - border-image: - source: /core_styles/images/button_hover.png - border: 5 + image-source: /core_styles/images/button_hover.png + image-border: 5 $checked: text-offset: 1 1 - border-image: - source: /core_styles/images/button_down.png - border: 5 + image-source: /core_styles/images/button_down.png + image-border: 5 $disabled: color: #f0ad4d88 - background-color: #ffffff88 + image-color: #ffffff88 diff --git a/modules/core_styles/styles/comboboxes.otui b/modules/core_styles/styles/comboboxes.otui index d2b8e14f..b0457cd3 100644 --- a/modules/core_styles/styles/comboboxes.otui +++ b/modules/core_styles/styles/comboboxes.otui @@ -1,6 +1,6 @@ ComboBoxPopupMenuButton < UIButton font: verdana-11px-antialised - background-color: alpha + image-color: alpha text-align: left text-offset: 2 0 color: #aaaaaa @@ -9,10 +9,7 @@ ComboBoxPopupMenuButton < UIButton margin-right: 1 margin-top: 0 margin-bottom: 0 - - image: - source: /core_styles/images/empty_rect.png - repeated: true + background-color: white $hover: color: #ffffff @@ -30,19 +27,17 @@ ComboBoxPopupMenuButton < UIButton ComboBoxPopupMenuSeparator < UIWidget margin-left: 1 margin-right: 1 - image: - source: /core_styles/images/combobox.png - repeated: true + image-source: /core_styles/images/combobox.png + image-repeated: true clip: 1 59 89 1 height: 1 phantom: true ComboBoxPopupMenu < UIPopupMenu - border-image: - source: /core_styles/images/combobox.png - clip: 0 60 89 20 - border: 1 - border.top: 0 + image-source: /core_styles/images/combobox.png + image-clip: 0 60 89 20 + image-border: 1 + image-border-top: 0 ComboBox < UIComboBox font: verdana-11px-antialised @@ -50,22 +45,19 @@ ComboBox < UIComboBox size: 86 20 text-offset: 3 0 text-align: left - border-image: - source: /core_styles/images/combobox.png - border: 1 - border.right: 17 - size: 89 20 + image-source: /core_styles/images/combobox.png + image-border: 1 + image-border-right: 17 + image-clip: 0 0 89 20 $hover: - border-image: - source: /core_styles/images/combobox.png - border: 1 - border.right: 17 - clip: 0 20 89 20 + image-source: /core_styles/images/combobox.png + image-border: 1 + image-border-right: 17 + image-clip: 0 20 89 20 $on: - border-image: - source: /core_styles/images/combobox.png - border: 1 - border.right: 17 - clip: 0 40 89 20 \ No newline at end of file + image-source: /core_styles/images/combobox.png + image-border: 1 + image-border-right: 17 + image-clip: 0 40 89 20 \ No newline at end of file diff --git a/modules/core_styles/styles/creatures.otui b/modules/core_styles/styles/creatures.otui index 80324482..6074d150 100644 --- a/modules/core_styles/styles/creatures.otui +++ b/modules/core_styles/styles/creatures.otui @@ -1,6 +1,5 @@ Creature < UICreature size: 66 66 padding: 1 - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 diff --git a/modules/core_styles/styles/items.otui b/modules/core_styles/styles/items.otui index 4b41db44..5ee47157 100644 --- a/modules/core_styles/styles/items.otui +++ b/modules/core_styles/styles/items.otui @@ -1,6 +1,5 @@ Item < UIItem size: 34 34 padding: 1 - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 diff --git a/modules/core_styles/styles/lineedits.otui b/modules/core_styles/styles/lineedits.otui index 01c2a492..18b25b72 100644 --- a/modules/core_styles/styles/lineedits.otui +++ b/modules/core_styles/styles/lineedits.otui @@ -3,9 +3,8 @@ LineEdit < UILineEdit color: #aaaaaa size: 86 20 text-margin: 3 - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 $disabled: color: #aaaaaa88 diff --git a/modules/core_styles/styles/listboxes.otui b/modules/core_styles/styles/listboxes.otui index 1c7c980c..92e2dc9f 100644 --- a/modules/core_styles/styles/listboxes.otui +++ b/modules/core_styles/styles/listboxes.otui @@ -1,5 +1,5 @@ TextList < UIWidget layout: verticalBox - border-image: - source: /core_styles/images/panel_flat.png - border: 4 \ No newline at end of file + border-width: 1 + border-color: #1d222b + background-color: #222833 \ No newline at end of file diff --git a/modules/core_styles/styles/panels.otui b/modules/core_styles/styles/panels.otui index 4dee070c..904b9603 100644 --- a/modules/core_styles/styles/panels.otui +++ b/modules/core_styles/styles/panels.otui @@ -1,34 +1,26 @@ Panel < UIWidget phantom: true -RectPanel < UIWidget - image: /core_styles/images/empty_rect.png - FlatPanel < Panel - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 TopPanel < Panel height: 36 - image: - source: /core_styles/images/top_panel.png - repeated: true + image-source: /core_styles/images/top_panel.png + image-repeated: true InterfacePanel < Panel focusable: false - border-image: - source: /core_styles/images/interface_panel.png - border: 4 + image-source: /core_styles/images/interface_panel.png + image-border: 4 InterfacePanel2 < Panel focusable: false - border-image: - source: /core_styles/images/interface_panel2.png - border: 4 + image-source: /core_styles/images/interface_panel2.png + image-border: 4 Map< UIMap padding: 4 - border-image: - source: /core_styles/images/map_panel.png - border: 4 + image-source: /core_styles/images/map_panel.png + image-border: 4 diff --git a/modules/core_styles/styles/popupmenus.otui b/modules/core_styles/styles/popupmenus.otui index c11c5622..b6c03ee0 100644 --- a/modules/core_styles/styles/popupmenus.otui +++ b/modules/core_styles/styles/popupmenus.otui @@ -1,16 +1,13 @@ PopupMenuButton < UIButton font: verdana-11px-antialised - background-color: alpha + image-color: alpha color: #aaaaaa height: 18 margin-left: 3 margin-right: 3 margin-top: 0 margin-bottom: 0 - - image: - source: /core_styles/images/empty_rect.png - repeated: true + background-color: alpha $hover: color: #ffffff @@ -28,16 +25,15 @@ PopupMenuButton < UIButton PopupMenuSeparator < UIWidget margin-left: 2 margin-right: 2 - border-image: - source: /core_styles/images/menubox.png - border.left: 1 - border.right: 1 - clip: 0 0 32 2 + image-source: /core_styles/images/menubox.png + image-border-left: 1 + image-border-right: 1 + image-clip: 0 0 32 2 height: 2 phantom: true PopupMenu < UIPopupMenu width: 50 border-image: - source: /core_styles/images/menubox.png - border: 3 \ No newline at end of file + image-source: /core_styles/images/menubox.png + image-border: 3 \ No newline at end of file diff --git a/modules/core_styles/styles/progressbars.otui b/modules/core_styles/styles/progressbars.otui new file mode 100644 index 00000000..86a6e3ce --- /dev/null +++ b/modules/core_styles/styles/progressbars.otui @@ -0,0 +1,4 @@ +ProgressBar < UIProgressBar + height: 15 + background-color: red + border: 1 black diff --git a/modules/core_styles/styles/separators.otui b/modules/core_styles/styles/separators.otui index 8ab0dc19..fd213b6f 100644 --- a/modules/core_styles/styles/separators.otui +++ b/modules/core_styles/styles/separators.otui @@ -1,7 +1,6 @@ HorizontalSeparator < UIWidget - border-image: - source: /core_styles/images/horizontal_separator.png - border.top: 2 + image-source: /core_styles/images/horizontal_separator.png + image-border.top: 2 height: 2 phantom: true focusable: false \ No newline at end of file diff --git a/modules/core_styles/styles/tabbars.otui b/modules/core_styles/styles/tabbars.otui new file mode 100644 index 00000000..ed4e10b4 --- /dev/null +++ b/modules/core_styles/styles/tabbars.otui @@ -0,0 +1,5 @@ +TabBar < UITabBar +TabBarTabButton < UIButton +TabBarCloseButton < UIButton +TabBarPrevButton < UIButton +TabBarNextButton < UIButton \ No newline at end of file diff --git a/modules/core_styles/styles/windows.otui b/modules/core_styles/styles/windows.otui index 7168c380..c51f877c 100644 --- a/modules/core_styles/styles/windows.otui +++ b/modules/core_styles/styles/windows.otui @@ -1,20 +1,18 @@ Window < UIWindow font: verdana-11px-antialised size: 200 200 - opacity: 255 + opacity: 1 color: white - background-color: white head-height: 20 head-text-align: center move-policy: free stackable: true - border-image: - source: /core_styles/images/window.png - border: 4 - border.top: 20 + image-source: /core_styles/images/window.png + image-border: 4 + image-border-top: 20 $pressed: - opacity: 192 + opacity: 0.75 $disabled: color: #aaaaaa88 @@ -28,10 +26,9 @@ MiniWindow < UIWindow margin-left: 6 margin-right: 6 move-policy: free updated - border-image: - source: /core_styles/images/mini_window.png - border: 4 - border.top: 25 + image-source: /core_styles/images/mini_window.png + image-border: 4 + image-border-top: 25 MainWindow < Window anchors.centerIn: parent diff --git a/modules/core_widgets/core_widgets.otmod b/modules/core_widgets/core_widgets.otmod index 7a6b2250..1b2b7db3 100644 --- a/modules/core_widgets/core_widgets.otmod +++ b/modules/core_widgets/core_widgets.otmod @@ -5,10 +5,12 @@ Module website: https://github.com/edubart/otclient onLoad: | - require 'tooltip/tooltip' - require 'messagebox/messagebox' require 'uiwidget' require 'uibutton' require 'uilabel' + require 'uicheckbox' require 'uicombobox' - require 'uipopupmenu' \ No newline at end of file + require 'uiprogressbar' + require 'uipopupmenu' + require 'tooltip/tooltip' + require 'messagebox/messagebox' \ No newline at end of file diff --git a/modules/core_widgets/tooltip/tooltip.lua b/modules/core_widgets/tooltip/tooltip.lua index 7bfb3d17..b890e925 100644 --- a/modules/core_widgets/tooltip/tooltip.lua +++ b/modules/core_widgets/tooltip/tooltip.lua @@ -13,7 +13,7 @@ local function moveToolTip(tooltip) else pos.x = pos.x + 10 end - tooltip:moveTo(pos) + tooltip:setPos(pos) end -- public functions @@ -28,7 +28,7 @@ function ToolTip.display(text) local size = label:getSize() size.width = size.width + 4 size.height = size.height + 4 - currentToolTip:resize(size) + currentToolTip:setSize(size) moveToolTip(currentToolTip) end end diff --git a/modules/core_widgets/tooltip/tooltip.otui b/modules/core_widgets/tooltip/tooltip.otui index 12ce8874..7777ac88 100644 --- a/modules/core_widgets/tooltip/tooltip.otui +++ b/modules/core_widgets/tooltip/tooltip.otui @@ -1,4 +1,4 @@ -RectPanel +Panel background-color: #111111bb size: 200 200 id: toolTip diff --git a/modules/core_widgets/uicheckbox.lua b/modules/core_widgets/uicheckbox.lua index bc010691..7ba4c97d 100644 --- a/modules/core_widgets/uicheckbox.lua +++ b/modules/core_widgets/uicheckbox.lua @@ -3,6 +3,12 @@ UICheckBox = extends(UIWidget) function UICheckBox.create() local checkbox = UICheckBox.internalCreate() checkbox:setFocusable(false) - checkbox:setAlign(AlignLeft) + checkbox:setTextAlign(AlignLeft) return checkbox end + +function UICheckBox:onMouseRelease(mousePos, mouseButton) + if self:isPressed() and self:containsPoint(mousePos) then + self:setChecked(not self:isChecked()) + end +end diff --git a/modules/core_widgets/uiprogressbar.lua b/modules/core_widgets/uiprogressbar.lua new file mode 100644 index 00000000..ff2ad0ba --- /dev/null +++ b/modules/core_widgets/uiprogressbar.lua @@ -0,0 +1,19 @@ +UIProgressBar = extends(UIWidget) + +function UIProgressBar.create() + local progressbar = UIProgressBar.internalCreate() + progressbar:setFocusable(false) + progressbar:setPhantom(true) + progressbar.percent = 100 + return progressbar +end + +function UIProgressBar:setPercent(percent) + self:setBackgroundHeight(self:getHeight()) + self:setBackgroundWidth((percent * self:getWidth())/100) + self.percent = percent +end + +function UIProgressBar:getPercent() + return self.percent +end diff --git a/modules/core_widgets/uitabbar.lua b/modules/core_widgets/uitabbar.lua new file mode 100644 index 00000000..585f6155 --- /dev/null +++ b/modules/core_widgets/uitabbar.lua @@ -0,0 +1 @@ +UITabBar = extends(UIWidget) diff --git a/modules/core_widgets/uiwidget.lua b/modules/core_widgets/uiwidget.lua index 88e82ca0..17e3cb9f 100644 --- a/modules/core_widgets/uiwidget.lua +++ b/modules/core_widgets/uiwidget.lua @@ -1,19 +1,19 @@ function UIWidget:setMargin(...) - local params = {...} - if #params == 1 then - self:setMarginTop(params[1]) - self:setMarginRight(params[1]) - self:setMarginBottom(params[1]) - self:setMarginLeft(params[1]) - elseif #params == 2 then - self:setMarginTop(params[1]) - self:setMarginRight(params[2]) - self:setMarginBottom(params[1]) - self:setMarginLeft(params[2]) - elseif #params == 4 then - self:setMarginTop(params[1]) - self:setMarginRight(params[2]) - self:setMarginBottom(params[3]) - self:setMarginLeft(params[4]) - end + local params = {...} + if #params == 1 then + self:setMarginTop(params[1]) + self:setMarginRight(params[1]) + self:setMarginBottom(params[1]) + self:setMarginLeft(params[1]) + elseif #params == 2 then + self:setMarginTop(params[1]) + self:setMarginRight(params[2]) + self:setMarginBottom(params[1]) + self:setMarginLeft(params[2]) + elseif #params == 4 then + self:setMarginTop(params[1]) + self:setMarginRight(params[2]) + self:setMarginBottom(params[3]) + self:setMarginLeft(params[4]) + end end diff --git a/modules/game_console/console.otui b/modules/game_console/console.otui index 340e874c..652469ad 100644 --- a/modules/game_console/console.otui +++ b/modules/game_console/console.otui @@ -3,6 +3,27 @@ ConsoleLabel < UILabel height: 14 color: yellow +SayModeButton < UIButton + size: 26 26 + icon: /core_styles/icons/say.png + image-source: /core_styles/images/top_button.png + image-color: white + image-clip: 0 0 26 26 + image-border: 3 + + $hover: + image-source: /core_styles/images/top_button.png + clip: 26 0 26 26 + border: 3 + + $pressed: + image-source: /core_styles/images/top_button.png + image-clip: 52 0 26 26 + image-border: 3 + + $disabled: + image-color: #ffffff66 + Panel id: consolePanel anchors.fill: parent @@ -22,9 +43,17 @@ Panel align-bottom: true focusable: false + SayModeButton + id: sayModeButton + size: 20 20 + anchors.left: parent.left + anchors.bottom: parent.bottom + margin-left: 6 + margin-bottom: 6 + LineEdit id: consoleLineEdit - anchors.left: parent.left + anchors.left: sayModeButton.right anchors.right: parent.right anchors.bottom: parent.bottom margin-right: 6 diff --git a/modules/game_healthbar/healthbar.otui b/modules/game_healthbar/healthbar.otui index 98338987..00da5179 100644 --- a/modules/game_healthbar/healthbar.otui +++ b/modules/game_healthbar/healthbar.otui @@ -1,15 +1,13 @@ -HealthBar < UIProgressBar +HealthBar < ProgressBar id: healthBar - color: black height: 15 background-color: red anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right -ManaBar < UIProgressBar +ManaBar < ProgressBar id: manaBar - color: black height: 15 background-color: blue anchors.bottom: parent.bottom diff --git a/modules/game_inventory/inventory.otui b/modules/game_inventory/inventory.otui index 64291125..b2f94a06 100644 --- a/modules/game_inventory/inventory.otui +++ b/modules/game_inventory/inventory.otui @@ -90,9 +90,8 @@ UIWindow text-align: center - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 GameLabel id: capacity @@ -104,7 +103,6 @@ UIWindow text-align: center - border-image: - source: /core_styles/images/panel_flat.png - border: 1 + image-source: /core_styles/images/panel_flat.png + image-border: 1 diff --git a/modules/game_skills/skills.otui b/modules/game_skills/skills.otui index 246f1f0f..ac0af983 100644 --- a/modules/game_skills/skills.otui +++ b/modules/game_skills/skills.otui @@ -22,9 +22,8 @@ SkillValueLabel < GameLabel anchors.bottom: parent.bottom anchors.left: prev.left -SkillPercentPanel < UIProgressBar +SkillPercentPanel < ProgressBar id: percent - color: black background-color: green height: 5 margin-top: 15 @@ -36,7 +35,7 @@ SkillPercentPanel < UIProgressBar MiniWindow id: skillWindow title: Skills - size: 200 400 + size: 200 310 Panel id: skillPanel @@ -60,7 +59,7 @@ MiniWindow text: Level SkillValueLabel SkillPercentPanel - background-color: red + image-color: red SkillButton id: health @@ -103,7 +102,7 @@ MiniWindow text: Magic Level SkillValueLabel SkillPercentPanel - background-color: red + image-color: red SkillButton id: skillId0 diff --git a/modules/game_viplist/viplist.otui b/modules/game_viplist/viplist.otui index 4711834a..a40918fa 100644 --- a/modules/game_viplist/viplist.otui +++ b/modules/game_viplist/viplist.otui @@ -8,11 +8,11 @@ MiniWindow id: vipWindow title: VIP List - TextList + UIWidget id: vipList - border-image: ~ + layout: verticalBox anchors.fill: parent - margin-top: 26 + margin-top: 27 margin-bottom: 6 margin-left: 6 margin-right: 6 diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index fc65aa43..8c0f0cc9 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -159,8 +159,6 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/graphics/framebuffer.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp - ${CMAKE_CURRENT_LIST_DIR}/graphics/borderimage.cpp - ${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particlesystem.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.cpp @@ -187,13 +185,14 @@ SET(framework_SOURCES ${framework_SOURCES} # framework ui ${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidget.cpp + ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetimage.cpp + ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgettext.cpp + ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetbasestyle.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiwindow.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiverticallayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilayout.cpp - ${CMAKE_CURRENT_LIST_DIR}/ui/uiprogressbar.cpp - ${CMAKE_CURRENT_LIST_DIR}/ui/uicheckbox.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiframecounter.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uitranslator.cpp diff --git a/src/framework/graphics/borderimage.cpp b/src/framework/graphics/borderimage.cpp deleted file mode 100644 index 66ecc2fd..00000000 --- a/src/framework/graphics/borderimage.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "borderimage.h" -#include "graphics.h" -#include "texture.h" -#include "texturemanager.h" - -#include - -BorderImage::BorderImage(TexturePtr texture, - const Rect& left, - const Rect& right, - const Rect& top, - const Rect& bottom, - const Rect& topLeft, - const Rect& topRight, - const Rect& bottomLeft, - const Rect& bottomRight, - const Rect& center) -{ - m_texture = texture; - m_leftBorderTexCoords = left; - m_rightBorderTexCoords = right; - m_topBorderTexCoords = top; - m_bottomBorderTexCoords = bottom; - m_topLeftCornerTexCoords = topLeft; - m_topRightCornerTexCoords = topRight; - m_bottomLeftCornerTexCoords = bottomLeft; - m_bottomRightCornerTexCoords = bottomRight; - m_centerTexCoords = center; - - m_bordersSize = Size(left.width() + right.width(), - top.height() + bottom.height()); - - m_defaultSize = Size(std::max(std::max(topLeft.width(), bottomLeft.width()), left.width()) + - std::max(std::max(topRight.width(), bottomRight.width()), right.width()) + - center.width(), - std::max(std::max(topLeft.height(), topRight.height()), top.height()) + - std::max(std::max(bottomLeft.height(), bottomRight.height()), bottom.height()) + - center.height()); -} - -BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode) -{ - Rect leftBorder; - Rect rightBorder; - Rect topBorder; - Rect bottomBorder; - Rect topLeftCorner; - Rect topRightCorner; - Rect bottomLeftCorner; - Rect bottomRightCorner; - Rect center; - Rect clipRect; - int top, bottom, left, right, border; - Size size; - Point offset; - - // load texture - std::string source = borderImageNode->at("source")->value(); - TexturePtr texture = g_textures.getTexture(source); - - // load basic border confs - border = borderImageNode->valueAt("border", 0); - clipRect = borderImageNode->valueAt("clip", Rect(0, 0, texture->getSize())); - - // load border margins - top = bottom = left = right = border; - top = borderImageNode->valueAt("border.top", top); - bottom = borderImageNode->valueAt("border.bottom", bottom); - left = borderImageNode->valueAt("border.left", left); - right = borderImageNode->valueAt("border.right", right); - - // calculates border coords - leftBorder = Rect(clipRect.left(), clipRect.top() + top, left, clipRect.height() - top - bottom); - rightBorder = Rect(clipRect.right() - right + 1, clipRect.top() + top, right, clipRect.height() - top - bottom); - topBorder = Rect(clipRect.left() + left, clipRect.top(), clipRect.width() - right - left, top); - bottomBorder = Rect(clipRect.left() + left, clipRect.bottom() - bottom + 1, clipRect.width() - right - left, bottom); - topLeftCorner = Rect(clipRect.left(), clipRect.top(), left, top); - topRightCorner = Rect(clipRect.right() - right + 1, clipRect.top(), right, top); - bottomLeftCorner = Rect(clipRect.left(), clipRect.bottom() - bottom + 1, left, bottom); - bottomRightCorner = Rect(clipRect.right() - right + 1, clipRect.bottom() - bottom + 1, right, bottom); - center = Rect(clipRect.left() + left, clipRect.top() + top, clipRect.width() - right - left, clipRect.height() - top - bottom); - - // load individual border conf if supplied - /* - leftBorder = borderImageNode->valueAt("left border", leftBorder); - rightBorder = borderImageNode->valueAt("right border", rightBorder); - topBorder = borderImageNode->valueAt("top border", topBorder); - bottomBorder = borderImageNode->valueAt("bottom border", bottomBorder); - topLeftCorner = borderImageNode->valueAt("top left corner", topLeftCorner); - topRightCorner = borderImageNode->valueAt("top right corner", topRightCorner); - bottomLeftCorner = borderImageNode->valueAt("bottom left corner", bottomLeftCorner); - bottomRightCorner = borderImageNode->valueAt("bottom right corner", bottomRightCorner); - center = borderImageNode->valueAt("center", center); - */ - - return BorderImagePtr(new BorderImage(texture, - leftBorder, - rightBorder, - topBorder, - bottomBorder, - topLeftCorner, - topRightCorner, - bottomLeftCorner, - bottomRightCorner, - center)); -} - -void BorderImage::draw(const Rect& screenCoords) -{ - //TODO: borderimage drawing could be optimized by caching the render into a texture - if(screenCoords != m_cachedScreenCoords) { - m_cachedScreenCoords = screenCoords; - m_coordsBuffer.clear(); - - Rect rectCoords; - Size centerSize = screenCoords.size() - m_bordersSize; - - // first the center - if(centerSize.area() > 0) { - rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(), - screenCoords.top() + m_topBorderTexCoords.height(), - centerSize); - m_coordsBuffer.addRepeatedRects(rectCoords, m_centerTexCoords); - } - - // top left corner - rectCoords = Rect(screenCoords.topLeft(), - m_topLeftCornerTexCoords.size()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_topLeftCornerTexCoords); - - // top - rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(), - screenCoords.topLeft().y, - centerSize.width(), - m_topBorderTexCoords.height()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_topBorderTexCoords); - - - // top right corner - rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(), - screenCoords.top(), - m_topRightCornerTexCoords.size()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_topRightCornerTexCoords); - - // left - rectCoords = Rect(screenCoords.left(), - screenCoords.top() + m_topLeftCornerTexCoords.height(), - m_leftBorderTexCoords.width(), - centerSize.height()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_leftBorderTexCoords); - - // right - rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(), - screenCoords.top() + m_topRightCornerTexCoords.height(), - m_rightBorderTexCoords.width(), - centerSize.height()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_rightBorderTexCoords); - - // bottom left corner - rectCoords = Rect(screenCoords.left(), - screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(), - m_bottomLeftCornerTexCoords.size()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomLeftCornerTexCoords); - - // bottom - rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(), - screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(), - centerSize.width(), - m_bottomBorderTexCoords.height()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomBorderTexCoords); - - // bottom right corner - rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(), - screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(), - m_bottomRightCornerTexCoords.size()); - m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomRightCornerTexCoords); - } - g_painter.drawTextureCoords(m_coordsBuffer, m_texture); -} \ No newline at end of file diff --git a/src/framework/graphics/borderimage.h b/src/framework/graphics/borderimage.h deleted file mode 100644 index 0399c86c..00000000 --- a/src/framework/graphics/borderimage.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef BORDERIMAGE_H -#define BORDERIMAGE_H - -#include "image.h" - -class BorderImage : public Image -{ -public: - BorderImage(TexturePtr texture, - const Rect& left, - const Rect& right, - const Rect& top, - const Rect& bottom, - const Rect& topLeft, - const Rect& topRight, - const Rect& bottomLeft, - const Rect& bottomRight, - const Rect& center); - - static BorderImagePtr loadFromOTML(const OTMLNodePtr& borderImageNode); - - void draw(const Rect& screenCoords); - - Size getDefaultSize() const { return m_defaultSize; } - -private: - Rect m_leftBorderTexCoords; - Rect m_rightBorderTexCoords; - Rect m_topBorderTexCoords; - Rect m_bottomBorderTexCoords; - - Rect m_topLeftCornerTexCoords; - Rect m_topRightCornerTexCoords; - Rect m_bottomLeftCornerTexCoords; - Rect m_bottomRightCornerTexCoords; - - Rect m_centerTexCoords; - - Size m_bordersSize; - Size m_defaultSize; -}; - -#endif diff --git a/src/framework/graphics/declarations.h b/src/framework/graphics/declarations.h index 3d3a4211..e2903c10 100644 --- a/src/framework/graphics/declarations.h +++ b/src/framework/graphics/declarations.h @@ -29,8 +29,6 @@ class Texture; class AnimatedTexture; class Font; -class Image; -class BorderImage; class FrameBuffer; class Shader; class ShaderProgram; @@ -46,8 +44,6 @@ typedef std::weak_ptr ParticleSystemWeakPtr; typedef std::shared_ptr TexturePtr; typedef std::shared_ptr AnimatedTexturePtr; typedef std::shared_ptr FontPtr; -typedef std::shared_ptr ImagePtr; -typedef std::shared_ptr BorderImagePtr; typedef std::shared_ptr FrameBufferPtr; typedef std::shared_ptr ShaderPtr; typedef std::shared_ptr ShaderProgramPtr; diff --git a/src/framework/graphics/framebuffer.cpp b/src/framework/graphics/framebuffer.cpp index e46df6bb..4917bf84 100644 --- a/src/framework/graphics/framebuffer.cpp +++ b/src/framework/graphics/framebuffer.cpp @@ -44,7 +44,7 @@ void FrameBuffer::resize(const Size& size) { internalBind(); m_texture = TexturePtr(new Texture(size.width(), size.height(), 4)); - m_texture->enableBilinearFilter(); + m_texture->setSmooth(true); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp deleted file mode 100644 index 63ca9775..00000000 --- a/src/framework/graphics/image.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "image.h" -#include "texture.h" -#include "graphics.h" -#include "texturemanager.h" - -#include - -Image::Image() -{ - m_fixedRatio = false; - m_repeated = false; -} - -void Image::loadFromOTML(const OTMLNodePtr& imageNode) -{ - // load configs from otml node - std::string source = imageNode->hasValue() ? imageNode->value() : imageNode->valueAt("source"); - bool smooth = imageNode->valueAt("smooth", false); - m_fixedRatio = imageNode->valueAt("fixed ratio", false); - m_repeated = imageNode->valueAt("repeated", false); - - // load texture - m_texture = g_textures.getTexture(source); - m_textureCoords = imageNode->valueAt("clip", Rect(0, 0, m_texture->getSize())); - - // enable texture bilinear filter - if(smooth) - m_texture->enableBilinearFilter(); -} - -void Image::draw(const Rect& screenCoords) -{ - if(!m_texture) - return; - - if(m_cachedScreenCoords != screenCoords) { - m_cachedScreenCoords = screenCoords; - m_coordsBuffer.clear(); - - if(m_fixedRatio) { - const Size& texSize = m_texture->getSize(); - Size texCoordsSize = screenCoords.size(); - texCoordsSize.scale(texSize, Fw::KeepAspectRatio); - Point texCoordsOffset; - if(texSize.height() > texCoordsSize.height()) - texCoordsOffset.y = (texSize.height() - texCoordsSize.height())/2; - else if(texSize.width() > texCoordsSize.width()) - texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2; - - m_coordsBuffer.addRect(screenCoords, Rect(texCoordsOffset, texCoordsSize)); - } else { - if(m_repeated) - m_coordsBuffer.addRepeatedRects(screenCoords, m_textureCoords); - else - m_coordsBuffer.addRect(screenCoords, m_textureCoords); - } - } - - g_painter.drawTextureCoords(m_coordsBuffer, m_texture); -} diff --git a/src/framework/graphics/image.h b/src/framework/graphics/image.h deleted file mode 100644 index 40beff52..00000000 --- a/src/framework/graphics/image.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef IMAGE_H -#define IMAGE_H - -#include "declarations.h" -#include "coordsbuffer.h" - -#include - -class Image -{ -public: - Image(); - - void loadFromOTML(const OTMLNodePtr& imageNode); - - virtual void draw(const Rect& screenCoords); - -protected: - TexturePtr m_texture; - Rect m_textureCoords; - bool m_fixedRatio; - bool m_repeated; - - Rect m_cachedScreenCoords; - CoordsBuffer m_coordsBuffer; -}; - -#endif diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index 8e6f5c6d..c53ec16b 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -51,13 +51,13 @@ public: void setColor(const Color& color) { m_currentColor = color; } Color getColor() { return m_currentColor; } - void setOpacity(int opacity) { m_currentOpacity = opacity / 255.0f; } - int getOpacity() { return m_currentOpacity * 255.0f; } + void setOpacity(float opacity) { m_currentOpacity = opacity; } + float getOpacity() { return m_currentOpacity; } void setCustomProgram(PainterShaderProgramPtr program); void releaseCustomProgram() { m_customProgram = nullptr; } void setCompositionMode(CompositionMode compositionMode); - + void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; } Matrix3 getProjectionMatrix() { return m_projectionMatrix; } diff --git a/src/framework/graphics/particle.cpp b/src/framework/graphics/particle.cpp index 32e045c4..91f8700a 100644 --- a/src/framework/graphics/particle.cpp +++ b/src/framework/graphics/particle.cpp @@ -91,7 +91,7 @@ void Particle::updatePosition(double elapsedTime) m_velocity += m_acceleration * elapsedTime; } - m_rect.moveTo((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2); + m_rect.move((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2); } void Particle::updateSize() diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index a63fbd89..bc9f746f 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -95,12 +95,23 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int return id; } -void Texture::enableBilinearFilter() +void Texture::setSmooth(bool smooth) { - // enable smooth texture - glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if(smooth == m_smooth) + return; + + if(smooth) { + // enable smooth texture + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + // nearest filtering (non smooth) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + m_smooth = true; } std::vector Texture::getPixels() diff --git a/src/framework/graphics/texture.h b/src/framework/graphics/texture.h index c9e572ef..095e44d7 100644 --- a/src/framework/graphics/texture.h +++ b/src/framework/graphics/texture.h @@ -32,7 +32,7 @@ public: Texture(int width, int height, int channels, uchar* pixels = NULL); virtual ~Texture(); - virtual void enableBilinearFilter(); + virtual void setSmooth(bool smooth); GLuint getId() { return m_textureId; } std::vector getPixels(); @@ -48,6 +48,7 @@ protected: GLuint m_textureId; Size m_size; + Boolean m_smooth; }; #endif diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 73c9af97..43ed3cf6 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -45,116 +45,7 @@ void Application::registerLuaFunctions() // UIWidget g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIWidgetPtr(new UIWidget); } ); - g_lua.bindClassMemberFunction("destroy", &UIWidget::destroy); - g_lua.bindClassMemberFunction("setVisible", &UIWidget::setVisible); - g_lua.bindClassMemberFunction("setEnabled", &UIWidget::setEnabled); - g_lua.bindClassMemberFunction("setChecked", &UICheckBox::setChecked); - g_lua.bindClassMemberFunction("setOn", &UICheckBox::setOn); - g_lua.bindClassMemberFunction("setPressed", &UIWidget::setPressed); - g_lua.bindClassMemberFunction("setId", &UIWidget::setId); - g_lua.bindClassMemberFunction("setFocusable", &UIWidget::setFocusable); - g_lua.bindClassMemberFunction("setPhantom", &UIWidget::setPhantom); - g_lua.bindClassMemberFunction("setStyle", &UIWidget::setStyle); - g_lua.bindClassMemberFunction("setStyleFromNode", &UIWidget::setStyleFromNode); - g_lua.bindClassMemberFunction("setLayout", &UIWidget::setLayout); - g_lua.bindClassMemberFunction("setParent", &UIWidget::setParent); - g_lua.bindClassMemberFunction("setRect", &UIWidget::setRect); - g_lua.bindClassMemberFunction("setX", &UIWidget::setX); - g_lua.bindClassMemberFunction("setY", &UIWidget::setY); - g_lua.bindClassMemberFunction("setWidth", &UIWidget::setWidth); - g_lua.bindClassMemberFunction("setHeight", &UIWidget::setHeight); - g_lua.bindClassMemberFunction("setIcon", &UIWidget::setIcon); - g_lua.bindClassMemberFunction("setOpacity", &UIWidget::setOpacity); - g_lua.bindClassMemberFunction("setBackgroundColor", &UIWidget::setBackgroundColor); - g_lua.bindClassMemberFunction("setColor", &UIWidget::setColor); - g_lua.bindClassMemberFunction("setMarginTop", &UIWidget::setMarginTop); - g_lua.bindClassMemberFunction("setMarginRight", &UIWidget::setMarginRight); - g_lua.bindClassMemberFunction("setMarginBottom", &UIWidget::setMarginBottom); - g_lua.bindClassMemberFunction("setMarginLeft", &UIWidget::setMarginLeft); - g_lua.bindClassMemberFunction("setText", &UIWidget::setText); - g_lua.bindClassMemberFunction("setTextAlign", &UIWidget::setTextAlign); - g_lua.bindClassMemberFunction("setTextOffset", &UIWidget::setTextOffset); - g_lua.bindClassMemberFunction("setFont", &UIWidget::setFont); - g_lua.bindClassMemberFunction("setSizeFixed", &UIWidget::setSizeFixed); - g_lua.bindClassMemberFunction("setLastFocusReason", &UIWidget::setLastFocusReason); - g_lua.bindClassMemberFunction("bindRectToParent", &UIWidget::bindRectToParent); - g_lua.bindClassMemberFunction("resize", &UIWidget::resize); - g_lua.bindClassMemberFunction("resizeToText", &UIWidget::resizeToText); - g_lua.bindClassMemberFunction("moveTo", &UIWidget::moveTo); - g_lua.bindClassMemberFunction("hide", &UIWidget::hide); - g_lua.bindClassMemberFunction("show", &UIWidget::show); - g_lua.bindClassMemberFunction("disable", &UIWidget::disable); - g_lua.bindClassMemberFunction("enable", &UIWidget::enable); - g_lua.bindClassMemberFunction("lock", &UIWidget::lock); - g_lua.bindClassMemberFunction("unlock", &UIWidget::unlock); - g_lua.bindClassMemberFunction("focus", &UIWidget::focus); - g_lua.bindClassMemberFunction("grabMouse", &UIWidget::grabMouse); - g_lua.bindClassMemberFunction("ungrabMouse", &UIWidget::ungrabMouse); - g_lua.bindClassMemberFunction("grabKeyboard", &UIWidget::grabKeyboard); - g_lua.bindClassMemberFunction("ungrabKeyboard", &UIWidget::ungrabKeyboard); - g_lua.bindClassMemberFunction("clearText", &UIWidget::clearText); - g_lua.bindClassMemberFunction("isActive", &UIWidget::isActive); - g_lua.bindClassMemberFunction("isEnabled", &UIWidget::isEnabled); - g_lua.bindClassMemberFunction("isDisabled", &UIWidget::isDisabled); - g_lua.bindClassMemberFunction("isFocused", &UIWidget::isFocused); - g_lua.bindClassMemberFunction("isHovered", &UIWidget::isHovered); - g_lua.bindClassMemberFunction("isPressed", &UIWidget::isPressed); - g_lua.bindClassMemberFunction("isFirst", &UIWidget::isFirst); - g_lua.bindClassMemberFunction("isMiddle", &UIWidget::isMiddle); - g_lua.bindClassMemberFunction("isLast", &UIWidget::isLast); - g_lua.bindClassMemberFunction("isAlternate", &UIWidget::isAlternate); - g_lua.bindClassMemberFunction("isVisible", &UIWidget::isVisible); - g_lua.bindClassMemberFunction("isOn", &UICheckBox::isOn); - g_lua.bindClassMemberFunction("isChecked", &UICheckBox::isChecked); - g_lua.bindClassMemberFunction("isHidden", &UIWidget::isHidden); - g_lua.bindClassMemberFunction("isExplicitlyEnabled", &UIWidget::isExplicitlyEnabled); - g_lua.bindClassMemberFunction("isExplicitlyVisible", &UIWidget::isExplicitlyVisible); - g_lua.bindClassMemberFunction("isFocusable", &UIWidget::isFocusable); - g_lua.bindClassMemberFunction("isPhantom", &UIWidget::isPhantom); - g_lua.bindClassMemberFunction("isSizeFixed", &UIWidget::isSizeFixed); - g_lua.bindClassMemberFunction("containsPoint", &UIWidget::containsPoint); - g_lua.bindClassMemberFunction("hasChildren", &UIWidget::hasChildren); - g_lua.bindClassMemberFunction("hasChild", &UIWidget::hasChild); - g_lua.bindClassMemberFunction("getId", &UIWidget::getId); - g_lua.bindClassMemberFunction("getChildCount", &UIWidget::getChildCount); - g_lua.bindClassMemberFunction("getLayout", &UIWidget::getLayout); - g_lua.bindClassMemberFunction("getParent", &UIWidget::getParent); - g_lua.bindClassMemberFunction("getRootParent", &UIWidget::getRootParent); - g_lua.bindClassMemberFunction("getPos", &UIWidget::getPos); - g_lua.bindClassMemberFunction("getSize", &UIWidget::getSize); - g_lua.bindClassMemberFunction("getRect", &UIWidget::getRect); - g_lua.bindClassMemberFunction("getX", &UIWidget::getX); - g_lua.bindClassMemberFunction("getY", &UIWidget::getY); - g_lua.bindClassMemberFunction("getWidth", &UIWidget::getWidth); - g_lua.bindClassMemberFunction("getHeight", &UIWidget::getHeight); - g_lua.bindClassMemberFunction("getColor", &UIWidget::getColor); - g_lua.bindClassMemberFunction("getBackgroundColor", &UIWidget::getBackgroundColor); - g_lua.bindClassMemberFunction("getOpacity", &UIWidget::getOpacity); - g_lua.bindClassMemberFunction("getMarginTop", &UIWidget::getMarginTop); - g_lua.bindClassMemberFunction("getMarginRight", &UIWidget::getMarginRight); - g_lua.bindClassMemberFunction("getMarginBottom", &UIWidget::getMarginBottom); - g_lua.bindClassMemberFunction("getMarginLeft", &UIWidget::getMarginLeft); - g_lua.bindClassMemberFunction("getText", &UIWidget::getText); - g_lua.bindClassMemberFunction("getTextAlign", &UIWidget::getTextAlign); - g_lua.bindClassMemberFunction("getTextOffset", &UIWidget::getTextOffset); - g_lua.bindClassMemberFunction("getFont", &UIWidget::getFont); - g_lua.bindClassMemberFunction("getTextSize", &UIWidget::getTextSize); - g_lua.bindClassMemberFunction("getLastFocusReason", &UIWidget::getLastFocusReason); - g_lua.bindClassMemberFunction("getStyle", &UIWidget::getStyle); - g_lua.bindClassMemberFunction("getStyleName", &UIWidget::getStyleName); - g_lua.bindClassMemberFunction("getChildren", &UIWidget::getChildren); - g_lua.bindClassMemberFunction("getFocusedChild", &UIWidget::getFocusedChild); - g_lua.bindClassMemberFunction("getChildAfter", &UIWidget::getChildAfter); - g_lua.bindClassMemberFunction("getChildBefore", &UIWidget::getChildBefore); - g_lua.bindClassMemberFunction("getChildById", &UIWidget::getChildById); - g_lua.bindClassMemberFunction("getChildByPos", &UIWidget::getChildByPos); - g_lua.bindClassMemberFunction("getChildByIndex", &UIWidget::getChildByIndex); - g_lua.bindClassMemberFunction("getFirstChild", &UIWidget::getFirstChild); - g_lua.bindClassMemberFunction("getLastChild", &UIWidget::getLastChild); - g_lua.bindClassMemberFunction("recursiveGetChildById", &UIWidget::recursiveGetChildById); - g_lua.bindClassMemberFunction("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos); - g_lua.bindClassMemberFunction("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById); + g_lua.bindClassStaticFunction("create", []{ return UIWidgetPtr(new UIWidget); }); g_lua.bindClassMemberFunction("addChild", &UIWidget::addChild); g_lua.bindClassMemberFunction("insertChild", &UIWidget::insertChild); g_lua.bindClassMemberFunction("removeChild", &UIWidget::removeChild); @@ -165,11 +56,217 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("moveChildToIndex", &UIWidget::moveChildToIndex); g_lua.bindClassMemberFunction("lockChild", &UIWidget::lockChild); g_lua.bindClassMemberFunction("unlockChild", &UIWidget::unlockChild); - g_lua.bindClassMemberFunction("isChildLocked", &UIWidget::isChildLocked); - g_lua.bindClassMemberFunction("getChildIndex", &UIWidget::getChildIndex); + g_lua.bindClassMemberFunction("applyStyle", &UIWidget::applyStyle); + g_lua.bindClassMemberFunction("addAnchor", &UIWidget::addAnchor); + g_lua.bindClassMemberFunction("fill", &UIWidget::fill); + g_lua.bindClassMemberFunction("centerIn", &UIWidget::centerIn); + g_lua.bindClassMemberFunction("breakAnchors", &UIWidget::breakAnchors); g_lua.bindClassMemberFunction("updateParentLayout", &UIWidget::updateParentLayout); g_lua.bindClassMemberFunction("updateLayout", &UIWidget::updateLayout); - g_lua.bindClassMemberFunction("applyStyle", &UIWidget::applyStyle); + g_lua.bindClassMemberFunction("lock", &UIWidget::lock); + g_lua.bindClassMemberFunction("unlock", &UIWidget::unlock); + g_lua.bindClassMemberFunction("focus", &UIWidget::focus); + g_lua.bindClassMemberFunction("grabMouse", &UIWidget::grabMouse); + g_lua.bindClassMemberFunction("ungrabMouse", &UIWidget::ungrabMouse); + g_lua.bindClassMemberFunction("grabKeyboard", &UIWidget::grabKeyboard); + g_lua.bindClassMemberFunction("ungrabKeyboard", &UIWidget::ungrabKeyboard); + g_lua.bindClassMemberFunction("bindRectToParent", &UIWidget::bindRectToParent); + g_lua.bindClassMemberFunction("destroy", &UIWidget::destroy); + g_lua.bindClassMemberFunction("setId", &UIWidget::setId); + g_lua.bindClassMemberFunction("setParent", &UIWidget::setParent); + g_lua.bindClassMemberFunction("setLayout", &UIWidget::setLayout); + g_lua.bindClassMemberFunction("setRect", &UIWidget::setRect); + g_lua.bindClassMemberFunction("setStyle", &UIWidget::setStyle); + g_lua.bindClassMemberFunction("setStyleFromNode", &UIWidget::setStyleFromNode); + g_lua.bindClassMemberFunction("setEnabled", &UIWidget::setEnabled); + g_lua.bindClassMemberFunction("setVisible", &UIWidget::setVisible); + g_lua.bindClassMemberFunction("setPressed", &UIWidget::setPressed); + g_lua.bindClassMemberFunction("setOn", &UIWidget::setOn); + g_lua.bindClassMemberFunction("setChecked", &UIWidget::setChecked); + g_lua.bindClassMemberFunction("setFocusable", &UIWidget::setFocusable); + g_lua.bindClassMemberFunction("setPhantom", &UIWidget::setPhantom); + g_lua.bindClassMemberFunction("setFixedSize", &UIWidget::setFixedSize); + g_lua.bindClassMemberFunction("setLastFocusReason", &UIWidget::setLastFocusReason); + g_lua.bindClassMemberFunction("isVisible", &UIWidget::isVisible); + g_lua.bindClassMemberFunction("isChildLocked", &UIWidget::isChildLocked); + g_lua.bindClassMemberFunction("hasChild", &UIWidget::hasChild); + g_lua.bindClassMemberFunction("getChildIndex", &UIWidget::getChildIndex); + g_lua.bindClassMemberFunction("getChildrenRect", &UIWidget::getChildrenRect); + g_lua.bindClassMemberFunction("getAnchoredLayout", &UIWidget::getAnchoredLayout); + g_lua.bindClassMemberFunction("getRootParent", &UIWidget::getRootParent); + g_lua.bindClassMemberFunction("getChildAfter", &UIWidget::getChildAfter); + g_lua.bindClassMemberFunction("getChildBefore", &UIWidget::getChildBefore); + g_lua.bindClassMemberFunction("getChildById", &UIWidget::getChildById); + g_lua.bindClassMemberFunction("getChildByPos", &UIWidget::getChildByPos); + g_lua.bindClassMemberFunction("getChildByIndex", &UIWidget::getChildByIndex); + g_lua.bindClassMemberFunction("recursiveGetChildById", &UIWidget::recursiveGetChildById); + g_lua.bindClassMemberFunction("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos); + g_lua.bindClassMemberFunction("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById); + g_lua.bindClassMemberFunction("asUIWidget", &UIWidget::asUIWidget); + g_lua.bindClassMemberFunction("resize", &UIWidget::resize); + g_lua.bindClassMemberFunction("move", &UIWidget::move); + g_lua.bindClassMemberFunction("hide", &UIWidget::hide); + g_lua.bindClassMemberFunction("show", &UIWidget::show); + g_lua.bindClassMemberFunction("disable", &UIWidget::disable); + g_lua.bindClassMemberFunction("enable", &UIWidget::enable); + g_lua.bindClassMemberFunction("isActive", &UIWidget::isActive); + g_lua.bindClassMemberFunction("isEnabled", &UIWidget::isEnabled); + g_lua.bindClassMemberFunction("isDisabled", &UIWidget::isDisabled); + g_lua.bindClassMemberFunction("isFocused", &UIWidget::isFocused); + g_lua.bindClassMemberFunction("isHovered", &UIWidget::isHovered); + g_lua.bindClassMemberFunction("isPressed", &UIWidget::isPressed); + g_lua.bindClassMemberFunction("isFirst", &UIWidget::isFirst); + g_lua.bindClassMemberFunction("isMiddle", &UIWidget::isMiddle); + g_lua.bindClassMemberFunction("isLast", &UIWidget::isLast); + g_lua.bindClassMemberFunction("isAlternate", &UIWidget::isAlternate); + g_lua.bindClassMemberFunction("isChecked", &UIWidget::isChecked); + g_lua.bindClassMemberFunction("isOn", &UIWidget::isOn); + g_lua.bindClassMemberFunction("isHidden", &UIWidget::isHidden); + g_lua.bindClassMemberFunction("isExplicitlyEnabled", &UIWidget::isExplicitlyEnabled); + g_lua.bindClassMemberFunction("isExplicitlyVisible", &UIWidget::isExplicitlyVisible); + g_lua.bindClassMemberFunction("isFocusable", &UIWidget::isFocusable); + g_lua.bindClassMemberFunction("isPhantom", &UIWidget::isPhantom); + g_lua.bindClassMemberFunction("isFixedSize", &UIWidget::isFixedSize); + g_lua.bindClassMemberFunction("isDestroyed", &UIWidget::isDestroyed); + g_lua.bindClassMemberFunction("hasChildren", &UIWidget::hasChildren); + g_lua.bindClassMemberFunction("containsPoint", &UIWidget::containsPoint); + g_lua.bindClassMemberFunction("getId", &UIWidget::getId); + g_lua.bindClassMemberFunction("getParent", &UIWidget::getParent); + g_lua.bindClassMemberFunction("getFocusedChild", &UIWidget::getFocusedChild); + g_lua.bindClassMemberFunction("getChildren", &UIWidget::getChildren); + g_lua.bindClassMemberFunction("getFirstChild", &UIWidget::getFirstChild); + g_lua.bindClassMemberFunction("getLastChild", &UIWidget::getLastChild); + g_lua.bindClassMemberFunction("getLayout", &UIWidget::getLayout); + g_lua.bindClassMemberFunction("getStyle", &UIWidget::getStyle); + g_lua.bindClassMemberFunction("getChildCount", &UIWidget::getChildCount); + g_lua.bindClassMemberFunction("getLastFocusReason", &UIWidget::getLastFocusReason); + g_lua.bindClassMemberFunction("getStyleName", &UIWidget::getStyleName); + g_lua.bindClassMemberFunction("setX", &UIWidget::setX); + g_lua.bindClassMemberFunction("setY", &UIWidget::setY); + g_lua.bindClassMemberFunction("setWidth", &UIWidget::setWidth); + g_lua.bindClassMemberFunction("setHeight", &UIWidget::setHeight); + g_lua.bindClassMemberFunction("setSize", &UIWidget::setSize); + g_lua.bindClassMemberFunction("setPos", &UIWidget::setPos); + g_lua.bindClassMemberFunction("setColor", &UIWidget::setColor); + g_lua.bindClassMemberFunction("setBackgroundColor", &UIWidget::setBackgroundColor); + g_lua.bindClassMemberFunction("setBackgroundOffsetX", &UIWidget::setBackgroundOffsetX); + g_lua.bindClassMemberFunction("setBackgroundOffsetY", &UIWidget::setBackgroundOffsetY); + g_lua.bindClassMemberFunction("setBackgroundOffset", &UIWidget::setBackgroundOffset); + g_lua.bindClassMemberFunction("setBackgroundWidth", &UIWidget::setBackgroundWidth); + g_lua.bindClassMemberFunction("setBackgroundHeight", &UIWidget::setBackgroundHeight); + g_lua.bindClassMemberFunction("setBackgroundSize", &UIWidget::setBackgroundSize); + g_lua.bindClassMemberFunction("setBackgroundRect", &UIWidget::setBackgroundRect); + g_lua.bindClassMemberFunction("setIcon", &UIWidget::setIcon); + g_lua.bindClassMemberFunction("setIconColor", &UIWidget::setIconColor); + g_lua.bindClassMemberFunction("setIconOffsetX", &UIWidget::setIconOffsetX); + g_lua.bindClassMemberFunction("setIconOffsetY", &UIWidget::setIconOffsetY); + g_lua.bindClassMemberFunction("setIconOffset", &UIWidget::setIconOffset); + g_lua.bindClassMemberFunction("setIconWidth", &UIWidget::setIconWidth); + g_lua.bindClassMemberFunction("setIconHeight", &UIWidget::setIconHeight); + g_lua.bindClassMemberFunction("setIconSize", &UIWidget::setIconSize); + g_lua.bindClassMemberFunction("setIconRect", &UIWidget::setIconRect); + g_lua.bindClassMemberFunction("setBorderWidth", &UIWidget::setBorderWidth); + g_lua.bindClassMemberFunction("setBorderColor", &UIWidget::setBorderColor); + g_lua.bindClassMemberFunction("setMargin", &UIWidget::setMargin); + g_lua.bindClassMemberFunction("setMarginHorizontal", &UIWidget::setMarginHorizontal); + g_lua.bindClassMemberFunction("setMarginVertical", &UIWidget::setMarginVertical); + g_lua.bindClassMemberFunction("setMarginTop", &UIWidget::setMarginTop); + g_lua.bindClassMemberFunction("setMarginRight", &UIWidget::setMarginRight); + g_lua.bindClassMemberFunction("setMarginBottom", &UIWidget::setMarginBottom); + g_lua.bindClassMemberFunction("setMarginLeft", &UIWidget::setMarginLeft); + g_lua.bindClassMemberFunction("setPadding", &UIWidget::setPadding); + g_lua.bindClassMemberFunction("setPaddingHorizontal", &UIWidget::setPaddingHorizontal); + g_lua.bindClassMemberFunction("setPaddingVertical", &UIWidget::setPaddingVertical); + g_lua.bindClassMemberFunction("setPaddingTop", &UIWidget::setPaddingTop); + g_lua.bindClassMemberFunction("setPaddingRight", &UIWidget::setPaddingRight); + g_lua.bindClassMemberFunction("setPaddingBottom", &UIWidget::setPaddingBottom); + g_lua.bindClassMemberFunction("setPaddingLeft", &UIWidget::setPaddingLeft); + g_lua.bindClassMemberFunction("setOpacity", &UIWidget::setOpacity); + g_lua.bindClassMemberFunction("getX", &UIWidget::getX); + g_lua.bindClassMemberFunction("getY", &UIWidget::getY); + g_lua.bindClassMemberFunction("getPos", &UIWidget::getPos); + g_lua.bindClassMemberFunction("getWidth", &UIWidget::getWidth); + g_lua.bindClassMemberFunction("getHeight", &UIWidget::getHeight); + g_lua.bindClassMemberFunction("getSize", &UIWidget::getSize); + g_lua.bindClassMemberFunction("getRect", &UIWidget::getRect); + g_lua.bindClassMemberFunction("getColor", &UIWidget::getColor); + g_lua.bindClassMemberFunction("getBackgroundColor", &UIWidget::getBackgroundColor); + g_lua.bindClassMemberFunction("getBackgroundOffsetX", &UIWidget::getBackgroundOffsetX); + g_lua.bindClassMemberFunction("getBackgroundOffsetY", &UIWidget::getBackgroundOffsetY); + g_lua.bindClassMemberFunction("getBackgroundOffset", &UIWidget::getBackgroundOffset); + g_lua.bindClassMemberFunction("getBackgroundWidth", &UIWidget::getBackgroundWidth); + g_lua.bindClassMemberFunction("getBackgroundHeight", &UIWidget::getBackgroundHeight); + g_lua.bindClassMemberFunction("getBackgroundSize", &UIWidget::getBackgroundSize); + g_lua.bindClassMemberFunction("getBackgroundRect", &UIWidget::getBackgroundRect); + g_lua.bindClassMemberFunction("getIconColor", &UIWidget::getIconColor); + g_lua.bindClassMemberFunction("getIconOffsetX", &UIWidget::getIconOffsetX); + g_lua.bindClassMemberFunction("getIconOffsetY", &UIWidget::getIconOffsetY); + g_lua.bindClassMemberFunction("getIconOffset", &UIWidget::getIconOffset); + g_lua.bindClassMemberFunction("getIconWidth", &UIWidget::getIconWidth); + g_lua.bindClassMemberFunction("getIconHeight", &UIWidget::getIconHeight); + g_lua.bindClassMemberFunction("getIconSize", &UIWidget::getIconSize); + g_lua.bindClassMemberFunction("getIconRect", &UIWidget::getIconRect); + g_lua.bindClassMemberFunction("getBorderTopColor", &UIWidget::getBorderTopColor); + g_lua.bindClassMemberFunction("getBorderRightColor", &UIWidget::getBorderRightColor); + g_lua.bindClassMemberFunction("getBorderBottomColor", &UIWidget::getBorderBottomColor); + g_lua.bindClassMemberFunction("getBorderLeftColor", &UIWidget::getBorderLeftColor); + g_lua.bindClassMemberFunction("getBorderTopWidth", &UIWidget::getBorderTopWidth); + g_lua.bindClassMemberFunction("getBorderRightWidth", &UIWidget::getBorderRightWidth); + g_lua.bindClassMemberFunction("getBorderBottomWidth", &UIWidget::getBorderBottomWidth); + g_lua.bindClassMemberFunction("getBorderLeftWidth", &UIWidget::getBorderLeftWidth); + g_lua.bindClassMemberFunction("getMarginTop", &UIWidget::getMarginTop); + g_lua.bindClassMemberFunction("getMarginRight", &UIWidget::getMarginRight); + g_lua.bindClassMemberFunction("getMarginBottom", &UIWidget::getMarginBottom); + g_lua.bindClassMemberFunction("getMarginLeft", &UIWidget::getMarginLeft); + g_lua.bindClassMemberFunction("getPaddingTop", &UIWidget::getPaddingTop); + g_lua.bindClassMemberFunction("getPaddingRight", &UIWidget::getPaddingRight); + g_lua.bindClassMemberFunction("getPaddingBottom", &UIWidget::getPaddingBottom); + g_lua.bindClassMemberFunction("getPaddingLeft", &UIWidget::getPaddingLeft); + g_lua.bindClassMemberFunction("getOpacity", &UIWidget::getOpacity); + g_lua.bindClassMemberFunction("setImageSource", &UIWidget::setImageSource); + g_lua.bindClassMemberFunction("setImageClip", &UIWidget::setImageClip); + g_lua.bindClassMemberFunction("setImageOffsetX", &UIWidget::setImageOffsetX); + g_lua.bindClassMemberFunction("setImageOffsetY", &UIWidget::setImageOffsetY); + g_lua.bindClassMemberFunction("setImageOffset", &UIWidget::setImageOffset); + g_lua.bindClassMemberFunction("setImageWidth", &UIWidget::setImageWidth); + g_lua.bindClassMemberFunction("setImageHeight", &UIWidget::setImageHeight); + g_lua.bindClassMemberFunction("setImageSize", &UIWidget::setImageSize); + g_lua.bindClassMemberFunction("setImageRect", &UIWidget::setImageRect); + g_lua.bindClassMemberFunction("setImageColor", &UIWidget::setImageColor); + g_lua.bindClassMemberFunction("setImageFixedRatio", &UIWidget::setImageFixedRatio); + g_lua.bindClassMemberFunction("setImageRepeated", &UIWidget::setImageRepeated); + g_lua.bindClassMemberFunction("setImageSmooth", &UIWidget::setImageSmooth); + g_lua.bindClassMemberFunction("setImageBorderTop", &UIWidget::setImageBorderTop); + g_lua.bindClassMemberFunction("setImageBorderRight", &UIWidget::setImageBorderRight); + g_lua.bindClassMemberFunction("setImageBorderBottom", &UIWidget::setImageBorderBottom); + g_lua.bindClassMemberFunction("setImageBorderLeft", &UIWidget::setImageBorderLeft); + g_lua.bindClassMemberFunction("setImageBorder", &UIWidget::setImageBorder); + g_lua.bindClassMemberFunction("getImageClip", &UIWidget::getImageClip); + g_lua.bindClassMemberFunction("getImageOffsetX", &UIWidget::getImageOffsetX); + g_lua.bindClassMemberFunction("getImageOffsetY", &UIWidget::getImageOffsetY); + g_lua.bindClassMemberFunction("getImageOffset", &UIWidget::getImageOffset); + g_lua.bindClassMemberFunction("getImageWidth", &UIWidget::getImageWidth); + g_lua.bindClassMemberFunction("getImageHeight", &UIWidget::getImageHeight); + g_lua.bindClassMemberFunction("getImageSize", &UIWidget::getImageSize); + g_lua.bindClassMemberFunction("getImageRect", &UIWidget::getImageRect); + g_lua.bindClassMemberFunction("getImageColor", &UIWidget::getImageColor); + g_lua.bindClassMemberFunction("isImageFixedRatio", &UIWidget::isImageFixedRatio); + g_lua.bindClassMemberFunction("isImageSmooth", &UIWidget::isImageSmooth); + g_lua.bindClassMemberFunction("getImageBorderTop", &UIWidget::getImageBorderTop); + g_lua.bindClassMemberFunction("getImageBorderRight", &UIWidget::getImageBorderRight); + g_lua.bindClassMemberFunction("getImageBorderBottom", &UIWidget::getImageBorderBottom); + g_lua.bindClassMemberFunction("getImageBorderLeft", &UIWidget::getImageBorderLeft); + g_lua.bindClassMemberFunction("resizeToText", &UIWidget::resizeToText); + g_lua.bindClassMemberFunction("clearText", &UIWidget::clearText); + g_lua.bindClassMemberFunction("setText", &UIWidget::setText); + g_lua.bindClassMemberFunction("setTextAlign", &UIWidget::setTextAlign); + g_lua.bindClassMemberFunction("setTextOffset", &UIWidget::setTextOffset); + g_lua.bindClassMemberFunction("setFont", &UIWidget::setFont); + g_lua.bindClassMemberFunction("getText", &UIWidget::getText); + g_lua.bindClassMemberFunction("getTextAlign", &UIWidget::getTextAlign); + g_lua.bindClassMemberFunction("getTextOffset", &UIWidget::getTextOffset); + g_lua.bindClassMemberFunction("getFont", &UIWidget::getFont); + g_lua.bindClassMemberFunction("getTextSize", &UIWidget::getTextSize); // UILayout g_lua.registerClass(); @@ -191,12 +288,6 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("centerIn", &UIAnchorLayout::centerIn); g_lua.bindClassMemberFunction("fill", &UIAnchorLayout::fill); - // UIProgressBar - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIProgressBarPtr(new UIProgressBar); } ); - g_lua.bindClassMemberFunction("getPercent", &UIProgressBar::getPercent); - g_lua.bindClassMemberFunction("setPercent", &UIProgressBar::setPercent); - // UILineEdit g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UILineEditPtr(new UILineEdit); } ); @@ -216,10 +307,6 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("isAlwaysActive", &UILineEdit::isAlwaysActive); g_lua.bindClassMemberFunction("isTextHidden", &UILineEdit::isTextHidden); - // UICheckBox - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UICheckBoxPtr(new UICheckBox); } ); - // UIWindow g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UIWindowPtr(new UIWindow); } ); diff --git a/src/framework/luascript/luavaluecasts.h b/src/framework/luascript/luavaluecasts.h index f933d441..da0cb0c8 100644 --- a/src/framework/luascript/luavaluecasts.h +++ b/src/framework/luascript/luavaluecasts.h @@ -40,6 +40,10 @@ bool luavalue_cast(int index, int& i); void push_luavalue(double d); bool luavalue_cast(int index, double& d); +// float +inline void push_luavalue(float f) { push_luavalue((double)f); } +inline bool luavalue_cast(int index, float& f) { double d; bool r = luavalue_cast(index, d); f = d; return r; } + // int8 inline void push_luavalue(int8 v) { push_luavalue((int)v); } inline bool luavalue_cast(int index, int8& v) { int i; bool r = luavalue_cast(index, i); v = i; return r; } diff --git a/src/framework/math/rect.h b/src/framework/math/rect.h index ecbc9320..98c90075 100644 --- a/src/framework/math/rect.h +++ b/src/framework/math/rect.h @@ -42,6 +42,7 @@ public: TRect(const TRect& other) : x1(other.x1), y1(other.y1), x2(other.x2), y2(other.y2) { } TRect(T x, T y, const TSize& size) : x1(x), y1(y), x2(x+size.width()-1), y2(y+size.height()-1) { } TRect(const TPoint& topLeft, const TSize& size) : x1(topLeft.x), y1(topLeft.y), x2(x1+size.width()-1), y2(y1+size.height()-1) { } + TRect(const TPoint& topLeft, int width, int height) : x1(topLeft.x), y1(topLeft.y), x2(x1+width-1), y2(y1+height-1) { } bool isNull() const { return x2 == x1 - 1 && y2 == y1 - 1; } bool isEmpty() const { return x1 > x2 || y1 > y2; } @@ -78,21 +79,23 @@ public: void setBottomLeft(const TPoint &p) { x1 = p.x; y2 = p.y; } void setWidth(T width) { x2 = x1 + width - 1; } void setHeight(T height) { y2 = y1 + height- 1; } - void resize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; } - void resize(const TSize& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; } + void setSize(const TSize& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; } void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); } void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; } - void addLeft(T add) { x1 -= add; } - void addTop(T add) { y1 -= add; } - void addRight(T add) { x2 += add; } - void addBottom(T add) { y2 += add; } - void add(T top, T right, T bottom, T left) { x1 -= left; y1 -= top; x2 += right; y2 += bottom; } + void expandLeft(T add) { x1 -= add; } + void expandTop(T add) { y1 -= add; } + void expandRight(T add) { x2 += add; } + void expandBottom(T add) { y2 += add; } + void expand(T top, T right, T bottom, T left) { x1 -= left; y1 -= top; x2 += right; y2 += bottom; } + void expand(T add) { x1 -= add; y1 -= add; x2 += add; y2 += add; } void translate(T x, T y) { x1 += x; y1 += y; x2 += x; y2 += y; } void translate(const TPoint &p) { x1 += p.x; y1 += p.y; x2 += p.x; y2 += p.y; } - void moveTo(T x, T y) { x2 += x - x1; y2 += y - y1; x1 = x; y1 = y; } - void moveTo(const TPoint &p) { x2 += p.x - x1; y2 += p.y - y1; x1 = p.x; y1 = p.y; } + void resize(const TSize& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; } + void resize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; } + void move(T x, T y) { x2 += x - x1; y2 += y - y1; x1 = x; y1 = y; } + void move(const TPoint &p) { x2 += p.x - x1; y2 += p.y - y1; x1 = p.x; y1 = p.y; } void moveLeft(T pos) { x2 += (pos - x1); x1 = pos; } void moveTop(T pos) { y2 += (pos - y1); y1 = pos; } void moveRight(T pos) { x1 += (pos - x2); x2 = pos; } @@ -105,7 +108,7 @@ public: TRect translated(int x, int y) const { return TRect(TPoint(x1 + x, y1 + y), TPoint(x2 + x, y2 + y)); } TRect translated(const TPoint &p) const { return TRect(TPoint(x1 + p.x, y1 + p.y), TPoint(x2 + p.x, y2 + p.y)); } - TRect expanded(T pixels) const { return TRect(TPoint(x1 - pixels, y1 - pixels), TPoint(x2 + pixels, y2 + pixels)); } + TRect expanded(T add) const { return TRect(TPoint(x1 - add, y1 - add), TPoint(x2 + add, y2 + add)); } void moveCenter(const TPoint &p) { T w = x2 - x1; diff --git a/src/framework/ui/declarations.h b/src/framework/ui/declarations.h index b5d4c53c..4edcd4bd 100644 --- a/src/framework/ui/declarations.h +++ b/src/framework/ui/declarations.h @@ -27,11 +27,7 @@ class UIManager; class UIWidget; -class UILabel; -class UIButton; class UILineEdit; -class UICheckBox; -class UIProgressBar; class UIFrameCounter; class UIWindow; class UILayout; @@ -41,11 +37,7 @@ class UIAnchorLayout; typedef std::shared_ptr UIWidgetPtr; typedef std::weak_ptr UIWidgetWeakPtr; -typedef std::shared_ptr UILabelPtr; -typedef std::shared_ptr UIButtonPtr; typedef std::shared_ptr UILineEditPtr; -typedef std::shared_ptr UICheckBoxPtr; -typedef std::shared_ptr UIProgressBarPtr; typedef std::shared_ptr UIFrameCounterPtr; typedef std::shared_ptr UIWindowPtr; typedef std::shared_ptr UILayoutPtr; diff --git a/src/framework/ui/ui.h b/src/framework/ui/ui.h index 6316c91f..b4932993 100644 --- a/src/framework/ui/ui.h +++ b/src/framework/ui/ui.h @@ -28,8 +28,6 @@ #include "uilineedit.h" #include "uiwindow.h" #include "uiframecounter.h" -#include "uiprogressbar.h" -#include "uicheckbox.h" #include "uilayout.h" #include "uiverticallayout.h" #include "uianchorlayout.h" diff --git a/src/framework/ui/uicheckbox.cpp b/src/framework/ui/uicheckbox.cpp deleted file mode 100644 index ab480aae..00000000 --- a/src/framework/ui/uicheckbox.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uicheckbox.h" -#include "uitranslator.h" -#include -#include -#include -#include -#include - -UICheckBox::UICheckBox() -{ - m_focusable = false; - m_textAlign = Fw::AlignLeft; -} - -void UICheckBox::render() -{ - if(m_image) { - Rect boxRect; - boxRect.resize(m_boxSize); - boxRect.moveLeft(m_rect.left()); - boxRect.moveVerticalCenter(m_rect.verticalCenter()); - g_painter.setColor(m_backgroundColor); - m_image->draw(boxRect); - } - - if(m_text.length()) { - Rect textRect(m_rect); - textRect.setTopLeft(textRect.topLeft() + m_textOffset); - m_font->renderText(m_text, textRect, m_textAlign, m_color); - } -} - -void UICheckBox::onMouseRelease(const Point& mousePos, Fw::MouseButton button) -{ - if(isPressed() && getRect().contains(mousePos)) - setChecked(!isChecked()); -} - -void UICheckBox::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(OTMLNodePtr node : styleNode->children()) { - if(node->tag() == "text-offset") - m_textOffset = node->value(); - else if(node->tag() == "text") - m_text = node->value(); - else if(node->tag() == "box-size") - m_boxSize = node->value(); - else if(node->tag() == "text-align") - m_textAlign = Fw::translateAlignment(node->value()); - else if(node->tag() == "checked") { - // must be scheduled because setChecked can change the style again - g_dispatcher.addEvent(std::bind(&UICheckBox::setChecked, asUICheckBox(), node->value())); - } - } -} diff --git a/src/framework/ui/uicheckbox.h b/src/framework/ui/uicheckbox.h deleted file mode 100644 index e7c92bf1..00000000 --- a/src/framework/ui/uicheckbox.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UICHECKBOX_H -#define UICHECKBOX_H - -#include "uiwidget.h" - -class UICheckBox : public UIWidget -{ -public: - UICheckBox(); - void render(); - - void setText(const std::string& text) { m_text = text; } - std::string getText() { return m_text; } - - UICheckBoxPtr asUICheckBox() { return std::static_pointer_cast(shared_from_this()); } - -protected: - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button); - - std::string m_text; - Size m_boxSize; - Point m_textOffset; - Fw::AlignmentFlag m_textAlign; -}; - -#endif diff --git a/src/framework/ui/uiframecounter.cpp b/src/framework/ui/uiframecounter.cpp index cbfa41b9..792ab842 100644 --- a/src/framework/ui/uiframecounter.cpp +++ b/src/framework/ui/uiframecounter.cpp @@ -36,9 +36,9 @@ UIFrameCounter::UIFrameCounter() m_frameCount = 0; } -void UIFrameCounter::render() +void UIFrameCounter::draw() { - UIWidget::render(); + UIWidget::draw(); if(g_clock.ticksElapsed(m_lastFrameTicks) >= 1000) { m_fpsText = Fw::mkstr("FPS: ", m_frameCount); diff --git a/src/framework/ui/uiframecounter.h b/src/framework/ui/uiframecounter.h index 97035215..d6890543 100644 --- a/src/framework/ui/uiframecounter.h +++ b/src/framework/ui/uiframecounter.h @@ -29,7 +29,7 @@ class UIFrameCounter : public UIWidget { public: UIFrameCounter(); - virtual void render(); + virtual void draw(); void setAlign(Fw::AlignmentFlag align) { m_align = align; } Fw::AlignmentFlag getAlign() { return m_align; } diff --git a/src/framework/ui/uiimage.cpp b/src/framework/ui/uiimage.cpp deleted file mode 100644 index cffb7004..00000000 --- a/src/framework/ui/uiimage.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "uiimage.h" -#include - -void UIImage::draw(const Rect& screenCoords) -{ - -} - -void UIImage::applyStyle(const OTMLNodePtr& styleNode) -{ - /* - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "image-source") - setImageSource(node->value()); - else if(node->tag() == "image-clip") - setImageClip(node->value()); - else if(node->tag() == "image-rect") - setImageRect(node->value()); - else if(node->tag() == "image-fixed-ratio") - setImageFixedRatio(node->value()); - else if(node->tag() == "image-repeated") - setImageRepeated(node->value()); - else if(node->tag() == "image-smooth") - setImageSmooth(node->value()); - else if(node->tag() == "image-color") - setImageColor(node->value()); - else if(node->tag() == "image-border-top") - setImageBorderTop(node->value()); - else if(node->tag() == "image-border-right") - setImageBorderRight(node->value()); - else if(node->tag() == "image-border-bottom") - setImageBorderBottom(node->value()); - else if(node->tag() == "image-border-left") - setImageBorderLeft(node->value()); - else if(node->tag() == "image-border") { - - } - } - */ -} - diff --git a/src/framework/ui/uiimage.h b/src/framework/ui/uiimage.h deleted file mode 100644 index 37a8913f..00000000 --- a/src/framework/ui/uiimage.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIIMAGE_H -#define UIIMAGE_H - -#include -#include -#include "declarations.h" - -class UIImage -{ -public: - void draw(const Rect& screenCoords); - void applyStyle(const OTMLNodePtr& styleNode); - - void setImageSource(const std::string& source); - void setImageClip(const Rect& clipRect); - void setImageRect(const Rect& rect); - void setImageFixedRatio(bool fixedRatio); - void setImageRepeated(bool repeated); - void setImageSmooth(bool smooth); - void setImageColor(const Color& color); - void setImageBorderTop(int border); - void setImageBorderRight(int border); - void setImageBorderBottom(int border); - void setImageBorderLeft(int border); - -protected: - TexturePtr m_imageTexture; - Rect m_imageClipRect; - Rect m_imageRect; - Boolean m_imageFixedRatio; - Boolean m_imageRepeated; - Color m_imageColor; - - // border image coords - Rect m_leftBorderTexCoords; - Rect m_rightBorderTexCoords; - Rect m_topBorderTexCoords; - Rect m_bottomBorderTexCoords; - Rect m_topLeftCornerTexCoords; - Rect m_topRightCornerTexCoords; - Rect m_bottomLeftCornerTexCoords; - Rect m_bottomRightCornerTexCoords; - Rect m_centerTexCoords; - Size m_bordersSize; -}; - -#endif diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index 8b80f73a..1021a417 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -26,6 +26,9 @@ void UILayout::update() { + if(m_updateDisabled) + return; + assert(!m_updating); m_updating = true; internalUpdate(); @@ -34,7 +37,7 @@ void UILayout::update() void UILayout::updateLater() { - if(m_updateScheduled) + if(m_updateDisabled || m_updateScheduled) return; if(!getParentWidget()) diff --git a/src/framework/ui/uilayout.h b/src/framework/ui/uilayout.h index b4cfc0de..f834c54e 100644 --- a/src/framework/ui/uilayout.h +++ b/src/framework/ui/uilayout.h @@ -38,9 +38,13 @@ public: virtual void applyStyle(const OTMLNodePtr& styleNode) { } virtual void addWidget(const UIWidgetPtr& widget) = 0; virtual void removeWidget(const UIWidgetPtr& widget) = 0; + void disableUpdates() { m_updateDisabled = true; } + void enableUpdates() { m_updateDisabled = false; } + void setParent(UIWidgetPtr parentWidget) { m_parentWidget = parentWidget; } UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); } + bool isUpdateDisabled() { return m_updateDisabled; } bool isUpdating() { return m_updating; } virtual bool needsUpdatesOnChildChange() { return false; } @@ -51,6 +55,7 @@ public: protected: virtual void internalUpdate() = 0; + Boolean m_updateDisabled; Boolean m_updating; Boolean m_updateScheduled; UIWidgetWeakPtr m_parentWidget; diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index a0df09b5..40149114 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -38,7 +38,7 @@ UILineEdit::UILineEdit() blinkCursor(); } -void UILineEdit::renderSelf() +void UILineEdit::drawSelf() { drawBackground(m_rect); drawBorder(m_rect); @@ -140,8 +140,8 @@ void UILineEdit::update() } Rect textScreenCoords = m_rect; - textScreenCoords.addLeft(-m_textHorizontalMargin); - textScreenCoords.addRight(-m_textHorizontalMargin); + textScreenCoords.expandLeft(-m_textHorizontalMargin); + textScreenCoords.expandRight(-m_textHorizontalMargin); m_drawArea = textScreenCoords; if(m_textAlign & Fw::AlignBottom) { @@ -339,8 +339,8 @@ int UILineEdit::getTextPos(Point pos) int candidatePos = -1; for(int i=0;igetYOffset() + m_font->getGlyphSpacing().height()); - clickGlyphRect.addLeft(m_font->getGlyphSpacing().width()+1); + clickGlyphRect.expandTop(m_font->getYOffset() + m_font->getGlyphSpacing().height()); + clickGlyphRect.expandLeft(m_font->getGlyphSpacing().width()+1); if(clickGlyphRect.contains(pos)) return i; else if(pos.y >= clickGlyphRect.top() && pos.y <= clickGlyphRect.bottom()) { diff --git a/src/framework/ui/uilineedit.h b/src/framework/ui/uilineedit.h index 467d904a..1cb73d7f 100644 --- a/src/framework/ui/uilineedit.h +++ b/src/framework/ui/uilineedit.h @@ -30,7 +30,7 @@ class UILineEdit : public UIWidget public: UILineEdit(); - virtual void renderSelf(); + virtual void drawSelf(); private: void update(); diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index ec79d0f7..5245a919 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -47,12 +47,12 @@ void UIManager::terminate() void UIManager::render() { - m_rootWidget->render(); + m_rootWidget->draw(); } void UIManager::resize(const Size& size) { - m_rootWidget->resize(g_window.getSize()); + m_rootWidget->setSize(g_window.getSize()); } void UIManager::inputEvent(const InputEvent& event) diff --git a/src/framework/ui/uiprogressbar.cpp b/src/framework/ui/uiprogressbar.cpp deleted file mode 100644 index 6373a233..00000000 --- a/src/framework/ui/uiprogressbar.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiprogressbar.h" -#include -#include - -UIProgressBar::UIProgressBar() -{ - m_phantom = false; - m_focusable = false; - m_percent = 0; -} - -void UIProgressBar::render() -{ - UIWidget::render(); - - g_painter.setColor(m_color); - g_painter.drawBoundingRect(m_rect, 1); - - Rect fillRect = m_rect.expanded(-1); - fillRect.setWidth(fillRect.width() * m_percent / 100.0); - - g_painter.setColor(m_backgroundColor); - g_painter.drawFilledRect(fillRect); -} - -void UIProgressBar::setPercent(double percent) -{ - if(percent == NAN) - percent = 0; - m_percent = std::min(std::max(percent, 0.0), 100.0); -} diff --git a/src/framework/ui/uiprogressbar.h b/src/framework/ui/uiprogressbar.h deleted file mode 100644 index 459e45b5..00000000 --- a/src/framework/ui/uiprogressbar.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIPROGRESSBAR_H -#define UIPROGRESSBAR_H - -#include "uiwidget.h" - -class UIProgressBar : public UIWidget -{ -public: - UIProgressBar(); - virtual void render(); - - void setPercent(double percent); - double getPercent() { return m_percent; } - -private: - double m_percent; -}; - -#endif diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index 548c0b74..2f81c6e3 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -97,7 +97,7 @@ void UIVerticalLayout::internalUpdate() pos.y += gap; prefferedHeight += gap; - if(widget->isSizeFixed()) { + if(widget->isFixedSize()) { // center it pos.x = childrenRect.left() + (childrenRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2; pos.x = std::max(pos.x, parentWidget->getX()); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 5d85b44e..cc81d58d 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -23,13 +23,9 @@ #include "uiwidget.h" #include "uimanager.h" #include "uianchorlayout.h" -#include "uiverticallayout.h" #include "uitranslator.h" #include -#include -#include -#include #include #include #include @@ -39,79 +35,55 @@ UIWidget::UIWidget() { m_lastFocusReason = Fw::ActiveFocusReason; m_states = Fw::DefaultState; - m_font = g_fonts.getDefaultFont(); - m_opacity = 255; - m_marginTop = m_marginRight = m_marginBottom = m_marginLeft = 0; - m_paddingTop = m_paddingRight = m_paddingBottom = m_paddingLeft = 0; - //m_backgroundColor = Fw::alpha; - m_backgroundColor = Fw::white; - m_color = Fw::white; - m_textAlign = Fw::AlignCenter; - // generate an unique id, this is need because anchored layouts find widgets by id - static unsigned long id = 1; - m_id = Fw::mkstr("widget", id++); + initBaseStyle(); + initText(); + initImage(); } -void UIWidget::destroy() +UIWidget::~UIWidget() { - if(m_destroyed) - logWarning("attempt to destroy widget '", m_id, "' two times"); - - setVisible(false); - setEnabled(false); - - // release input grabs - if(g_ui.getKeyboardReceiver() == asUIWidget()) - g_ui.resetKeyboardReceiver(); - - if(g_ui.getMouseReceiver() == asUIWidget()) - g_ui.resetMouseReceiver(); - - // remove itself from parent - if(UIWidgetPtr parent = getParent()) { - if(parent->hasChild(asUIWidget())) - parent->removeChild(asUIWidget()); - } - - callLuaField("onDestroy"); - - m_destroyed = true; + // nothing to do } -void UIWidget::render() +void UIWidget::draw() { - renderSelf(); - renderChildren(); + drawSelf(); + drawChildren(); } -void UIWidget::renderSelf() +void UIWidget::drawSelf() { // draw style components in order - drawBackground(m_rect); + if(m_backgroundColor.a() > 0) { + Rect backgroundDestRect = m_rect; + backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); + drawBackground(m_rect); + } + drawBorder(m_rect); drawImage(m_rect); drawIcon(m_rect); drawText(m_rect); } -void UIWidget::renderChildren() +void UIWidget::drawChildren() { // draw children for(const UIWidgetPtr& child : m_children) { - // render only visible children with a valid rect inside our rect + // render only visible children with a valid rect inside parent rect if(child->isExplicitlyVisible() && child->getRect().isValid() && - child->getRect().intersects(m_rect) && - child->getOpacity() > 0) { + child->getOpacity() > 0.0f && + child->getRect().intersects(m_rect)) { // store current graphics opacity - int oldOpacity = g_painter.getOpacity(); + float oldOpacity = g_painter.getOpacity(); // decrease to self opacity if(child->getOpacity() < oldOpacity) g_painter.setOpacity(child->getOpacity()); - child->render(); + child->draw(); // debug draw box if(g_ui.isDrawingDebugBoxes()) { @@ -125,406 +97,6 @@ void UIWidget::renderChildren() } } -void UIWidget::drawBackground(const Rect& screenCoords) -{ - /* - if(m_backgroundColor.a() > 0) { - g_painter.setColor(m_backgroundColor); - g_painter.drawFilledRect(screenCoords); - //g_painter.drawFilledRect(screenCoords.expanded(-m_borderWidth)); - } - */ -} - -void UIWidget::drawBorder(const Rect& screenCoords) -{ - /* - if(m_borderWidth > 0 && m_borderColor.a() > 0) { - g_painter.bindColor(m_borderColor); - g_painter.drawBoundingRect(screenCoords, m_borderWidth); - } - */ -} - -void UIWidget::drawImage(const Rect& screenCoords) -{ - if(m_image) { - g_painter.setColor(m_backgroundColor); - m_image->draw(screenCoords); - } -} - -void UIWidget::drawIcon(const Rect& screenCoords) -{ - if(m_icon) { - Rect iconRect; - iconRect.resize(m_icon->getSize()); - iconRect.moveCenter(screenCoords.center()); - g_painter.setColor(Fw::white); - g_painter.drawTexturedRect(iconRect, m_icon); - } -} - -void UIWidget::drawText(const Rect& screenCoords) -{ - g_painter.setColor(m_color); - if(m_text.length() > 0 && m_color.a() > 0) { - Rect textRect = screenCoords; - textRect.translate(m_textOffset); - m_font->renderText(m_text, textRect, m_textAlign, m_color); - } -} - -void UIWidget::setVisible(bool visible) -{ - if(m_visible != visible) { - m_visible = visible; - - // make parent focus another child - if(!visible && isFocused()) { - if(UIWidgetPtr parent = getParent()) - parent->focusPreviousChild(Fw::ActiveFocusReason); - } - - updateState(Fw::ActiveState); - updateState(Fw::HoverState); - } -} - -void UIWidget::setEnabled(bool enabled) -{ - if(enabled != m_enabled) { - m_enabled = enabled; - - updateState(Fw::DisabledState); - updateState(Fw::ActiveState); - updateState(Fw::HoverState); - } -} - -void UIWidget::setPressed(bool pressed) -{ - if(pressed != m_pressed) { - m_pressed = pressed; - updateState(Fw::PressedState); - } -} - -void UIWidget::setOn(bool on) -{ - setState(Fw::OnState, on); -} - -void UIWidget::setChecked(bool checked) -{ - if(setState(Fw::CheckedState, checked)) - callLuaField("onCheckChange", checked); -} - -void UIWidget::setFocusable(bool focusable) -{ - if(m_focusable != focusable) { - m_focusable = focusable; - - // make parent focus another child - if(!focusable && isFocused()) { - if(UIWidgetPtr parent = getParent()) - parent->focusPreviousChild(Fw::ActiveFocusReason); - } - } -} - -void UIWidget::setStyle(const std::string& styleName) -{ - OTMLNodePtr styleNode = g_ui.getStyle(styleName); - if(!styleNode) { - logTraceError("unable to retrive style '", styleName, "': not a defined style"); - return; - } - applyStyle(styleNode); - m_style = styleNode; - assert(getStyleName() != ""); - updateStyle(); -} - -void UIWidget::setStyleFromNode(const OTMLNodePtr& styleNode) -{ - applyStyle(styleNode); - m_style = styleNode; - updateStyle(); -} - -void UIWidget::setParent(const UIWidgetPtr& parent) -{ - // remove from old parent - UIWidgetPtr oldParent = getParent(); - - // the parent is already the same - if(oldParent == parent) - return; - - UIWidgetPtr self = asUIWidget(); - if(oldParent && oldParent->hasChild(self)) - oldParent->removeChild(self); - - // reset parent - m_parent.reset(); - - // set new parent - if(parent) { - m_parent = parent; - - // add to parent if needed - if(!parent->hasChild(self)) - parent->addChild(self); - } -} - -void UIWidget::setRect(const Rect& rect) -{ - // only update if the rect really changed - Rect oldRect = m_rect; - if(rect == oldRect) - return; - - m_rect = rect; - - // updates own layout - updateLayout(); - - // avoid massive update events - if(!m_updateEventScheduled) { - UIWidgetPtr self = asUIWidget(); - g_dispatcher.addEvent([self, oldRect]() { - self->m_updateEventScheduled = false; - if(oldRect != self->getRect()) - self->onGeometryChange(oldRect, self->getRect()); - }); - m_updateEventScheduled = true; - } -} - -void UIWidget::setIcon(const std::string& iconFile) -{ - m_icon = g_textures.getTexture(iconFile); -} - -void UIWidget::setText(const std::string& text) -{ - if(m_text != text) { - m_text = text; - - // update rect size - if(!m_rect.isValid()) { - Size textSize = m_font->calculateTextRectSize(m_text); - Size newSize = getSize(); - if(newSize.width() <= 0) - newSize.setWidth(textSize.width()); - if(newSize.height() <= 0) - newSize.setHeight(textSize.height()); - resize(newSize); - } - - onTextChange(text); - } -} - -void UIWidget::setFont(const std::string& fontName) -{ - m_font = g_fonts.getFont(fontName); -} - -void UIWidget::bindRectToParent() -{ - Rect boundRect = m_rect; - UIWidgetPtr parent = getParent(); - if(parent) { - Rect parentRect = parent->getRect(); - boundRect.bound(parentRect); - } - - setRect(boundRect); -} - -void UIWidget::lock() -{ - if(UIWidgetPtr parent = getParent()) - parent->lockChild(asUIWidget()); -} - -void UIWidget::unlock() -{ - if(UIWidgetPtr parent = getParent()) - parent->unlockChild(asUIWidget()); -} - -void UIWidget::focus() -{ - if(!m_focusable) - return; - if(UIWidgetPtr parent = getParent()) - parent->focusChild(asUIWidget(), Fw::ActiveFocusReason); -} - -void UIWidget::grabMouse() -{ - g_ui.setMouseReceiver(asUIWidget()); -} - -void UIWidget::ungrabMouse() -{ - if(g_ui.getMouseReceiver() == asUIWidget()) - g_ui.resetMouseReceiver(); -} - -void UIWidget::grabKeyboard() -{ - g_ui.setKeyboardReceiver(asUIWidget()); -} - -void UIWidget::ungrabKeyboard() -{ - if(g_ui.getKeyboardReceiver() == asUIWidget()) - g_ui.resetKeyboardReceiver(); -} - -bool UIWidget::isVisible() -{ - if(!m_visible) - return false; - else if(UIWidgetPtr parent = getParent()) - return parent->isVisible(); - else - return asUIWidget() == g_ui.getRootWidget(); -} - -bool UIWidget::hasChild(const UIWidgetPtr& child) -{ - auto it = std::find(m_children.begin(), m_children.end(), child); - if(it != m_children.end()) - return true; - return false; -} - -Rect UIWidget::getChildrenRect() -{ - Rect rect = m_rect; - rect.add(-m_paddingTop, -m_paddingRight, -m_paddingBottom, -m_paddingLeft); - return rect; -} - -UIWidgetPtr UIWidget::getRootParent() -{ - if(UIWidgetPtr parent = getParent()) - return parent->getRootParent(); - else - return asUIWidget(); -} - -UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) -{ - auto it = std::find(m_children.begin(), m_children.end(), relativeChild); - if(it != m_children.end() && ++it != m_children.end()) - return *it; - return nullptr; -} - -UIWidgetPtr UIWidget::getChildBefore(const UIWidgetPtr& relativeChild) -{ - auto it = std::find(m_children.rbegin(), m_children.rend(), relativeChild); - if(it != m_children.rend() && ++it != m_children.rend()) - return *it; - return nullptr; -} - -UIWidgetPtr UIWidget::getChildById(const std::string& childId) -{ - for(const UIWidgetPtr& child : m_children) { - if(child->getId() == childId) - return child; - } - return nullptr; -} - -UIWidgetPtr UIWidget::getChildByPos(const Point& childPos) -{ - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& widget = (*it); - if(widget->isExplicitlyVisible() && widget->containsPoint(childPos)) - return widget; - } - - return nullptr; -} - -UIWidgetPtr UIWidget::getChildByIndex(int index) -{ - index = index <= 0 ? (m_children.size() + index) : index-1; - if(index >= 0 && (uint)index < m_children.size()) - return m_children.at(index); - return nullptr; -} - -UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& id) -{ - UIWidgetPtr widget = getChildById(id); - if(!widget) { - for(const UIWidgetPtr& child : m_children) { - widget = child->recursiveGetChildById(id); - if(widget) - break; - } - } - return widget; -} - -UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos) -{ - for(const UIWidgetPtr& child : m_children) { - if(child->containsPoint(childPos)) { - if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos)) - return subChild; - return child; - } - } - return nullptr; -} - -UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id) -{ - UIWidgetPtr widget = getChildById(id); - if(!widget) { - if(UIWidgetPtr parent = getParent()) - widget = parent->backwardsGetWidgetById(id); - } - return widget; -} - -void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason) -{ - if(child && !hasChild(child)) { - logError("Attempt to focus an unknown child in a UIWidget"); - return; - } - - if(child != m_focusedChild) { - UIWidgetPtr oldFocused = m_focusedChild; - m_focusedChild = child; - - if(child) { - child->setLastFocusReason(reason); - child->updateState(Fw::FocusState); - child->updateState(Fw::ActiveState); - } - - if(oldFocused) { - oldFocused->setLastFocusReason(reason); - oldFocused->updateState(Fw::FocusState); - oldFocused->updateState(Fw::ActiveState); - } - } -} - void UIWidget::addChild(const UIWidgetPtr& child) { if(!child) { @@ -618,6 +190,32 @@ void UIWidget::removeChild(const UIWidgetPtr& child) logError("Attempt to remove an unknown child from a UIWidget"); } + +void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason) +{ + if(child && !hasChild(child)) { + logError("Attempt to focus an unknown child in a UIWidget"); + return; + } + + if(child != m_focusedChild) { + UIWidgetPtr oldFocused = m_focusedChild; + m_focusedChild = child; + + if(child) { + child->setLastFocusReason(reason); + child->updateState(Fw::FocusState); + child->updateState(Fw::ActiveState); + } + + if(oldFocused) { + oldFocused->setLastFocusReason(reason); + oldFocused->updateState(Fw::FocusState); + oldFocused->updateState(Fw::ActiveState); + } + } +} + void UIWidget::focusNextChild(Fw::FocusReason reason) { UIWidgetPtr toFocus; @@ -764,21 +362,54 @@ void UIWidget::unlockChild(const UIWidgetPtr& child) } } -bool UIWidget::isChildLocked(const UIWidgetPtr& child) +void UIWidget::applyStyle(const OTMLNodePtr& styleNode) { - auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child); - return it != m_lockedChildren.end(); + try { + m_loadingStyle = true; + onStyleApply(styleNode->tag(), styleNode); + callLuaField("onStyleApply", styleNode->tag(), styleNode); + + if(m_firstOnStyle) { + callLuaField("onSetup"); + // always focus new child + if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) + focus(); + } + m_firstOnStyle = false; + + m_loadingStyle = false; + } catch(Exception& e) { + logError("Failed to apply style to widget '", m_id, "' style: ", e.what()); + } +} +void UIWidget::addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) +{ + if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) + anchorLayout->addAnchor(asUIWidget(), anchoredEdge, hookedWidgetId, hookedEdge); } -int UIWidget::getChildIndex(const UIWidgetPtr& child) +void UIWidget::centerIn(const std::string& hookedWidgetId) { - int index = 1; - for(auto it = m_children.begin(); it != m_children.end(); ++it) { - if(*it == child) - return index; - ++index; + if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter); + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter); } - return -1; +} + +void UIWidget::fill(const std::string& hookedWidgetId) +{ + if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorLeft, hookedWidgetId, Fw::AnchorLeft); + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorRight, hookedWidgetId, Fw::AnchorRight); + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop); + anchorLayout->addAnchor(asUIWidget(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); + } +} + +void UIWidget::breakAnchors() +{ + if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) + anchorLayout->removeAnchors(asUIWidget()); } void UIWidget::updateParentLayout() @@ -800,27 +431,406 @@ void UIWidget::updateLayout() parentLayout->updateLater(); } -void UIWidget::applyStyle(const OTMLNodePtr& styleNode) +void UIWidget::lock() { - try { - m_loadingStyle = true; - onStyleApply(styleNode->tag(), styleNode); - callLuaField("onStyleApply", styleNode->tag(), styleNode); + if(UIWidgetPtr parent = getParent()) + parent->lockChild(asUIWidget()); +} - if(m_firstOnStyle) { - callLuaField("onSetup"); - // always focus new child - if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) - focus(); - } - m_firstOnStyle = false; +void UIWidget::unlock() +{ + if(UIWidgetPtr parent = getParent()) + parent->unlockChild(asUIWidget()); +} - m_loadingStyle = false; - } catch(Exception& e) { - logError("Failed to apply style to widget '", m_id, "' style: ", e.what()); +void UIWidget::focus() +{ + if(!m_focusable) + return; + if(UIWidgetPtr parent = getParent()) + parent->focusChild(asUIWidget(), Fw::ActiveFocusReason); +} + +void UIWidget::grabMouse() +{ + g_ui.setMouseReceiver(asUIWidget()); +} + +void UIWidget::ungrabMouse() +{ + if(g_ui.getMouseReceiver() == asUIWidget()) + g_ui.resetMouseReceiver(); +} + +void UIWidget::grabKeyboard() +{ + g_ui.setKeyboardReceiver(asUIWidget()); +} + +void UIWidget::ungrabKeyboard() +{ + if(g_ui.getKeyboardReceiver() == asUIWidget()) + g_ui.resetKeyboardReceiver(); +} + +void UIWidget::bindRectToParent() +{ + Rect boundRect = m_rect; + UIWidgetPtr parent = getParent(); + if(parent) { + Rect parentRect = parent->getRect(); + boundRect.bound(parentRect); + } + + setRect(boundRect); +} + +void UIWidget::destroy() +{ + if(m_destroyed) + logWarning("attempt to destroy widget '", m_id, "' two times"); + + setVisible(false); + setEnabled(false); + + // release input grabs + if(g_ui.getKeyboardReceiver() == asUIWidget()) + g_ui.resetKeyboardReceiver(); + + if(g_ui.getMouseReceiver() == asUIWidget()) + g_ui.resetMouseReceiver(); + + // remove itself from parent + if(UIWidgetPtr parent = getParent()) { + if(parent->hasChild(asUIWidget())) + parent->removeChild(asUIWidget()); + } + + callLuaField("onDestroy"); + + m_destroyed = true; +} + +void UIWidget::setId(const std::string& id) +{ + m_id = id; +} + +void UIWidget::setParent(const UIWidgetPtr& parent) +{ + // remove from old parent + UIWidgetPtr oldParent = getParent(); + + // the parent is already the same + if(oldParent == parent) + return; + + UIWidgetPtr self = asUIWidget(); + if(oldParent && oldParent->hasChild(self)) + oldParent->removeChild(self); + + // reset parent + m_parent.reset(); + + // set new parent + if(parent) { + m_parent = parent; + + // add to parent if needed + if(!parent->hasChild(self)) + parent->addChild(self); } } +void UIWidget::setLayout(const UILayoutPtr& layout) +{ + if(m_layout) + m_layout->disableUpdates(); + + layout->setParent(asUIWidget()); + layout->disableUpdates(); + + for(const UIWidgetPtr& child : m_children) { + if(m_layout) + m_layout->removeWidget(child); + layout->addWidget(child); + } + + if(m_layout) { + m_layout->enableUpdates(); + m_layout->setParent(nullptr); + m_layout->update(); + } + + layout->enableUpdates(); + m_layout = layout; +} + +void UIWidget::setRect(const Rect& rect) +{ + // only update if the rect really changed + Rect oldRect = m_rect; + if(rect == oldRect) + return; + + m_rect = rect; + + // updates own layout + updateLayout(); + + // avoid massive update events + if(!m_updateEventScheduled) { + UIWidgetPtr self = asUIWidget(); + g_dispatcher.addEvent([self, oldRect]() { + self->m_updateEventScheduled = false; + if(oldRect != self->getRect()) + self->onGeometryChange(oldRect, self->getRect()); + }); + m_updateEventScheduled = true; + } +} + +void UIWidget::setStyle(const std::string& styleName) +{ + OTMLNodePtr styleNode = g_ui.getStyle(styleName); + if(!styleNode) { + logTraceError("unable to retrive style '", styleName, "': not a defined style"); + return; + } + applyStyle(styleNode); + m_style = styleNode; + updateStyle(); +} + +void UIWidget::setStyleFromNode(const OTMLNodePtr& styleNode) +{ + applyStyle(styleNode); + m_style = styleNode; + updateStyle(); +} + +void UIWidget::setEnabled(bool enabled) +{ + if(enabled != m_enabled) { + m_enabled = enabled; + + updateState(Fw::DisabledState); + updateState(Fw::ActiveState); + updateState(Fw::HoverState); + } +} + +void UIWidget::setVisible(bool visible) +{ + if(m_visible != visible) { + m_visible = visible; + + // hiding a widget make it lose focus + if(!visible && isFocused()) { + if(UIWidgetPtr parent = getParent()) + parent->focusPreviousChild(Fw::ActiveFocusReason); + } + + updateState(Fw::ActiveState); + updateState(Fw::HoverState); + } +} + +void UIWidget::setPressed(bool pressed) +{ + if(pressed != m_pressed) { + m_pressed = pressed; + updateState(Fw::PressedState); + } +} + +void UIWidget::setOn(bool on) +{ + setState(Fw::OnState, on); +} + +void UIWidget::setChecked(bool checked) +{ + if(setState(Fw::CheckedState, checked)) + callLuaField("onCheckChange", checked); +} + +void UIWidget::setFocusable(bool focusable) +{ + if(m_focusable != focusable) { + m_focusable = focusable; + + // make parent focus another child + if(!focusable && isFocused()) { + if(UIWidgetPtr parent = getParent()) + parent->focusPreviousChild(Fw::ActiveFocusReason); + } + } +} + +void UIWidget::setPhantom(bool phantom) +{ + m_phantom = phantom; +} + +void UIWidget::setFixedSize(bool fixed) +{ + m_fixedSize = fixed; + updateParentLayout(); +} + +void UIWidget::setLastFocusReason(Fw::FocusReason reason) +{ + m_lastFocusReason = reason; +} + +bool UIWidget::isVisible() +{ + if(!m_visible) + return false; + else if(UIWidgetPtr parent = getParent()) + return parent->isVisible(); + else + return asUIWidget() == g_ui.getRootWidget(); +} + +bool UIWidget::isChildLocked(const UIWidgetPtr& child) +{ + auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child); + return it != m_lockedChildren.end(); +} + +bool UIWidget::hasChild(const UIWidgetPtr& child) +{ + auto it = std::find(m_children.begin(), m_children.end(), child); + if(it != m_children.end()) + return true; + return false; +} + +int UIWidget::getChildIndex(const UIWidgetPtr& child) +{ + int index = 1; + for(auto it = m_children.begin(); it != m_children.end(); ++it) { + if(*it == child) + return index; + ++index; + } + return -1; +} + +Rect UIWidget::getChildrenRect() +{ + Rect rect = m_rect; + rect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); + rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left); + return rect; +} + +UIAnchorLayoutPtr UIWidget::getAnchoredLayout() +{ + UIWidgetPtr parent = getParent(); + if(!parent) { + logError("cannot add anchors to widget ", m_id, ": there is no parent"); + return nullptr; + } + + UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout(); + if(!anchorLayout) { + logError("cannot add anchors to widget ", m_id, ": the parent doesn't use anchors layout"); + return nullptr; + } + return anchorLayout; +} + +UIWidgetPtr UIWidget::getRootParent() +{ + if(UIWidgetPtr parent = getParent()) + return parent->getRootParent(); + else + return asUIWidget(); +} + +UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) +{ + auto it = std::find(m_children.begin(), m_children.end(), relativeChild); + if(it != m_children.end() && ++it != m_children.end()) + return *it; + return nullptr; +} + +UIWidgetPtr UIWidget::getChildBefore(const UIWidgetPtr& relativeChild) +{ + auto it = std::find(m_children.rbegin(), m_children.rend(), relativeChild); + if(it != m_children.rend() && ++it != m_children.rend()) + return *it; + return nullptr; +} + +UIWidgetPtr UIWidget::getChildById(const std::string& childId) +{ + for(const UIWidgetPtr& child : m_children) { + if(child->getId() == childId) + return child; + } + return nullptr; +} + +UIWidgetPtr UIWidget::getChildByPos(const Point& childPos) +{ + for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { + const UIWidgetPtr& widget = (*it); + if(widget->isExplicitlyVisible() && widget->containsPoint(childPos)) + return widget; + } + + return nullptr; +} + +UIWidgetPtr UIWidget::getChildByIndex(int index) +{ + index = index <= 0 ? (m_children.size() + index) : index-1; + if(index >= 0 && (uint)index < m_children.size()) + return m_children.at(index); + return nullptr; +} + +UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& id) +{ + UIWidgetPtr widget = getChildById(id); + if(!widget) { + for(const UIWidgetPtr& child : m_children) { + widget = child->recursiveGetChildById(id); + if(widget) + break; + } + } + return widget; +} + +UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos) +{ + for(const UIWidgetPtr& child : m_children) { + if(child->containsPoint(childPos)) { + if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos)) + return subChild; + return child; + } + } + return nullptr; +} + +UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id) +{ + UIWidgetPtr widget = getChildById(id); + if(!widget) { + if(UIWidgetPtr parent = getParent()) + widget = parent->backwardsGetWidgetById(id); + } + return widget; +} + + bool UIWidget::setState(Fw::WidgetState state, bool on) { if(state == Fw::InvalidState) @@ -1020,216 +1030,9 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty if(const OTMLNodePtr& node = styleNode->get("id")) setId(node->value()); - // load styles used by all widgets - for(const OTMLNodePtr& node : styleNode->children()) { - // background image - if(node->tag() == "image") { - ImagePtr image = ImagePtr(new Image); - image->loadFromOTML(node); - setImage(image); - } - else if(node->tag() == "border-image") - setImage(BorderImage::loadFromOTML(node)); - if(node->tag() == "icon") - setIcon(node->value()); - else if(node->tag() == "text") - setText(node->value()); - else if(node->tag() == "text-align") - setTextAlign(Fw::translateAlignment(node->value())); - else if(node->tag() == "text-offset") - setTextOffset(node->value()); - else if(node->tag() == "font") - setFont(node->value()); - else if(node->tag() == "color") - setColor(node->value()); - else if(node->tag() == "background-color") - setBackgroundColor(node->value()); - else if(node->tag() == "opacity") - setOpacity(node->value()); - else if(node->tag() == "enabled") - setEnabled(node->value()); - else if(node->tag() == "visible") - setVisible(node->value()); - else if(node->tag() == "checked") - setChecked(node->value()); - else if(node->tag() == "on") - setOn(node->value()); - else if(node->tag() == "focusable") - setFocusable(node->value()); - else if(node->tag() == "phantom") - setPhantom(node->value()); - else if(node->tag() == "size") - resize(node->value()); - else if(node->tag() == "width") - setWidth(node->value()); - else if(node->tag() == "height") - setHeight(node->value()); - else if(node->tag() == "fixed-size") - setSizeFixed(node->value()); - else if(node->tag() == "pos") - moveTo(node->value()); - else if(node->tag() == "x") - setX(node->value()); - else if(node->tag() == "y") - setY(node->value()); - else if(node->tag() == "margin-top") - setMarginTop(node->value()); - else if(node->tag() == "margin-right") - setMarginRight(node->value()); - else if(node->tag() == "margin-bottom") - setMarginBottom(node->value()); - else if(node->tag() == "margin-left") - setMarginLeft(node->value()); - else if(node->tag() == "margin") { - std::string marginDesc = node->value(); - std::vector split; - boost::split(split, marginDesc, boost::is_any_of(std::string(" "))); - if(split.size() == 4) { - setMarginTop(Fw::safeCast(split[0])); - setMarginRight(Fw::safeCast(split[1])); - setMarginBottom(Fw::safeCast(split[2])); - setMarginLeft(Fw::safeCast(split[3])); - } else if(split.size() == 3) { - int marginTop = Fw::safeCast(split[0]); - int marginHorizontal = Fw::safeCast(split[1]); - int marginBottom = Fw::safeCast(split[2]); - setMarginTop(marginTop); - setMarginRight(marginHorizontal); - setMarginBottom(marginBottom); - setMarginLeft(marginHorizontal); - } else if(split.size() == 2) { - int marginVertical = Fw::safeCast(split[0]); - int marginHorizontal = Fw::safeCast(split[1]); - setMarginTop(marginVertical); - setMarginRight(marginHorizontal); - setMarginBottom(marginVertical); - setMarginLeft(marginHorizontal); - } else if(split.size() == 1) { - int margin = Fw::safeCast(split[0]); - setMarginTop(margin); - setMarginRight(margin); - setMarginBottom(margin); - setMarginLeft(margin); - } - } - else if(node->tag() == "padding-top") - setPaddingTop(node->value()); - else if(node->tag() == "padding-right") - setPaddingRight(node->value()); - else if(node->tag() == "padding-bottom") - setPaddingBottom(node->value()); - else if(node->tag() == "padding-left") - setPaddingLeft(node->value()); - else if(node->tag() == "padding") { - std::string paddingDesc = node->value(); - std::vector split; - boost::split(split, paddingDesc, boost::is_any_of(std::string(" "))); - if(split.size() == 4) { - setPaddingTop(Fw::safeCast(split[0])); - setPaddingRight(Fw::safeCast(split[1])); - setPaddingBottom(Fw::safeCast(split[2])); - setPaddingLeft(Fw::safeCast(split[3])); - } else if(split.size() == 3) { - int paddingTop = Fw::safeCast(split[0]); - int paddingHorizontal = Fw::safeCast(split[1]); - int paddingBottom = Fw::safeCast(split[2]); - setPaddingTop(paddingTop); - setPaddingRight(paddingHorizontal); - setPaddingBottom(paddingBottom); - setPaddingLeft(paddingHorizontal); - } else if(split.size() == 2) { - int paddingVertical = Fw::safeCast(split[0]); - int paddingHorizontal = Fw::safeCast(split[1]); - setPaddingTop(paddingVertical); - setPaddingRight(paddingHorizontal); - setPaddingBottom(paddingVertical); - setPaddingLeft(paddingHorizontal); - } else if(split.size() == 1) { - int padding = Fw::safeCast(split[0]); - setPaddingTop(padding); - setPaddingRight(padding); - setPaddingBottom(padding); - setPaddingLeft(padding); - } - } - // layouts - else if(node->tag() == "layout") { - std::string layoutType; - if(node->hasValue()) - layoutType = node->value(); - else - layoutType = node->valueAt("type", ""); - - if(!layoutType.empty()) { - UILayoutPtr layout; - if(layoutType == "verticalBox") - layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget())); - else if(layoutType == "anchor") - layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); - else - throw OTMLException(node, "cannot determine layout type"); - setLayout(layout); - } - - if(node->hasChildren()) - m_layout->applyStyle(node); - } - // anchors - else if(boost::starts_with(node->tag(), "anchors.")) { - UIWidgetPtr parent = getParent(); - if(!parent) { - if(m_firstOnStyle) - throw OTMLException(node, "cannot create anchor, there is no parent widget!"); - else - continue; - } - - UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout(); - if(!anchorLayout) - throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!"); - - std::string what = node->tag().substr(8); - if(what == "fill") { - anchorLayout->fill(asUIWidget(), node->value()); - } else if(what == "centerIn") { - anchorLayout->centerIn(asUIWidget(), node->value()); - } else { - Fw::AnchorEdge anchoredEdge = Fw::translateAnchorEdge(what); - - std::string anchorDescription = node->value(); - std::vector split; - boost::split(split, anchorDescription, boost::is_any_of(std::string("."))); - if(split.size() != 2) - throw OTMLException(node, "invalid anchor description"); - - std::string hookedWidgetId = split[0]; - Fw::AnchorEdge hookedEdge = Fw::translateAnchorEdge(split[1]); - - if(anchoredEdge == Fw::AnchorNone) - throw OTMLException(node, "invalid anchor edge"); - - if(hookedEdge == Fw::AnchorNone) - throw OTMLException(node, "invalid anchor target edge"); - - anchorLayout->addAnchor(asUIWidget(), anchoredEdge, hookedWidgetId, hookedEdge); - } - // lua functions - } else if(boost::starts_with(node->tag(), "@")) { - // load once - if(m_firstOnStyle) { - std::string funcName = node->tag().substr(1); - std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]"; - g_lua.loadFunction(node->value(), funcOrigin); - luaSetField(funcName); - } - // lua fields value - } else if(boost::starts_with(node->tag(), "&")) { - std::string fieldName = node->tag().substr(1); - std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]"; - g_lua.evaluateExpression(node->value(), fieldOrigin); - luaSetField(fieldName); - } - } + parseBaseStyle(styleNode); + parseImageStyle(styleNode); + parseTextStyle(styleNode); } void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect) @@ -1251,17 +1054,6 @@ void UIWidget::onHoverChange(bool hovered) g_ui.getRootWidget()->updateState(Fw::HoverState); } - -void UIWidget::onTextChange(const std::string& text) -{ - callLuaField("onTextChange", text); -} - -void UIWidget::onFontChange(const std::string& font) -{ - callLuaField("onFontChange", font); -} - bool UIWidget::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers) { return callLuaField("onKeyPress", keyCode, keyText, keyboardModifiers); diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 5dff0960..1b094a81 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -28,154 +28,50 @@ #include #include #include +#include + +template +struct EdgeGroup { + EdgeGroup() { top = right = bottom = left = T(0); } + void set(T value) { top = right = bottom = left = value; } + T top; + T right; + T bottom; + T left; +}; class UIWidget : public LuaObject { +// widget core public: UIWidget(); - virtual ~UIWidget() { } - - void destroy(); + virtual ~UIWidget(); protected: - virtual void render(); - virtual void renderSelf(); - virtual void renderChildren(); + virtual void draw(); + virtual void drawSelf(); + virtual void drawChildren(); friend class UIManager; - void drawBackground(const Rect& screenCoords); - void drawBorder(const Rect& screenCoords); - void drawImage(const Rect& screenCoords); - void drawIcon(const Rect& screenCoords); - void drawText(const Rect& screenCoords); + std::string m_id; + Rect m_rect; + Boolean m_enabled; + Boolean m_visible; + Boolean m_focusable; + Boolean m_fixedSize; + Boolean m_pressed; + Boolean m_phantom; + Boolean m_destroyed; + UILayoutPtr m_layout; + UIWidgetWeakPtr m_parent; + UIWidgetList m_children; + UIWidgetList m_lockedChildren; + UIWidgetPtr m_focusedChild; + OTMLNodePtr m_style; + Fw::FocusReason m_lastFocusReason; public: - void setVisible(bool visible); - void setEnabled(bool enabled); - void setPressed(bool pressed); - void setOn(bool on); - void setChecked(bool checked); - void setId(const std::string& id) { m_id = id; } - void setFocusable(bool focusable); - void setPhantom(bool phantom) { m_phantom = phantom; } - void setStyle(const std::string& styleName); - void setStyleFromNode(const OTMLNodePtr& styleNode); - void setLayout(const UILayoutPtr& layout) { m_layout = layout; } - void setParent(const UIWidgetPtr& parent); - void setRect(const Rect& rect); - void setX(int x) { moveTo(Point(x, getY())); } - void setY(int y) { moveTo(Point(getX(), y)); } - void setWidth(int width) { resize(Size(width, getHeight())); } - void setHeight(int height) { resize(Size(getWidth(), height)); } - void setImage(const ImagePtr& image) { m_image = image; } - void setIcon(const std::string& iconFile); - void setOpacity(int opacity) { m_opacity = opacity; } - void setBackgroundColor(const Color& color) { m_backgroundColor = color; } - void setColor(const Color& color) { m_color = color; } - void setMarginTop(int margin) { m_marginTop = margin; updateParentLayout(); } - void setMarginRight(int margin) { m_marginRight = margin; updateParentLayout(); } - void setMarginBottom(int margin) { m_marginBottom = margin; updateParentLayout(); } - void setMarginLeft(int margin) { m_marginLeft = margin; updateParentLayout(); } - void setPaddingTop(int padding) { m_paddingTop = padding; updateLayout(); } - void setPaddingRight(int padding) { m_paddingRight = padding; updateLayout(); } - void setPaddingBottom(int padding) { m_paddingBottom = padding; updateLayout(); } - void setPaddingLeft(int padding) { m_paddingLeft = padding; updateLayout(); } - void setText(const std::string& text); - void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; } - void setTextOffset(const Point& offset) { m_textOffset = offset; } - void setFont(const std::string& fontName); - void setSizeFixed(bool fixed) { m_fixedSize = fixed; updateParentLayout(); } - void setLastFocusReason(Fw::FocusReason reason) { m_lastFocusReason = reason; } - - void bindRectToParent(); - void resize(const Size& size) { setRect(Rect(getPos(), size)); } - void resizeToText() { resize(getTextSize()); } - void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); } - void hide() { setVisible(false); } - void show() { setVisible(true); } - void disable() { setEnabled(false); } - void enable() { setEnabled(true); } - void lock(); - void unlock(); - void focus(); - void grabMouse(); - void ungrabMouse(); - void grabKeyboard(); - void ungrabKeyboard(); - void clearText() { setText(""); } - - bool isActive() { return hasState(Fw::ActiveState); } - bool isEnabled() { return !hasState(Fw::DisabledState); } - bool isDisabled() { return hasState(Fw::DisabledState); } - bool isFocused() { return hasState(Fw::FocusState); } - bool isHovered() { return hasState(Fw::HoverState); } - bool isPressed() { return hasState(Fw::PressedState); } - bool isFirst() { return hasState(Fw::FirstState); } - bool isMiddle() { return hasState(Fw::MiddleState); } - bool isLast() { return hasState(Fw::LastState); } - bool isAlternate() { return hasState(Fw::AlternateState); } - bool isChecked() { return hasState(Fw::CheckedState); } - bool isOn() { return hasState(Fw::OnState); } - bool isVisible(); - bool isHidden() { return !isVisible(); } - bool isExplicitlyEnabled() { return m_enabled; } - bool isExplicitlyVisible() { return m_visible; } - bool isFocusable() { return m_focusable; } - bool isPhantom() { return m_phantom; } - bool isSizeFixed() { return m_fixedSize; } - bool isDestroyed() { return m_destroyed; } - bool containsPoint(const Point& point) { return m_rect.contains(point); } - bool hasChildren() { return m_children.size() > 0; } - bool hasChild(const UIWidgetPtr& child); - - std::string getId() { return m_id; } - int getChildCount() { return m_children.size(); } - UILayoutPtr getLayout() { return m_layout; } - UIWidgetPtr getParent() { return m_parent.lock(); } - UIWidgetPtr getRootParent(); - Point getPos() { return m_rect.topLeft(); } - Size getSize() { return m_rect.size(); } - Rect getRect() { return m_rect; } - Rect getChildrenRect(); - int getX() { return m_rect.x(); } - int getY() { return m_rect.y(); } - int getWidth() { return m_rect.width(); } - int getHeight() { return m_rect.height(); } - Color getColor() { return m_color; } - Color getBackgroundColor() { return m_backgroundColor; } - int getOpacity() { return m_opacity; } - int getMarginTop() { return m_marginTop; } - int getMarginRight() { return m_marginRight; } - int getMarginBottom() { return m_marginBottom; } - int getMarginLeft() { return m_marginLeft; } - int getPaddingTop() { return m_paddingTop; } - int getPaddingRight() { return m_paddingRight; } - int getPaddingBottom() { return m_paddingBottom; } - int getPaddingLeft() { return m_paddingLeft; } - std::string getText() { return m_text; } - Fw::AlignmentFlag getTextAlign() { return m_textAlign; } - Point getTextOffset() { return m_textOffset; } - std::string getFont() { return m_font->getName(); } - Size getTextSize() { return m_font->calculateTextRectSize(m_text); } - - Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; } - OTMLNodePtr getStyle() { return m_style; } - std::string getStyleName() { return m_style->tag(); } - - UIWidgetList getChildren() { return m_children; } - UIWidgetPtr getFocusedChild() { return m_focusedChild; } - UIWidgetPtr getChildAfter(const UIWidgetPtr& relativeChild); - UIWidgetPtr getChildBefore(const UIWidgetPtr& relativeChild); - UIWidgetPtr getChildById(const std::string& childId); - UIWidgetPtr getChildByPos(const Point& childPos); - UIWidgetPtr getChildByIndex(int index); - UIWidgetPtr getFirstChild() { return getChildByIndex(1); } - UIWidgetPtr getLastChild() { return getChildByIndex(-1); } - UIWidgetPtr recursiveGetChildById(const std::string& id); - UIWidgetPtr recursiveGetChildByPos(const Point& childPos); - UIWidgetPtr backwardsGetWidgetById(const std::string& id); - void addChild(const UIWidgetPtr& child); void insertChild(int index, const UIWidgetPtr& child); void removeChild(const UIWidgetPtr& child); @@ -186,15 +82,63 @@ public: void moveChildToIndex(const UIWidgetPtr& child, int index); void lockChild(const UIWidgetPtr& child); void unlockChild(const UIWidgetPtr& child); - bool isChildLocked(const UIWidgetPtr& child); - int getChildIndex(const UIWidgetPtr& child); - + void applyStyle(const OTMLNodePtr& styleNode); + void addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge); + void fill(const std::string& hookedWidgetId); + void centerIn(const std::string& hookedWidgetId); + void breakAnchors(); void updateParentLayout(); void updateLayout(); - void applyStyle(const OTMLNodePtr& styleNode); + void lock(); + void unlock(); + void focus(); + void grabMouse(); + void ungrabMouse(); + void grabKeyboard(); + void ungrabKeyboard(); + void bindRectToParent(); + void destroy(); + + void setId(const std::string& id); + void setParent(const UIWidgetPtr& parent); + void setLayout(const UILayoutPtr& layout); + void setRect(const Rect& rect); + void setStyle(const std::string& styleName); + void setStyleFromNode(const OTMLNodePtr& styleNode); + void setEnabled(bool enabled); + void setVisible(bool visible); + void setPressed(bool pressed); + void setOn(bool on); + void setChecked(bool checked); + void setFocusable(bool focusable); + void setPhantom(bool phantom); + void setFixedSize(bool fixed); + void setLastFocusReason(Fw::FocusReason reason); + + bool isVisible(); + bool isChildLocked(const UIWidgetPtr& child); + bool hasChild(const UIWidgetPtr& child); + int getChildIndex(const UIWidgetPtr& child); + Rect getChildrenRect(); + UIAnchorLayoutPtr getAnchoredLayout(); + UIWidgetPtr getRootParent(); + UIWidgetPtr getChildAfter(const UIWidgetPtr& relativeChild); + UIWidgetPtr getChildBefore(const UIWidgetPtr& relativeChild); + UIWidgetPtr getChildById(const std::string& childId); + UIWidgetPtr getChildByPos(const Point& childPos); + UIWidgetPtr getChildByIndex(int index); + UIWidgetPtr recursiveGetChildById(const std::string& id); + UIWidgetPtr recursiveGetChildByPos(const Point& childPos); + UIWidgetPtr backwardsGetWidgetById(const std::string& id); UIWidgetPtr asUIWidget() { return std::static_pointer_cast(shared_from_this()); } +private: + Boolean m_updateEventScheduled; + Boolean m_loadingStyle; + + +// state managment protected: bool setState(Fw::WidgetState state, bool on); bool hasState(Fw::WidgetState state); @@ -203,16 +147,20 @@ private: void updateState(Fw::WidgetState state); void updateStates(); void updateChildrenIndexStates(); - void updateStyle(); + Boolean m_updateStyleScheduled; + Boolean m_firstOnStyle; + OTMLNodePtr m_stateStyle; + int m_states; + + +// event processing protected: virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); virtual void onFocusChange(bool focused, Fw::FocusReason reason); virtual void onHoverChange(bool hovered); - virtual void onTextChange(const std::string& text); - virtual void onFontChange(const std::string& font); virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers); virtual bool onKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers); virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button); @@ -227,46 +175,259 @@ protected: bool propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved); bool propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction); + +// function shortcuts +public: + void resize(int width, int height) { setRect(Rect(getPos(), Size(width, height))); } + void move(int x, int y) { setRect(Rect(x, y, getSize())); } + void hide() { setVisible(false); } + void show() { setVisible(true); } + void disable() { setEnabled(false); } + void enable() { setEnabled(true); } + + bool isActive() { return hasState(Fw::ActiveState); } + bool isEnabled() { return !hasState(Fw::DisabledState); } + bool isDisabled() { return hasState(Fw::DisabledState); } + bool isFocused() { return hasState(Fw::FocusState); } + bool isHovered() { return hasState(Fw::HoverState); } + bool isPressed() { return hasState(Fw::PressedState); } + bool isFirst() { return hasState(Fw::FirstState); } + bool isMiddle() { return hasState(Fw::MiddleState); } + bool isLast() { return hasState(Fw::LastState); } + bool isAlternate() { return hasState(Fw::AlternateState); } + bool isChecked() { return hasState(Fw::CheckedState); } + bool isOn() { return hasState(Fw::OnState); } + bool isHidden() { return !isVisible(); } + bool isExplicitlyEnabled() { return m_enabled; } + bool isExplicitlyVisible() { return m_visible; } + bool isFocusable() { return m_focusable; } + bool isPhantom() { return m_phantom; } + bool isFixedSize() { return m_fixedSize; } + bool isDestroyed() { return m_destroyed; } + + bool hasChildren() { return m_children.size() > 0; } + bool containsPoint(const Point& point) { return m_rect.contains(point); } + + std::string getId() { return m_id; } + UIWidgetPtr getParent() { return m_parent.lock(); } + UIWidgetPtr getFocusedChild() { return m_focusedChild; } + UIWidgetList getChildren() { return m_children; } + UIWidgetPtr getFirstChild() { return getChildByIndex(1); } + UIWidgetPtr getLastChild() { return getChildByIndex(-1); } + UILayoutPtr getLayout() { return m_layout; } + OTMLNodePtr getStyle() { return m_style; } + int getChildCount() { return m_children.size(); } + Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; } + std::string getStyleName() { return m_style->tag(); } + + +// base style +private: + void initBaseStyle(); + void parseBaseStyle(const OTMLNodePtr& styleNode); + protected: - std::string m_id; - Fw::FocusReason m_lastFocusReason; - Boolean m_enabled; - Boolean m_visible; - Boolean m_focusable; - Boolean m_fixedSize; - Boolean m_pressed; - Boolean m_phantom; - Boolean m_updateEventScheduled; - Boolean m_loadingStyle; - Boolean m_updateStyleScheduled; - Boolean m_firstOnStyle; - Boolean m_destroyed; - Rect m_rect; - UILayoutPtr m_layout; - UIWidgetWeakPtr m_parent; - UIWidgetList m_children; - UIWidgetList m_lockedChildren; - UIWidgetPtr m_focusedChild; - OTMLNodePtr m_style; - OTMLNodePtr m_stateStyle; - ImagePtr m_image; - TexturePtr m_icon; - FontPtr m_font; - Color m_backgroundColor; + void drawBackground(const Rect& screenCoords); + void drawBorder(const Rect& screenCoords); + void drawIcon(const Rect& screenCoords); + Color m_color; - int m_states; - int m_opacity; - int m_marginTop; - int m_marginRight; - int m_marginBottom; - int m_marginLeft; - int m_paddingTop; - int m_paddingRight; - int m_paddingBottom; - int m_paddingLeft; + Color m_backgroundColor; + Rect m_backgroundRect; + TexturePtr m_icon; + Color m_iconColor; + Rect m_iconRect; + EdgeGroup m_borderColor; + EdgeGroup m_borderWidth; + EdgeGroup m_margin; + EdgeGroup m_padding; + float m_opacity; + +public: + void setX(int x) { move(x, getY()); } + void setY(int y) { move(getX(), y); } + void setWidth(int width) { resize(width, getHeight()); } + void setHeight(int height) { resize(getWidth(), height); } + void setSize(const Size& size) { resize(size.width(), size.height()); } + void setPos(const Point& pos) { move(pos.x, pos.y); } + void setColor(const Color& color) { m_color = color; } + void setBackgroundColor(const Color& color) { m_backgroundColor = color; } + void setBackgroundOffsetX(int x) { m_backgroundRect.setX(x); } + void setBackgroundOffsetY(int y) { m_backgroundRect.setX(y); } + void setBackgroundOffset(const Point& pos) { m_backgroundRect.move(pos); } + void setBackgroundWidth(int width) { m_backgroundRect.setWidth(width); } + void setBackgroundHeight(int height) { m_backgroundRect.setHeight(height); } + void setBackgroundSize(const Size& size) { m_backgroundRect.resize(size); } + void setBackgroundRect(const Rect& rect) { m_backgroundRect = rect; } + void setIcon(const std::string& iconFile); + void setIconColor(const Color& color) { m_iconColor = color; } + void setIconOffsetX(int x) { m_iconRect.setX(x); } + void setIconOffsetY(int y) { m_iconRect.setX(y); } + void setIconOffset(const Point& pos) { m_iconRect.move(pos); } + void setIconWidth(int width) { m_iconRect.setWidth(width); } + void setIconHeight(int height) { m_iconRect.setHeight(height); } + void setIconSize(const Size& size) { m_iconRect.resize(size); } + void setIconRect(const Rect& rect) { m_iconRect = rect; } + void setBorderWidth(int width) { m_borderWidth.set(width); updateLayout(); } + void setBorderWidthTop(int width) { m_borderWidth.top = width; } + void setBorderWidthRight(int width) { m_borderWidth.right = width; } + void setBorderWidthBottom(int width) { m_borderWidth.bottom = width; } + void setBorderWidthLeft(int width) { m_borderWidth.left = width; } + void setBorderColor(const Color& color) { m_borderColor.set(color); updateLayout(); } + void setBorderColorTop(const Color& color) { m_borderColor.top = color; } + void setBorderColorRight(const Color& color) { m_borderColor.right = color; } + void setBorderColorBottom(const Color& color) { m_borderColor.bottom = color; } + void setBorderColorLeft(const Color& color) { m_borderColor.left = color; } + void setMargin(int margin) { m_margin.set(margin); updateParentLayout(); } + void setMarginHorizontal(int margin) { m_margin.right = m_margin.left = margin; updateParentLayout(); } + void setMarginVertical(int margin) { m_margin.bottom = m_margin.top = margin; updateParentLayout(); } + void setMarginTop(int margin) { m_margin.top = margin; updateParentLayout(); } + void setMarginRight(int margin) { m_margin.right = margin; updateParentLayout(); } + void setMarginBottom(int margin) { m_margin.bottom = margin; updateParentLayout(); } + void setMarginLeft(int margin) { m_margin.left = margin; updateParentLayout(); } + void setPadding(int padding) { m_padding.top = m_padding.right = m_padding.bottom = m_padding.left = padding; updateLayout(); } + void setPaddingHorizontal(int padding) { m_padding.right = m_padding.left = padding; updateLayout(); } + void setPaddingVertical(int padding) { m_padding.bottom = m_padding.top = padding; updateLayout(); } + void setPaddingTop(int padding) { m_padding.top = padding; updateLayout(); } + void setPaddingRight(int padding) { m_padding.right = padding; updateLayout(); } + void setPaddingBottom(int padding) { m_padding.bottom = padding; updateLayout(); } + void setPaddingLeft(int padding) { m_padding.left = padding; updateLayout(); } + void setOpacity(float opacity) { m_opacity = opacity; } + + int getX() { return m_rect.x(); } + int getY() { return m_rect.y(); } + Point getPos() { return m_rect.topLeft(); } + int getWidth() { return m_rect.width(); } + int getHeight() { return m_rect.height(); } + Size getSize() { return m_rect.size(); } + Rect getRect() { return m_rect; } + Color getColor() { return m_color; } + Color getBackgroundColor() { return m_backgroundColor; } + int getBackgroundOffsetX() { return m_backgroundRect.x(); } + int getBackgroundOffsetY() { return m_backgroundRect.y(); } + Point getBackgroundOffset() { return m_backgroundRect.topLeft(); } + int getBackgroundWidth() { return m_backgroundRect.width(); } + int getBackgroundHeight() { return m_backgroundRect.height(); } + Size getBackgroundSize() { return m_backgroundRect.size(); } + Rect getBackgroundRect() { return m_backgroundRect; } + Color getIconColor() { return m_iconColor; } + int getIconOffsetX() { return m_iconRect.x(); } + int getIconOffsetY() { return m_iconRect.y(); } + Point getIconOffset() { return m_iconRect.topLeft(); } + int getIconWidth() { return m_iconRect.width(); } + int getIconHeight() { return m_iconRect.height(); } + Size getIconSize() { return m_iconRect.size(); } + Rect getIconRect() { return m_iconRect; } + Color getBorderTopColor() { return m_borderColor.top; } + Color getBorderRightColor() { return m_borderColor.right; } + Color getBorderBottomColor() { return m_borderColor.bottom; } + Color getBorderLeftColor() { return m_borderColor.left; } + int getBorderTopWidth() { return m_borderWidth.top; } + int getBorderRightWidth() { return m_borderWidth.right; } + int getBorderBottomWidth() { return m_borderWidth.bottom; } + int getBorderLeftWidth() { return m_borderWidth.left; } + int getMarginTop() { return m_margin.top; } + int getMarginRight() { return m_margin.right; } + int getMarginBottom() { return m_margin.bottom; } + int getMarginLeft() { return m_margin.left; } + int getPaddingTop() { return m_padding.top; } + int getPaddingRight() { return m_padding.right; } + int getPaddingBottom() { return m_padding.bottom; } + int getPaddingLeft() { return m_padding.left; } + float getOpacity() { return m_opacity; } + + +// image +private: + void initImage() { } + void parseImageStyle(const OTMLNodePtr& styleNode); + + void updateImageCache() { m_imageMustRecache = true; } + void configureBorderImage() { m_imageBordered = true; updateImageCache(); } + + CoordsBuffer m_imageCoordsBuffer; + Rect m_imageCachedScreenCoords; + Boolean m_imageMustRecache; + Boolean m_imageBordered; + +protected: + void drawImage(const Rect& screenCoords); + + TexturePtr m_imageTexture; + Rect m_imageClipRect; + Rect m_imageRect; + Color m_imageColor; + Boolean m_imageFixedRatio; + Boolean m_imageRepeated; + Boolean m_imageSmooth; + EdgeGroup m_imageBorder; + +public: + void setImageSource(const std::string& source); + void setImageClip(const Rect& clipRect) { m_imageClipRect = clipRect; updateImageCache(); } + void setImageOffsetX(int x) { m_imageRect.setX(x); updateImageCache(); } + void setImageOffsetY(int y) { m_imageRect.setX(y); updateImageCache(); } + void setImageOffset(const Point& pos) { m_imageRect.move(pos); updateImageCache(); } + void setImageWidth(int width) { m_imageRect.setWidth(width); updateImageCache(); } + void setImageHeight(int height) { m_imageRect.setHeight(height); updateImageCache(); } + void setImageSize(const Size& size) { m_imageRect.resize(size); updateImageCache(); } + void setImageRect(const Rect& rect) { m_imageRect = rect; updateImageCache(); } + void setImageColor(const Color& color) { m_imageColor = color; updateImageCache(); } + void setImageFixedRatio(bool fixedRatio) { m_imageFixedRatio = fixedRatio; updateImageCache(); } + void setImageRepeated(bool repeated) { m_imageRepeated = repeated; updateImageCache(); } + void setImageSmooth(bool smooth) { m_imageSmooth = smooth; } + void setImageBorderTop(int border) { m_imageBorder.top = border; configureBorderImage(); } + void setImageBorderRight(int border) { m_imageBorder.right = border; configureBorderImage(); } + void setImageBorderBottom(int border) { m_imageBorder.bottom = border; configureBorderImage(); } + void setImageBorderLeft(int border) { m_imageBorder.left = border; configureBorderImage(); } + void setImageBorder(int border) { m_imageBorder.set(border); configureBorderImage(); } + + Rect getImageClip() { return m_imageClipRect; } + int getImageOffsetX() { return m_imageRect.x(); } + int getImageOffsetY() { return m_imageRect.y(); } + Point getImageOffset() { return m_imageRect.topLeft(); } + int getImageWidth() { return m_imageRect.width(); } + int getImageHeight() { return m_imageRect.height(); } + Size getImageSize() { return m_imageRect.size(); } + Rect getImageRect() { return m_imageRect; } + Color getImageColor() { return m_imageColor; } + bool isImageFixedRatio() { return m_imageFixedRatio; } + bool isImageSmooth() { return m_imageSmooth; } + int getImageBorderTop() { return m_imageBorder.top; } + int getImageBorderRight() { return m_imageBorder.right; } + int getImageBorderBottom() { return m_imageBorder.bottom; } + int getImageBorderLeft() { return m_imageBorder.left; } + +// text related +private: + void initText(); + void parseTextStyle(const OTMLNodePtr& styleNode); + +protected: + void drawText(const Rect& screenCoords); + + virtual void onTextChange(const std::string& text); + virtual void onFontChange(const std::string& font); + std::string m_text; - Point m_textOffset; Fw::AlignmentFlag m_textAlign; + Point m_textOffset; + FontPtr m_font; + +public: + void resizeToText() { setSize(getTextSize()); } + void clearText() { setText(""); } + + void setText(const std::string& text); + void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; } + void setTextOffset(const Point& offset) { m_textOffset = offset; } + void setFont(const std::string& fontName); + + std::string getText() { return m_text; } + Fw::AlignmentFlag getTextAlign() { return m_textAlign; } + Point getTextOffset() { return m_textOffset; } + std::string getFont() { return m_font->getName(); } + Size getTextSize() { return m_font->calculateTextRectSize(m_text); } }; #endif diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp new file mode 100644 index 00000000..3f4a9810 --- /dev/null +++ b/src/framework/ui/uiwidgetbasestyle.cpp @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "uiwidget.h" +#include "uianchorlayout.h" +#include "uiverticallayout.h" +#include "uitranslator.h" + +#include +#include +#include + +void UIWidget::initBaseStyle() +{ + m_backgroundColor = Fw::alpha; + m_borderColor.set(Fw::black); + m_iconColor = Fw::white; + m_color = Fw::white; + m_opacity = 1.0f; + + // generate an unique id, this is need because anchored layouts find widgets by id + static unsigned long id = 1; + m_id = Fw::mkstr("widget", id++); +} + +void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) +{ + // load styles used by all widgets + for(const OTMLNodePtr& node : styleNode->children()) { + if(node->tag() == "color") + setColor(node->value()); + else if(node->tag() == "x") + setX(node->value()); + else if(node->tag() == "y") + setY(node->value()); + else if(node->tag() == "pos") + setPos(node->value()); + else if(node->tag() == "width") + setWidth(node->value()); + else if(node->tag() == "height") + setHeight(node->value()); + else if(node->tag() == "rect") + setRect(node->value()); + else if(node->tag() == "background") + setBackgroundColor(node->value()); + else if(node->tag() == "background-color") + setBackgroundColor(node->value()); + else if(node->tag() == "background-offset-x") + setBackgroundOffsetX(node->value()); + else if(node->tag() == "background-offset-y") + setBackgroundOffsetY(node->value()); + else if(node->tag() == "background-offset") + setBackgroundOffset(node->value()); + else if(node->tag() == "background-width") + setBackgroundWidth(node->value()); + else if(node->tag() == "background-height") + setBackgroundHeight(node->value()); + else if(node->tag() == "background-size") + setBackgroundSize(node->value()); + else if(node->tag() == "background-rect") + setBackgroundRect(node->value()); + else if(node->tag() == "icon") + setIcon(node->value()); + else if(node->tag() == "icon-source") + setIcon(node->value()); + else if(node->tag() == "icon-color") + setIconColor(node->value()); + else if(node->tag() == "icon-offset-x") + setIconOffsetX(node->value()); + else if(node->tag() == "icon-offset-y") + setIconOffsetY(node->value()); + else if(node->tag() == "icon-offset") + setIconOffset(node->value()); + else if(node->tag() == "icon-width") + setIconWidth(node->value()); + else if(node->tag() == "icon-height") + setIconHeight(node->value()); + else if(node->tag() == "icon-size") + setIconSize(node->value()); + else if(node->tag() == "icon-rect") + setIconRect(node->value()); + else if(node->tag() == "opacity") + setOpacity(node->value()); + else if(node->tag() == "enabled") + setEnabled(node->value()); + else if(node->tag() == "visible") + setVisible(node->value()); + else if(node->tag() == "checked") + setChecked(node->value()); + else if(node->tag() == "on") + setOn(node->value()); + else if(node->tag() == "focusable") + setFocusable(node->value()); + else if(node->tag() == "phantom") + setPhantom(node->value()); + else if(node->tag() == "size") + setSize(node->value()); + else if(node->tag() == "fixed-size") + setFixedSize(node->value()); + else if(node->tag() == "border") { + auto split = Fw::split(node->value(), " "); + setBorderWidth(Fw::safeCast(split[0])); + setBorderColor(Fw::safeCast(split[1])); + } + else if(node->tag() == "border-width") + setBorderWidth(node->value()); + else if(node->tag() == "border-width-top") + setBorderWidthTop(node->value()); + else if(node->tag() == "border-width-right") + setBorderWidthRight(node->value()); + else if(node->tag() == "border-width-bottom") + setBorderWidthBottom(node->value()); + else if(node->tag() == "border-width-left") + setBorderWidthLeft(node->value()); + else if(node->tag() == "border-color") + setBorderColor(node->value()); + else if(node->tag() == "border-color-top") + setBorderColorTop(node->value()); + else if(node->tag() == "border-color-right") + setBorderColorRight(node->value()); + else if(node->tag() == "border-color-bottom") + setBorderColorBottom(node->value()); + else if(node->tag() == "border-color-left") + setBorderColorLeft(node->value()); + else if(node->tag() == "margin-top") + setMarginTop(node->value()); + else if(node->tag() == "margin-right") + setMarginRight(node->value()); + else if(node->tag() == "margin-bottom") + setMarginBottom(node->value()); + else if(node->tag() == "margin-left") + setMarginLeft(node->value()); + else if(node->tag() == "margin") { + std::string marginDesc = node->value(); + std::vector split; + boost::split(split, marginDesc, boost::is_any_of(std::string(" "))); + if(split.size() == 4) { + setMarginTop(Fw::safeCast(split[0])); + setMarginRight(Fw::safeCast(split[1])); + setMarginBottom(Fw::safeCast(split[2])); + setMarginLeft(Fw::safeCast(split[3])); + } else if(split.size() == 3) { + int marginTop = Fw::safeCast(split[0]); + int marginHorizontal = Fw::safeCast(split[1]); + int marginBottom = Fw::safeCast(split[2]); + setMarginTop(marginTop); + setMarginRight(marginHorizontal); + setMarginBottom(marginBottom); + setMarginLeft(marginHorizontal); + } else if(split.size() == 2) { + int marginVertical = Fw::safeCast(split[0]); + int marginHorizontal = Fw::safeCast(split[1]); + setMarginTop(marginVertical); + setMarginRight(marginHorizontal); + setMarginBottom(marginVertical); + setMarginLeft(marginHorizontal); + } else if(split.size() == 1) { + int margin = Fw::safeCast(split[0]); + setMarginTop(margin); + setMarginRight(margin); + setMarginBottom(margin); + setMarginLeft(margin); + } + } + else if(node->tag() == "padding-top") + setPaddingTop(node->value()); + else if(node->tag() == "padding-right") + setPaddingRight(node->value()); + else if(node->tag() == "padding-bottom") + setPaddingBottom(node->value()); + else if(node->tag() == "padding-left") + setPaddingLeft(node->value()); + else if(node->tag() == "padding") { + std::string paddingDesc = node->value(); + std::vector split; + boost::split(split, paddingDesc, boost::is_any_of(std::string(" "))); + if(split.size() == 4) { + setPaddingTop(Fw::safeCast(split[0])); + setPaddingRight(Fw::safeCast(split[1])); + setPaddingBottom(Fw::safeCast(split[2])); + setPaddingLeft(Fw::safeCast(split[3])); + } else if(split.size() == 3) { + int paddingTop = Fw::safeCast(split[0]); + int paddingHorizontal = Fw::safeCast(split[1]); + int paddingBottom = Fw::safeCast(split[2]); + setPaddingTop(paddingTop); + setPaddingRight(paddingHorizontal); + setPaddingBottom(paddingBottom); + setPaddingLeft(paddingHorizontal); + } else if(split.size() == 2) { + int paddingVertical = Fw::safeCast(split[0]); + int paddingHorizontal = Fw::safeCast(split[1]); + setPaddingTop(paddingVertical); + setPaddingRight(paddingHorizontal); + setPaddingBottom(paddingVertical); + setPaddingLeft(paddingHorizontal); + } else if(split.size() == 1) { + int padding = Fw::safeCast(split[0]); + setPaddingTop(padding); + setPaddingRight(padding); + setPaddingBottom(padding); + setPaddingLeft(padding); + } + } + // layouts + else if(node->tag() == "layout") { + std::string layoutType; + if(node->hasValue()) + layoutType = node->value(); + else + layoutType = node->valueAt("type", ""); + + if(!layoutType.empty()) { + UILayoutPtr layout; + if(layoutType == "verticalBox") + layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget())); + else if(layoutType == "anchor") + layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); + else + throw OTMLException(node, "cannot determine layout type"); + setLayout(layout); + } + + if(node->hasChildren()) + m_layout->applyStyle(node); + } + // anchors + else if(boost::starts_with(node->tag(), "anchors.")) { + UIWidgetPtr parent = getParent(); + if(!parent) { + if(m_firstOnStyle) + throw OTMLException(node, "cannot create anchor, there is no parent widget!"); + else + continue; + } + + UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout(); + if(!anchorLayout) + throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!"); + + std::string what = node->tag().substr(8); + if(what == "fill") { + fill(node->value()); + } else if(what == "centerIn") { + centerIn(node->value()); + } else { + Fw::AnchorEdge anchoredEdge = Fw::translateAnchorEdge(what); + + std::vector split = Fw::split(node->value(), "."); + if(split.size() != 2) + throw OTMLException(node, "invalid anchor description"); + + std::string hookedWidgetId = split[0]; + Fw::AnchorEdge hookedEdge = Fw::translateAnchorEdge(split[1]); + + if(anchoredEdge == Fw::AnchorNone) + throw OTMLException(node, "invalid anchor edge"); + + if(hookedEdge == Fw::AnchorNone) + throw OTMLException(node, "invalid anchor target edge"); + + addAnchor(anchoredEdge, hookedWidgetId, hookedEdge); + } + // lua functions + } else if(boost::starts_with(node->tag(), "@")) { + // load once + if(m_firstOnStyle) { + std::string funcName = node->tag().substr(1); + std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]"; + g_lua.loadFunction(node->value(), funcOrigin); + luaSetField(funcName); + } + // lua fields value + } else if(boost::starts_with(node->tag(), "&")) { + std::string fieldName = node->tag().substr(1); + std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]"; + g_lua.evaluateExpression(node->value(), fieldOrigin); + luaSetField(fieldName); + } + } +} + +void UIWidget::drawBackground(const Rect& screenCoords) +{ + if(m_backgroundColor.a() > 0) { + Rect drawRect = screenCoords; + drawRect.translate(m_backgroundRect.topLeft()); + if(m_backgroundRect.isValid()) + drawRect.resize(m_backgroundRect.size()); + g_painter.setColor(m_backgroundColor); + g_painter.drawFilledRect(drawRect); + } +} + +void UIWidget::drawBorder(const Rect& screenCoords) +{ + // top + if(m_borderWidth.top > 0 && m_borderColor.top.a() > 0) { + g_painter.setColor(m_borderColor.top); + + Rect borderRect(screenCoords.topLeft(), screenCoords.width(), m_borderWidth.top); + g_painter.drawFilledRect(borderRect); + } + // right + if(m_borderWidth.right > 0 && m_borderColor.top.a() > 0) { + g_painter.setColor(m_borderColor.top); + + Rect borderRect(screenCoords.topRight() - Point(m_borderWidth.right - 1, 0), m_borderWidth.right, screenCoords.height()); + g_painter.drawFilledRect(borderRect); + } + // bottom + if(m_borderWidth.bottom > 0 && m_borderColor.top.a() > 0) { + g_painter.setColor(m_borderColor.top); + + Rect borderRect(screenCoords.bottomLeft() - Point(0, m_borderWidth.bottom - 1), screenCoords.width(), m_borderWidth.bottom); + g_painter.drawFilledRect(borderRect); + } + // left + if(m_borderWidth.top > 0 && m_borderColor.top.a() > 0) { + g_painter.setColor(m_borderColor.top); + + Rect borderRect(screenCoords.topLeft(), m_borderWidth.left, screenCoords.height()); + g_painter.drawFilledRect(borderRect); + } +} + +void UIWidget::drawIcon(const Rect& screenCoords) +{ + if(m_icon && m_iconColor.a() > 0) { + Rect drawRect; + if(m_iconRect.isValid()) { + drawRect = screenCoords; + drawRect.translate(m_iconRect.topLeft()); + drawRect.resize(m_iconRect.size()); + } else { + drawRect.resize(m_icon->getSize()); + drawRect.moveCenter(screenCoords.center()); + } + g_painter.setColor(m_iconColor); + g_painter.drawTexturedRect(drawRect, m_icon); + } +} + +void UIWidget::setIcon(const std::string& iconFile) +{ + m_icon = g_textures.getTexture(iconFile); +} diff --git a/src/framework/ui/uiwidgetimage.cpp b/src/framework/ui/uiwidgetimage.cpp new file mode 100644 index 00000000..fc1af13e --- /dev/null +++ b/src/framework/ui/uiwidgetimage.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "uiwidget.h" +#include +#include +#include + +void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode) +{ + for(const OTMLNodePtr& node : styleNode->children()) { + if(node->tag() == "image") + setImageSource(node->value()); + else if(node->tag() == "image-source") + setImageSource(node->value()); + else if(node->tag() == "image-offset-x") + setImageOffsetX(node->value()); + else if(node->tag() == "image-offset-y") + setImageOffsetY(node->value()); + else if(node->tag() == "image-offset") + setImageOffset(node->value()); + else if(node->tag() == "image-width") + setImageWidth(node->value()); + else if(node->tag() == "image-height") + setImageHeight(node->value()); + else if(node->tag() == "image-size") + setImageSize(node->value()); + else if(node->tag() == "image-rect") + setImageRect(node->value()); + else if(node->tag() == "image-clip") + setImageClip(node->value()); + else if(node->tag() == "image-fixed-ratio") + setImageFixedRatio(node->value()); + else if(node->tag() == "image-repeated") + setImageRepeated(node->value()); + else if(node->tag() == "image-smooth") + setImageSmooth(node->value()); + else if(node->tag() == "image-color") + setImageColor(node->value()); + else if(node->tag() == "image-border-top") + setImageBorderTop(node->value()); + else if(node->tag() == "image-border-right") + setImageBorderRight(node->value()); + else if(node->tag() == "image-border-bottom") + setImageBorderBottom(node->value()); + else if(node->tag() == "image-border-left") + setImageBorderLeft(node->value()); + else if(node->tag() == "image-border") { + setImageBorder(node->value()); + } + } +} + +void UIWidget::drawImage(const Rect& screenCoords) +{ + if(!m_imageTexture || m_imageColor.a() == 0 || !screenCoords.isValid()) + return; + + // cache vertex buffers + if(m_imageCachedScreenCoords != screenCoords || m_imageMustRecache) { + m_imageCoordsBuffer.clear(); + m_imageCachedScreenCoords = screenCoords; + m_imageMustRecache = false; + + Rect drawRect = screenCoords; + drawRect.translate(m_imageRect.topLeft()); + if(m_imageRect.isValid()) + drawRect.resize(m_imageRect.size()); + + if(!m_imageBordered) { + if(m_imageFixedRatio) { + Size textureSize = m_imageTexture->getSize(); + + Size textureClipSize = drawRect.size(); + textureClipSize.scale(textureSize, Fw::KeepAspectRatio); + + Point texCoordsOffset; + if(textureSize.height() > textureClipSize.height()) + texCoordsOffset.y = (textureSize.height() - textureClipSize.height())/2; + else if(textureSize.width() > textureClipSize.width()) + texCoordsOffset.x = (textureSize.width() - textureClipSize.width())/2; + + Rect textureClipRect(texCoordsOffset, textureClipSize); + + m_imageCoordsBuffer.addRect(drawRect, textureClipRect); + } else { + if(m_imageRepeated) + m_imageCoordsBuffer.addRepeatedRects(drawRect, m_imageClipRect); + else + m_imageCoordsBuffer.addRect(drawRect, m_imageClipRect); + } + } else { + int top = m_imageBorder.top; + int bottom = m_imageBorder.bottom; + int left = m_imageBorder.left; + int right = m_imageBorder.right; + + // calculates border coords + const Rect clip = m_imageClipRect; + Rect leftBorder(clip.left(), clip.top() + top, left, clip.height() - top - bottom); + Rect rightBorder(clip.right() - right + 1, clip.top() + top, right, clip.height() - top - bottom); + Rect topBorder(clip.left() + left, clip.top(), clip.width() - right - left, top); + Rect bottomBorder(clip.left() + left, clip.bottom() - bottom + 1, clip.width() - right - left, bottom); + Rect topLeftCorner(clip.left(), clip.top(), left, top); + Rect topRightCorner(clip.right() - right + 1, clip.top(), right, top); + Rect bottomLeftCorner(clip.left(), clip.bottom() - bottom + 1, left, bottom); + Rect bottomRightCorner(clip.right() - right + 1, clip.bottom() - bottom + 1, right, bottom); + Rect center(clip.left() + left, clip.top() + top, clip.width() - right - left, clip.height() - top - bottom); + Size bordersSize(leftBorder.width() + rightBorder.width(), topBorder.height() + bottomBorder.height()); + Size centerSize = drawRect.size() - bordersSize; + Rect rectCoords; + + // first the center + if(centerSize.area() > 0) { + rectCoords = Rect(drawRect.left() + leftBorder.width(), drawRect.top() + topBorder.height(), centerSize); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, center); + } + // top left corner + rectCoords = Rect(drawRect.topLeft(), topLeftCorner.size()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, topLeftCorner); + // top + rectCoords = Rect(drawRect.left() + topLeftCorner.width(), drawRect.topLeft().y, centerSize.width(), topBorder.height()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, topBorder); + // top right corner + rectCoords = Rect(drawRect.left() + topLeftCorner.width() + centerSize.width(), drawRect.top(), topRightCorner.size()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, topRightCorner); + // left + rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height(), leftBorder.width(), centerSize.height()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, leftBorder); + // right + rectCoords = Rect(drawRect.left() + leftBorder.width() + centerSize.width(), drawRect.top() + topRightCorner.height(), rightBorder.width(), centerSize.height()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, rightBorder); + // bottom left corner + rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height() + centerSize.height(), bottomLeftCorner.size()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomLeftCorner); + // bottom + rectCoords = Rect(drawRect.left() + bottomLeftCorner.width(), drawRect.top() + topBorder.height() + centerSize.height(), centerSize.width(), bottomBorder.height()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomBorder); + // bottom right corner + rectCoords = Rect(drawRect.left() + bottomLeftCorner.width() + centerSize.width(), drawRect.top() + topRightCorner.height() + centerSize.height(), bottomRightCorner.size()); + m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomRightCorner); + } + } + + m_imageTexture->setSmooth(m_imageSmooth); + g_painter.setColor(m_imageColor); + g_painter.drawTextureCoords(m_imageCoordsBuffer, m_imageTexture); +} + +void UIWidget::setImageSource(const std::string& source) +{ + m_imageTexture = g_textures.getTexture(source); + if(!m_imageClipRect.isValid()) + m_imageClipRect = Rect(0, 0, m_imageTexture->getSize()); +} + diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp new file mode 100644 index 00000000..abc477e1 --- /dev/null +++ b/src/framework/ui/uiwidgettext.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "uiwidget.h" +#include "uitranslator.h" +#include +#include + +void UIWidget::initText() +{ + m_font = g_fonts.getDefaultFont(); + m_textAlign = Fw::AlignCenter; +} + +void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode) +{ + for(const OTMLNodePtr& node : styleNode->children()) { + if(node->tag() == "icon") + setIcon(node->value()); + else if(node->tag() == "text") + setText(node->value()); + else if(node->tag() == "text-align") + setTextAlign(Fw::translateAlignment(node->value())); + else if(node->tag() == "text-offset") + setTextOffset(node->value()); + else if(node->tag() == "font") + setFont(node->value()); + } +} + +void UIWidget::drawText(const Rect& screenCoords) +{ + g_painter.setColor(m_color); + if(m_text.length() > 0 && m_color.a() > 0) { + Rect textRect = screenCoords; + textRect.translate(m_textOffset); + m_font->renderText(m_text, textRect, m_textAlign, m_color); + } +} + +void UIWidget::onTextChange(const std::string& text) +{ + callLuaField("onTextChange", text); +} + +void UIWidget::onFontChange(const std::string& font) +{ + callLuaField("onFontChange", font); +} + +void UIWidget::setText(const std::string& text) +{ + if(m_text != text) { + m_text = text; + + // update rect size + if(!m_rect.isValid()) { + Size textSize = m_font->calculateTextRectSize(m_text); + Size newSize = getSize(); + if(newSize.width() <= 0) + newSize.setWidth(textSize.width()); + if(newSize.height() <= 0) + newSize.setHeight(textSize.height()); + setSize(newSize); + } + + onTextChange(text); + } +} + +void UIWidget::setFont(const std::string& fontName) +{ + m_font = g_fonts.getFont(fontName); + onFontChange(fontName); +} diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index 7e68fc0c..6ec6f0c2 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -22,7 +22,6 @@ #include "uiwindow.h" #include "uitranslator.h" -#include #include #include #include @@ -36,22 +35,22 @@ UIWindow::UIWindow() m_oldIndex = -1; } -void UIWindow::render() +void UIWindow::draw() { // render children - UIWidget::render(); + UIWidget::draw(); // draw window head text Rect headTextRect = m_rect; - headTextRect.addTop(-m_headTextOffset.y); + headTextRect.expandTop(-m_headTextOffset.y); headTextRect.setHeight(m_headHeight); if(m_titleAlign & Fw::AlignLeft) - headTextRect.addLeft(-m_headTextOffset.x); + headTextRect.expandLeft(-m_headTextOffset.x); else if(m_titleAlign & Fw::AlignRight) - headTextRect.addRight(-m_headTextOffset.x); + headTextRect.expandRight(-m_headTextOffset.x); else { - headTextRect.addLeft(-m_headTextOffset.x); - headTextRect.addRight(-m_headTextOffset.x); + headTextRect.expandLeft(-m_headTextOffset.x); + headTextRect.expandRight(-m_headTextOffset.x); } m_font->renderText(m_title, headTextRect, m_titleAlign, m_color); } @@ -111,7 +110,7 @@ void UIWindow::onMouseRelease(const Point& mousePos, Fw::MouseButton button) // restore position before move parent->moveChildToIndex(asUIWidget(), m_oldIndex); - moveTo(m_oldPos); + setPos(m_oldPos); // calculate new index int newIndex; @@ -133,7 +132,7 @@ void UIWindow::onMouseRelease(const Point& mousePos, Fw::MouseButton button) bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved) { if(m_moving) { - moveTo(mousePos - m_movingReference); + setPos(mousePos - m_movingReference); return true; } return UIWidget::onMouseMove(mousePos, mouseMoved); diff --git a/src/framework/ui/uiwindow.h b/src/framework/ui/uiwindow.h index c5049d66..8648cb6f 100644 --- a/src/framework/ui/uiwindow.h +++ b/src/framework/ui/uiwindow.h @@ -35,7 +35,7 @@ class UIWindow : public UIWidget public: UIWindow(); - virtual void render(); + virtual void draw(); void setTitle(const std::string& title) { m_title = title; } std::string getTitle() const { return m_title; } diff --git a/src/otclient/ui/uicreature.cpp b/src/otclient/ui/uicreature.cpp index 62581918..4b6debf2 100644 --- a/src/otclient/ui/uicreature.cpp +++ b/src/otclient/ui/uicreature.cpp @@ -24,14 +24,14 @@ #include #include -void UICreature::render() +void UICreature::draw() { - renderSelf(); + drawSelf(); if(m_creature) { g_painter.setColor(Fw::white); - m_creature->draw(m_rect.bottomRight() - Point(32, 32) + Point(m_paddingLeft, m_paddingTop), m_rect); + m_creature->draw(m_rect.bottomRight() - Point(32, 32) + Point(m_padding.left, m_padding.top), m_rect); } - renderChildren(); + drawChildren(); } diff --git a/src/otclient/ui/uicreature.h b/src/otclient/ui/uicreature.h index 44da3dcf..b99bad29 100644 --- a/src/otclient/ui/uicreature.h +++ b/src/otclient/ui/uicreature.h @@ -30,7 +30,7 @@ class UICreature : public UIWidget { public: - void render(); + void draw(); void setCreature(const CreaturePtr& creature) { m_creature = creature; } diff --git a/src/otclient/ui/uiitem.cpp b/src/otclient/ui/uiitem.cpp index beb63a56..bf964deb 100644 --- a/src/otclient/ui/uiitem.cpp +++ b/src/otclient/ui/uiitem.cpp @@ -30,12 +30,12 @@ UIItem::UIItem() m_font = g_fonts.getFont("verdana-11px-rounded"); } -void UIItem::render() +void UIItem::draw() { - renderSelf(); + drawSelf(); if(m_item) { - Point topLeft = m_rect.bottomRight() - Point(32, 32) + Point(m_paddingLeft, m_paddingTop); + Point topLeft = m_rect.bottomRight() - Point(32, 32) + Point(m_padding.left, m_padding.top); g_painter.setColor(Fw::white); m_item->draw(topLeft, m_rect); @@ -46,5 +46,5 @@ void UIItem::render() } } - renderChildren(); + drawChildren(); } diff --git a/src/otclient/ui/uiitem.h b/src/otclient/ui/uiitem.h index 64b08362..f9241e44 100644 --- a/src/otclient/ui/uiitem.h +++ b/src/otclient/ui/uiitem.h @@ -31,7 +31,7 @@ class UIItem : public UIWidget { public: UIItem(); - void render(); + void draw(); void setItem(const ItemPtr& item) { m_item = item; } ItemPtr getItem() { return m_item; } diff --git a/src/otclient/ui/uimap.cpp b/src/otclient/ui/uimap.cpp index 6561bd86..8c620961 100644 --- a/src/otclient/ui/uimap.cpp +++ b/src/otclient/ui/uimap.cpp @@ -27,15 +27,15 @@ #include #include -void UIMap::render() +void UIMap::draw() { - renderSelf(); + drawSelf(); g_painter.setColor(Fw::black); g_painter.drawBoundingRect(m_mapRect.expanded(1)); g_map.draw(m_mapRect); - renderChildren(); + drawChildren(); } TilePtr UIMap::getTile(const Point& mousePos) @@ -81,8 +81,7 @@ TilePtr UIMap::getTile(const Point& mousePos) void UIMap::onGeometryChange(const Rect& oldRect, const Rect& newRect) { - Rect mapRect = newRect.expanded(-1); - mapRect.add(-m_paddingTop, -m_paddingLeft, -m_paddingBottom, -m_paddingRight); + Rect mapRect = getChildrenRect().expanded(-1); Size mapSize(g_map.getVibibleSize().width() * Map::NUM_TILE_PIXELS, g_map.getVibibleSize().height() * Map::NUM_TILE_PIXELS); mapSize.scale(mapRect.size(), Fw::KeepAspectRatio); diff --git a/src/otclient/ui/uimap.h b/src/otclient/ui/uimap.h index 6984d1da..13020238 100644 --- a/src/otclient/ui/uimap.h +++ b/src/otclient/ui/uimap.h @@ -30,7 +30,7 @@ class UIMap : public UIWidget { public: - void render(); + void draw(); TilePtr getTile(const Point& mousePos); diff --git a/tools/lua-binding-generator/generate_lua_bindings.lua b/tools/lua-binding-generator/generate_lua_bindings.lua index b1b03c33..3a14bbd9 100755 --- a/tools/lua-binding-generator/generate_lua_bindings.lua +++ b/tools/lua-binding-generator/generate_lua_bindings.lua @@ -44,10 +44,10 @@ for line in io.lines(cppclassheader) do publicmethods = false if cppclassinstance then - print('g_lua.registerStaticClass("' .. luaclassname .. '");') + print(' g_lua.registerStaticClass("' .. luaclassname .. '");') else baseclassname = line:match(': public ([%w_]+)') - bindline = 'g_lua.registerClass<' .. cppclassname + bindline = ' g_lua.registerClass<' .. cppclassname if baseclassname and baseclassname ~= 'LuaObject' then bindline = bindline .. ', ' .. baseclassname @@ -56,7 +56,7 @@ for line in io.lines(cppclassheader) do bindline = bindline .. '>();' print(bindline) - bindline = 'g_lua.bindClassStaticFunction<' .. cppclassname .. '>("create", []{ return ' .. cppclassname .. 'Ptr(new ' .. cppclassname .. '); });' + bindline = ' g_lua.bindClassStaticFunction<' .. cppclassname .. '>("create", []{ return ' .. cppclassname .. 'Ptr(new ' .. cppclassname .. '); });' print(bindline) end elseif classfound then @@ -75,14 +75,14 @@ for line in io.lines(cppclassheader) do numargs = args:matchcount('[^,)]+[,)]') if cppclassinstance then - bindline = 'g_lua.bindClassStaticFunction("' .. luaclassname .. '", "' .. funcname .. '", ' .. + bindline = ' g_lua.bindClassStaticFunction("' .. luaclassname .. '", "' .. funcname .. '", ' .. 'std::bind(&' .. cppclassname .. "::" .. funcname .. ', &' .. cppclassinstance for i=1,numargs do bindline = bindline .. ', _' .. i end bindline = bindline .. '));' else - bindline = 'g_lua.bindClassMemberFunction<' .. cppclassname .. '>("' .. funcname .. '", &' .. + bindline = ' g_lua.bindClassMemberFunction<' .. cppclassname .. '>("' .. funcname .. '", &' .. cppclassname .. '::' .. funcname .. ');' end print(bindline)