UI tweaks

This commit is contained in:
Eduardo Bart 2012-04-30 13:40:12 -03:00
parent 3f689e0edf
commit beaba25af1
19 changed files with 154 additions and 80 deletions

22
BUGS
View File

@ -0,0 +1,22 @@
== CRASHS
modules recursivity makes client crash, it should generate a warning
== P1 BUGS (affects game play)
private channels are not closed when switching characters
sometimes minimap desync Z pos
follow and autowalk doesn't cancel when walking via hotkeys
== P2 BUGS
battle sometimes doesn't clear attacked/followed creatures when they go out of range
if you move a backpack to left panel, and resize it, client will go into a infinite loop resizing the backpack switching 4,5 columns
when looking from floor 5 in floor 7, sometimes a tile have 2 invisible grounds in floor 6 that should be ignored
== P3 BUGS
widgets may have been destroyed when adding event in onSetup (UIResizeBorder), generating invalid events
too many talk messages in game map make the messages boxes disappear
hotkeys works while windows are locked, it shouldn't
skulls is rendering outside map bounds
party options does not work when re-logging inside a party
sometimes we can still view hits from above/bottom floors from a fight that is not visible
must removeThing in protocol parseTileAdd when stackpos is greater than 11

119
TODO
View File

@ -1,51 +1,78 @@
== Core == MODULES
create a class for reading binary files game_shaders (with shader manager)
game_map (with save/load/options)
game_minimap (with all tibia functionality)
game_playertrade
game_textbooks
game_questlog
game_ruleviolations
== NOTABLE FEATURES
make left panel optional
must close last container when opening a new containers
add options "Copy Text", "Copy Name", "Message" in console labels with a popupmenu
move chat tabs
save/load mini windows states/location when restarting the client
graphics options menu
load modules from zip files
manual autoload setting in module manager
complete a smarter miniwindow moving/resizing
make miniwindow borderless on double click
== BEFORE RELEASE
polish interface skin
new optional skin
send otclient/system information to a third party server
== LATER FEATURES
reload spr/dat while ingame
create and bind new game events
text selection
login queue
port to MacOs and iphone
allow multiple Map and Game instances ?
== MINOR FEATURES
display exit box when exiting from game
case insensitive npctrade
load modules from zip packages
move up/down in lineedits
select characters in lineedits
scrolling multiline edit
mouse wheel lineedits
== OPTIMIZATIONS AND REWORKS
* game
do not redraw in MapView far zoom
map zoom rendering could be optimized using framebuffer caches
multisample option in map view
move redering of creatures names, skulls, etc to UI and scripts
clean sprites cache periodically
handle corrupt errors in dat/spr
* framework
rework Settings/g_configs
platform cursor cache
replace onKey events with Hotkeys.bind
add -no-sound option
rework lua/c++ logger rework lua/c++ logger
== Graphics * ui
map zoom rendering could be optimized using framebuffer caches rework hover => onWidgetVisibilityChange onWidgetEnableChange onWidgetMove onAppear onDisappear
implement graphics options menu reset dragging widget on destruction/visibility change/enable change
cancel layout changes on non visible widgets (acts like it doesn't exist)
add more anchors warnings to make creation of OTUIs easier
review UI/style loader and make more error prone with more warnings
change Align/Anchors lua API from enum to text
review widgets rendering order, consider adding z-index
reapply anchor styles when adding new childs
style inheritance using a style translator
find a way to add new widgets without focusing them
make set of background/icon/image width alone work
make api to enable/disable capture of events like mouseMove to avoid massive event processing
move layout proprieties to widget style
terminate rework of ui events propagation (for Key events)
== Modules * lua engine
fix modules recursivity, it makes client crash
load modules from zip packages
== Lua engine
make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size)
review usage of x,y/width,height in lua instead of point/size review usage of x,y/width,height in lua instead of point/size
== Platform
port to MacOs and iphone
== UI
review anchors API, add possibility to get/remove anchors
multiline rich text widget
move layout proprieties to widget style
multiline text editor widget
fix style inheritance using a style translator
find a way to add new widgets without focusing them
review UI/style loader and make more error prone with more warnings
reapply anchor styles when adding new childs
make set of background/icon/image width alone work
check for recursive anchors and print a error instead of crashing
make api to enable/disable capture of events like mouseMove to avoid massive event processing
review style apply system
review widgets rendering order, consider adding z-index
change Align/Anchors lua API from enum to text
== Game
clean sprites cache periodically
create a shader manager
find a way to load map rendering styles
move redering of creatures names, skulls, etc to UI
handle corrupt errors in dat/spr
remake spr/dat using OTML and image files
== Game modules
minimap window
login queue
questlog
edit texts
trade window
shop window

View File

@ -24,7 +24,7 @@ function Locales.init()
local userLocaleName = Settings.get('locale') local userLocaleName = Settings.get('locale')
if userLocaleName and Locales.setLocale(userLocaleName)then if userLocaleName and Locales.setLocale(userLocaleName)then
print('Using configurated locale: ' .. userLocaleName) print('Using configured locale: ' .. userLocaleName)
else else
print('Using default locale: ' .. defaultLocaleName) print('Using default locale: ' .. defaultLocaleName)
Locales.setLocale(defaultLocaleName) Locales.setLocale(defaultLocaleName)

View File

@ -26,14 +26,15 @@ ModuleInfoLabel < Label
ModuleValueLabel < UILabel ModuleValueLabel < UILabel
font: verdana-11px-antialised font: verdana-11px-antialised
color: #aaaaaa color: #aaaaaa
text-offset: 3 0 text-offset: 2 3
padding-bottom: 5
image-source: /core_styles/styles/images/panel_flat.png image-source: /core_styles/styles/images/panel_flat.png
image-border: 1 image-border: 1
height: 16 height: 20
MainWindow MainWindow
id: moduleManagerWindow id: moduleManagerWindow
size: 480 450 size: 450 450
!text: tr('Module Manager') !text: tr('Module Manager')
@onEscape: ModuleManager.hide() @onEscape: ModuleManager.hide()
@ -43,36 +44,47 @@ MainWindow
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: 180 width: 190
padding: 1 padding: 1
focusable: false focusable: false
margin-bottom: 30 margin-bottom: 30
vertical-scrollbar: moduleListScrollBar
VerticalScrollBar
id: moduleListScrollBar
anchors.top: moduleList.top
anchors.bottom: moduleList.bottom
anchors.left: moduleList.right
step: 14
pixels-scroll: true
Button Button
id: refreshModulesButton id: refreshModulesButton
anchors.top: moduleList.bottom anchors.top: moduleList.bottom
anchors.left: moduleList.left anchors.left: moduleList.left
margin-top: 8 margin-top: 8
width: 80
!text: tr('Refresh') !text: tr('Refresh')
text-auto-resize: true
@onClick: ModuleManager.refreshModules() @onClick: ModuleManager.refreshModules()
Button Button
id: reloadAllModulesButton id: reloadAllModulesButton
anchors.top: moduleList.bottom anchors.top: moduleList.bottom
anchors.right: moduleList.right anchors.right: moduleListScrollBar.right
margin-top: 8 margin-top: 8
width: 80
!text: tr('Reload All') !text: tr('Reload All')
text-auto-resize: true
@onClick: ModuleManager.reloadAllModules() @onClick: ModuleManager.reloadAllModules()
Panel Panel
id: moduleInfo id: moduleInfo
anchors.left: moduleList.right anchors.left: moduleListScrollBar.right
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
margin: 0 5 5 15 margin: 0 5 5 15
layout: verticalBox layout:
type: verticalBox
fit-children: true
height: 265 height: 265
ModuleInfoLabel ModuleInfoLabel
@ -84,8 +96,8 @@ MainWindow
!text: tr('Description') !text: tr('Description')
ModuleValueLabel ModuleValueLabel
id: moduleDescription id: moduleDescription
height: 100
text-wrap: true text-wrap: true
height: 100
//ModuleInfoLabel //ModuleInfoLabel
// !text: tr('Autoload') // !text: tr('Autoload')
@ -105,7 +117,7 @@ MainWindow
ModuleInfoLabel ModuleInfoLabel
!text: tr('Website') !text: tr('Website')
ModuleValueLabel TextEdit
id: moduleWebsite id: moduleWebsite
ModuleInfoLabel ModuleInfoLabel
@ -120,6 +132,7 @@ MainWindow
margin-top: 8 margin-top: 8
!text: tr('Load') !text: tr('Load')
enabled: false enabled: false
width: 90
@onClick: ModuleManager.reloadCurrentModule() @onClick: ModuleManager.reloadCurrentModule()
Button Button
@ -130,6 +143,7 @@ MainWindow
margin-top: 8 margin-top: 8
!text: tr('Unload') !text: tr('Unload')
enabled: false enabled: false
width: 90
@onClick: ModuleManager.unloadCurrentModule() @onClick: ModuleManager.unloadCurrentModule()
Button Button
@ -137,6 +151,6 @@ MainWindow
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
!text: tr('Close') !text: tr('Close')
width: 60 width: 90
@onClick: ModuleManager.hide() @onClick: ModuleManager.hide()

View File

@ -6,6 +6,7 @@ Button < UIButton
image-color: white image-color: white
image-source: /core_styles/styles/images/button.png image-source: /core_styles/styles/images/button.png
image-border: 5 image-border: 5
padding: 5 10 5 10
$hover !disabled: $hover !disabled:
image-source: /core_styles/styles/images/button_hover.png image-source: /core_styles/styles/images/button_hover.png

View File

@ -44,7 +44,7 @@ UIWidget
GameSidePanel GameSidePanel
id: gameRightPanel id: gameRightPanel
layout: verticalBox layout: verticalBox
anchors.left: rightSplitter.left width: 190
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -60,17 +60,6 @@ UIWidget
@canUpdateMargin: function(self, newMargin) return math.max(math.min(newMargin, self:getParent():getHeight() - 300), 100) end @canUpdateMargin: function(self, newMargin) return math.max(math.min(newMargin, self:getParent():getHeight() - 300), 100) end
@onGeometryChange: function(self) self:setMarginBottom(math.min(math.max(self:getParent():getHeight() - 300, 100), self:getMarginBottom())) end @onGeometryChange: function(self) self:setMarginBottom(math.min(math.max(self:getParent():getHeight() - 300, 100), self:getMarginBottom())) end
Splitter
id: rightSplitter
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
relative-margin: right
margin-right: 190
enabled: false
@canUpdateMargin: function(self, newMargin) return math.max(math.min(newMargin, self:getParent():getWidth() - 300), 150) end
@onGeometryChange: function(self) self:setMarginRight(math.min(math.max(self:getParent():getWidth() - 300, 150), self:getMarginRight())) end
UIWidget UIWidget
id: mouseGrabber id: mouseGrabber
focusable: false focusable: false

View File

@ -5,7 +5,6 @@ MiniWindow < UIMiniWindow
height: 200 height: 200
text-offset: 24 5 text-offset: 24 5
text-align: topLeft text-align: topLeft
margin-bottom: 2
image-source: /game/images/miniwindow.png image-source: /game/images/miniwindow.png
image-border: 4 image-border: 4
image-border-top: 23 image-border-top: 23
@ -84,7 +83,8 @@ MiniWindowContents < ScrollablePanel
id: contentsPanel id: contentsPanel
anchors.fill: parent anchors.fill: parent
anchors.right: miniwindowScrollBar.left anchors.right: miniwindowScrollBar.left
padding: 24 5 3 5 margin-top: 19
padding: 3 5 3 5
vertical-scrollbar: miniwindowScrollBar vertical-scrollbar: miniwindowScrollBar
BorderlessGameWindow < UIWindow BorderlessGameWindow < UIWindow

View File

@ -50,6 +50,7 @@ MiniWindow
anchors.top: parent.top anchors.top: parent.top
anchors.right: next.left anchors.right: next.left
margin-right: 5 margin-right: 5
margin-top: 3
BattleNPCs BattleNPCs
id: hideNPCs id: hideNPCs
@ -57,12 +58,14 @@ MiniWindow
anchors.top: parent.top anchors.top: parent.top
anchors.right: next.left anchors.right: next.left
margin-right: 5 margin-right: 5
margin-top: 3
BattleMonsters BattleMonsters
id: hideMonsters id: hideMonsters
!tooltip: tr('Hide monsters') !tooltip: tr('Hide monsters')
anchors.top: parent.top anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
margin-top: 3
BattleSkulls BattleSkulls
id: hideSkulls id: hideSkulls

View File

@ -99,7 +99,7 @@ local function onCreatureSpeak(name, level, speaktype, message, channelId, creat
if channel then if channel then
Console.addText(message, speaktype, channel) Console.addText(message, speaktype, channel)
elseif channelid ~= 0 then elseif channelId ~= 0 then
-- server sent a message on a channel that is not open -- server sent a message on a channel that is not open
warning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel') warning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel')
end end

View File

@ -27,9 +27,10 @@ ContainerWindow < MiniWindow
image-clip: 42 28 14 14 image-clip: 42 28 14 14
MiniWindowContents MiniWindowContents
padding: 27 6 6 8 padding-right: 0
layout: layout:
type: grid type: grid
cell-size: 34 34 cell-size: 40 40
flow: true flow: true
auto-spacing: true cell-spacing: 0

View File

@ -24,6 +24,10 @@ local function onContainerOpen(container, previousContainer)
containerWindow:hide() containerWindow:hide()
end end
-- this disables scrollbar auto hiding
local scrollbar = containerWindow:getChildById('miniwindowScrollBar')
scrollbar:mergeStyle({ ['$disabled'] = { ['width'] = scrollbar:getWidth() } })
local upButton = containerWindow:getChildById('upButton') local upButton = containerWindow:getChildById('upButton')
upButton.onClick = function() upButton.onClick = function()
g_game.openParent(container) g_game.openParent(container)
@ -41,6 +45,7 @@ local function onContainerOpen(container, previousContainer)
local itemWidget = createWidget('Item', containerPanel) local itemWidget = createWidget('Item', containerPanel)
itemWidget:setId('item' .. slot) itemWidget:setId('item' .. slot)
itemWidget:setItem(container:getItem(slot)) itemWidget:setItem(container:getItem(slot))
itemWidget:setMargin(3)
itemWidget.position = container:getSlotPosition(slot) itemWidget.position = container:getSlotPosition(slot)
end end

View File

@ -5,6 +5,7 @@ HealthBar < ProgressBar
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
margin-top: 3
ManaBar < ProgressBar ManaBar < ProgressBar
id: manaBar id: manaBar

View File

@ -11,6 +11,7 @@ MiniWindow
id: slot1 id: slot1
anchors.top: parent.top anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
margin-top: 4
&position: {x=65535, y=1, z=0} &position: {x=65535, y=1, z=0}
Item Item

View File

@ -72,6 +72,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("moveChildToIndex", &UIWidget::moveChildToIndex); g_lua.bindClassMemberFunction<UIWidget>("moveChildToIndex", &UIWidget::moveChildToIndex);
g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild); g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild);
g_lua.bindClassMemberFunction<UIWidget>("unlockChild", &UIWidget::unlockChild); g_lua.bindClassMemberFunction<UIWidget>("unlockChild", &UIWidget::unlockChild);
g_lua.bindClassMemberFunction<UIWidget>("mergeStyle", &UIWidget::mergeStyle);
g_lua.bindClassMemberFunction<UIWidget>("applyStyle", &UIWidget::applyStyle); g_lua.bindClassMemberFunction<UIWidget>("applyStyle", &UIWidget::applyStyle);
g_lua.bindClassMemberFunction<UIWidget>("addAnchor", &UIWidget::addAnchor); g_lua.bindClassMemberFunction<UIWidget>("addAnchor", &UIWidget::addAnchor);
g_lua.bindClassMemberFunction<UIWidget>("removeAnchor", &UIWidget::removeAnchor); g_lua.bindClassMemberFunction<UIWidget>("removeAnchor", &UIWidget::removeAnchor);

View File

@ -101,8 +101,10 @@ bool UIGridLayout::internalUpdate()
Point virtualPos = Point(column * (m_cellSize.width() + cellSpacing), line * (m_cellSize.height() + cellSpacing)); Point virtualPos = Point(column * (m_cellSize.width() + cellSpacing), line * (m_cellSize.height() + cellSpacing));
preferredHeight = virtualPos.y + m_cellSize.height(); preferredHeight = virtualPos.y + m_cellSize.height();
Point pos = topLeft + virtualPos - parentWidget->getVirtualOffset(); Point pos = topLeft + virtualPos - parentWidget->getVirtualOffset();
Rect dest = Rect(pos, m_cellSize);
dest.expand(-widget->getMarginTop(), -widget->getMarginRight(), -widget->getMarginBottom(), -widget->getMarginLeft());
if(widget->setRect(Rect(pos, m_cellSize))) if(widget->setRect(dest))
changed = true; changed = true;
index++; index++;

View File

@ -458,6 +458,13 @@ void UIWidget::unlockChild(const UIWidgetPtr& child)
} }
} }
void UIWidget::mergeStyle(const OTMLNodePtr& styleNode)
{
applyStyle(styleNode);
m_style->merge(styleNode);
updateStyle();
}
void UIWidget::applyStyle(const OTMLNodePtr& styleNode) void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
{ {
if(m_destroyed) if(m_destroyed)

View File

@ -90,6 +90,7 @@ public:
void moveChildToIndex(const UIWidgetPtr& child, int index); void moveChildToIndex(const UIWidgetPtr& child, int index);
void lockChild(const UIWidgetPtr& child); void lockChild(const UIWidgetPtr& child);
void unlockChild(const UIWidgetPtr& child); void unlockChild(const UIWidgetPtr& child);
void mergeStyle(const OTMLNodePtr& styleNode);
void applyStyle(const OTMLNodePtr& styleNode); void applyStyle(const OTMLNodePtr& styleNode);
void addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge); void addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge);
void removeAnchor(Fw::AnchorEdge anchoredEdge); void removeAnchor(Fw::AnchorEdge anchoredEdge);

View File

@ -43,7 +43,7 @@ void UIWidget::updateText()
// update rect size // update rect size
if(!m_rect.isValid() || m_textAutoResize) { if(!m_rect.isValid() || m_textAutoResize) {
Size textBoxSize = getTextSize(); Size textBoxSize = getTextSize();
textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.left); textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom);
Size size = getSize(); Size size = getSize();
if(size.width() <= 0 || (m_textAutoResize && !m_textWrap)) if(size.width() <= 0 || (m_textAutoResize && !m_textWrap))
size.setWidth(textBoxSize.width()); size.setWidth(textBoxSize.width());

View File

@ -38,7 +38,6 @@ void UIItem::drawSelf()
Rect drawRect = getClippingRect(); Rect drawRect = getClippingRect();
Point dest = drawRect.topLeft(); Point dest = drawRect.topLeft();
float scaleFactor = std::min(drawRect.width() / (float)m_item->getExactSize(), drawRect.height() / (float)m_item->getExactSize()); float scaleFactor = std::min(drawRect.width() / (float)m_item->getExactSize(), drawRect.height() / (float)m_item->getExactSize());
dest += (1 - scaleFactor)*32;
dest += m_item->getDisplacement() * scaleFactor; dest += m_item->getDisplacement() * scaleFactor;
g_painter->setColor(Color::white); g_painter->setColor(Color::white);