restore terminal, rework console

This commit is contained in:
Eduardo Bart 2012-01-07 15:36:58 -02:00
parent a3721b3a11
commit c4b2dd18d6
25 changed files with 265 additions and 143 deletions

2
TODO
View File

@ -44,6 +44,8 @@
[bart] padding [bart] padding
[bart] review and make more error prone with more warnings [bart] review and make more error prone with more warnings
[bart] a real working border and background property in otui [bart] a real working border and background property in otui
[bart] merge states declared in inherited styles
[bart] reapply anchor styles when adding new childs
== Client modules == Client modules
[bart] modules managment interface [bart] modules managment interface

View File

@ -1,12 +1,14 @@
MapEffects = {} MapEffects = {}
function MapEffects.init() function MapEffects.init()
--[[
local box = createWidget('ComboBox') local box = createWidget('ComboBox')
box:moveTo({x=100, y=8}) box:moveTo({x=100, y=8})
box:addOption('Normal') box:addOption('Normal')
box:addOption('Bloom') box:addOption('Bloom')
box:addOption('TV') box:addOption('TV')
--displayUI(box) displayUI(box)
]]--
end end
function MapEffects.terminate() function MapEffects.terminate()

View File

@ -1,4 +1,4 @@
Console = { } Terminal = { }
-- configs -- configs
local LogColors = { [LogInfo] = 'white', local LogColors = { [LogInfo] = 'white',
@ -8,11 +8,12 @@ local MaxLogLines = 80
local LabelHeight = 16 local LabelHeight = 16
-- private variables -- private variables
local consoleWidget local terminalWidget
local terminalButton
local logLocked = false local logLocked = false
local commandEnv = newenv() local commandEnv = newenv()
local commandLineEdit local commandLineEdit
local consoleBuffer local terminalBuffer
local commandHistory = { } local commandHistory = { }
local currentHistoryIndex = 0 local currentHistoryIndex = 0
@ -81,12 +82,12 @@ local function completeCommand()
end end
end end
local function onKeyPress(widget, keyCode, keyText, keyboardModifiers) local function onCommandLineKeyPress(widget, keyCode, keyText, keyboardModifiers)
if keyboardModifiers == KeyboardNoModifier then if keyboardModifiers == KeyboardNoModifier then
-- execute current command -- execute current command
if keyCode == KeyReturn or keyCode == keyEnter then if keyCode == KeyReturn or keyCode == KeyEnter then
local currentCommand = commandLineEdit:getText() local currentCommand = commandLineEdit:getText()
Console.executeCommand(currentCommand) Terminal.executeCommand(currentCommand)
commandLineEdit:clearText() commandLineEdit:clearText()
return true return true
-- navigate history up -- navigate history up
@ -114,46 +115,64 @@ local function onLog(level, message, time)
if logLocked then return end if logLocked then return end
logLocked = true logLocked = true
Console.addLine(message, LogColors[level]) Terminal.addLine(message, LogColors[level])
logLocked = false logLocked = false
end end
-- public functions -- public functions
function Console.init() function Terminal.init()
consoleWidget = displayUI('console.otui', { visible = false }) terminalWidget = displayUI('terminal.otui')
connect(consoleWidget, { onKeyPress = onKeyPress }) terminalWidget:setVisible(false)
commandLineEdit = consoleWidget:getChildById('commandLineEdit') terminalButton = TopMenu.addButton('terminalButton', 'Terminal', '/core_styles/icons/terminal.png', Terminal.show)
consoleBuffer = consoleWidget:getChildById('consoleBuffer')
commandLineEdit = terminalWidget:getChildById('commandLineEdit')
connect(commandLineEdit, { onKeyPress = onCommandLineKeyPress })
terminalBuffer = terminalWidget:getChildById('terminalBuffer')
Logger.setOnLog(onLog) Logger.setOnLog(onLog)
Logger.fireOldMessages() Logger.fireOldMessages()
end end
function Console.terminate() function Terminal.terminate()
Logger.setOnLog(nil) Logger.setOnLog(nil)
consoleWidget:destroy() terminalButton:destroy()
terminalButton = nil
commandLineEdit = nil commandLineEdit = nil
consoleWidget = nil terminalBuffer = nil
terminalWidget:destroy()
terminalWidget = nil
commandEnv = nil
end end
function Console.addLine(text, color) function Terminal.show()
terminalWidget:show()
terminalWidget:lock()
end
function Terminal.hide()
terminalWidget:unlock()
terminalWidget:hide()
end
function Terminal.addLine(text, color)
-- create new line label -- create new line label
local numLines = consoleBuffer:getChildCount() + 1 local numLines = terminalBuffer:getChildCount() + 1
local label = createWidget('ConsoleLabel', consoleBuffer) local label = createWidget('TerminalLabel', terminalBuffer)
label:setId('consoleLabel' .. numLines) label:setId('terminalLabel' .. numLines)
label:setText(text) label:setText(text)
label:setForegroundColor(color) label:setForegroundColor(color)
-- delete old lines if needed -- delete old lines if needed
if numLines > MaxLogLines then if numLines > MaxLogLines then
consoleBuffer:getChildByIndex(1):destroy() terminalBuffer:getChildByIndex(1):destroy()
else else
consoleBuffer:setHeight(consoleBuffer:getHeight() + LabelHeight) terminalBuffer:setHeight(terminalBuffer:getHeight() + LabelHeight)
consoleBuffer:updateParentLayout() terminalBuffer:updateParentLayout()
end end
end end
function Console.executeCommand(command) function Terminal.executeCommand(command)
-- detect and convert commands with simple syntax -- detect and convert commands with simple syntax
local realCommand local realCommand
if commandEnv[command] then if commandEnv[command] then
@ -173,7 +192,7 @@ function Console.executeCommand(command)
table.insert(commandHistory, command) table.insert(commandHistory, command)
-- add command line -- add command line
Console.addLine(">> " .. command, "#ffffff") Terminal.addLine(">> " .. command, "#ffffff")
-- load command buffer -- load command buffer
local func, err = loadstring(realCommand, "@") local func, err = loadstring(realCommand, "@")
@ -196,4 +215,3 @@ function Console.executeCommand(command)
Logger.log(LogError, 'command failed: ' .. ret) Logger.log(LogError, 'command failed: ' .. ret)
end end
end end

View File

@ -1,17 +1,16 @@
Module Module
name: console name: terminal
description: Console for executing lua functions description: Terminal for executing lua functions
author: OTClient team author: OTClient team
website: https://github.com/edubart/otclient website: https://github.com/edubart/otclient
// console can be loaded after core
autoLoad: true autoLoad: true
autoLoadPriority: 1000 autoLoadPriority: 1000
onLoad: | onLoad: |
require 'console' require 'terminal'
require 'commands' require 'commands'
Console.init() Terminal.init()
onUnload: | onUnload: |
Console.terminate() Terminal.terminate()

View File

@ -1,15 +1,15 @@
ConsoleLabel < UILabel TerminalLabel < UILabel
font: terminus-14px-bold font: terminus-14px-bold
height: 16 height: 16
RectPanel RectPanel
id: consolePanel id: terminalPanel
background-color: #000000 background-color: #000000
opacity: 216 opacity: 216
anchors.fill: parent anchors.fill: parent
Panel Panel
id: consoleBuffer id: terminalBuffer
layout: verticalBox layout: verticalBox
focusable: false focusable: false
anchors.left: parent.left anchors.left: parent.left

View File

@ -1,16 +1,20 @@
About = {} About = {}
-- private variables -- private variables
local aboutWindow local aboutButton
-- public functions -- public functions
function About.create() function About.init()
aboutButton = TopMenu.addRightButton('aboutButton', 'About', '/core_styles/icons/about.png', About.display)
end
function About.display()
aboutWindow = displayUI('about.otui', { locked = true }) aboutWindow = displayUI('about.otui', { locked = true })
end end
function About.destroy() function About.terminate()
aboutWindow:destroy() aboutButton:destroy()
aboutWindow = nil aboutButton = nil
end end
function About.openWebpage() function About.openWebpage()

View File

@ -6,3 +6,7 @@ Module
onLoad: | onLoad: |
require 'about' require 'about'
About.init()
onUnload:
About.terminate()

View File

@ -58,4 +58,4 @@ MainWindow
anchors.top: parent.top anchors.top: parent.top
margin-top: 191 margin-top: 191
margin-left: 188 margin-left: 188
@onClick: About.destroy() @onClick: self:getParent():destroy()

View File

@ -4,11 +4,11 @@ Background = { }
local background local background
-- public functions -- public functions
function Background.create() function Background.init()
background = displayUI('background.otui') background = displayUI('background.otui')
end end
function Background.destroy() function Background.terminate()
background:destroy() background:destroy()
background = nil background = nil
end end

View File

@ -6,8 +6,8 @@ Module
onLoad: | onLoad: |
require 'background' require 'background'
Background.create() Background.init()
onUnload: onUnload:
Background.destroy() Background.terminate()

View File

@ -5,6 +5,9 @@ local loadBox
local enterGame local enterGame
local motdNumber local motdNumber
local motdMessage local motdMessage
local motdButton
local enterGameButton
-- private functions -- private functions
local function clearAccountFields() local function clearAccountFields()
@ -25,7 +28,7 @@ end
local function onMotd(protocol, motd) local function onMotd(protocol, motd)
motdNumber = tonumber(motd:sub(0, motd:find("\n"))) motdNumber = tonumber(motd:sub(0, motd:find("\n")))
motdMessage = motd:sub(motd:find("\n") + 1, #motd) motdMessage = motd:sub(motd:find("\n") + 1, #motd)
TopMenu.getButton('motdButton'):show() motdButton:show()
end end
local function onCharacterList(protocol, characters, premDays) local function onCharacterList(protocol, characters, premDays)
@ -50,7 +53,10 @@ local function onCharacterList(protocol, characters, premDays)
end end
-- public functions -- public functions
function EnterGame.create() function EnterGame.init()
enterGameButton = TopMenu.addButton('enterGameButton', 'Login', '/core_styles/icons/login.png', EnterGame.openWindow)
motdButton = TopMenu.addButton('motdButton', 'Message of the day', '/core_styles/icons/motd.png', EnterGame.displayMotd)
motdButton:hide()
enterGame = displayUI('entergame.otui') enterGame = displayUI('entergame.otui')
local account = Settings.get('account') local account = Settings.get('account')
@ -72,9 +78,13 @@ function EnterGame.create()
end end
end end
function EnterGame.destroy() function EnterGame.terminate()
enterGame:destroy() enterGame:destroy()
enterGame = nil enterGame = nil
enterGameButton:destroy()
enterGameButton = nil
motdButton:destroy()
motdButton = nil
end end
function EnterGame.show() function EnterGame.show()
@ -86,6 +96,14 @@ function EnterGame.hide()
enterGame:hide() enterGame:hide()
end end
function EnterGame.openWindow()
if Game.isOnline() then
CharacterList.show()
elseif not CharacterList.isVisible() then
EnterGame.show()
end
end
function EnterGame.doLogin() function EnterGame.doLogin()
EnterGame.account = enterGame:getChildById('accountNameLineEdit'):getText() EnterGame.account = enterGame:getChildById('accountNameLineEdit'):getText()
EnterGame.password = enterGame:getChildById('accountPasswordLineEdit'):getText() EnterGame.password = enterGame:getChildById('accountPasswordLineEdit'):getText()
@ -111,5 +129,6 @@ function EnterGame.doLogin()
end end
function EnterGame.displayMotd() function EnterGame.displayMotd()
displayInfoBox("Message of the day", motdMessage) displayInfoBox('Message of the day', motdMessage)
end end

View File

@ -7,9 +7,9 @@ Module
onLoad: | onLoad: |
require 'entergame' require 'entergame'
require 'characterlist' require 'characterlist'
EnterGame.create() EnterGame.init()
onUnload: onUnload:
EnterGame.destroy() EnterGame.terminate()

View File

@ -1,5 +1,16 @@
Options = {} Options = {}
local optionsButton
function Options.init()
optionsButton = TopMenu.addButton('settingsButton', 'Options', '/core_styles/icons/settings.png', Options.show)
Options.load()
end
function Options.terminate()
TopMenu.removeButton(optionsButton)
end
function Options.load() function Options.load()
local booleanOptions = { vsync = true, local booleanOptions = { vsync = true,
showfps = true, showfps = true,

View File

@ -6,5 +6,7 @@ Module
onLoad: | onLoad: |
require 'options' require 'options'
Options.load() Options.init()
onUnload:
Options.terminate()

View File

@ -2,17 +2,74 @@ TopMenu = {}
-- private variables -- private variables
local topMenu local topMenu
local leftButtonsPanel
local rightButtonsPanel
-- public functions -- public functions
function TopMenu.create() function TopMenu.init()
topMenu = displayUI('topmenu.otui') topMenu = displayUI('topmenu.otui')
leftButtonsPanel = topMenu:getChildById('leftButtonsPanel')
rightButtonsPanel = topMenu:getChildById('rightButtonsPanel')
TopMenu.addRightButton('logoutButton', 'Logout', '/core_styles/icons/logout.png',
function()
if Game.isOnline() then
Game.logout(false)
else
exit()
end
end
)
end end
function TopMenu.destroy() function TopMenu.terminate()
leftButtonsPanel = nil
rightButtonsPanel = nil
topMenu:destroy() topMenu:destroy()
topMenu = nil topMenu = nil
end end
function TopMenu.getButton(id) function TopMenu.addButton(id, description, icon, callback, right)
return topMenu:getChildById(id) local panel
local class
if right then
panel = rightButtonsPanel
class = 'TopRightButton'
else
panel = leftButtonsPanel
class = 'TopLeftButton'
end
local button = createWidget(class, panel)
button:setId(id)
button:setTooltip(description)
button:setIcon(resolvepath(icon, 2))
button.onClick = callback
return button
end
function TopMenu.addLeftButton(id, description, icon, callback)
return TopMenu.addButton(id, description, icon, callback, false)
end
function TopMenu.addRightButton(id, description, icon, callback)
return TopMenu.addButton(id, description, icon, callback, true)
end
function TopMenu.removeButton(param)
local button
if type(param) == 'string' then
button = TopMenu.getButton(param)
else
button = param
end
button:destroy()
end
function TopMenu.getButton(id)
return topMenu:recursiveGetChildById(id)
end
function TopMenu:getLogoutButton(id)
return TopMenu.getButton('logoutButton')
end end

View File

@ -6,7 +6,7 @@ Module
onLoad: | onLoad: |
require 'topmenu' require 'topmenu'
TopMenu.create() TopMenu.init()
onUnload: | onUnload: |
TopMenu.destroy() TopMenu.terminate()

View File

@ -1,3 +1,52 @@
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
$hover:
border-image:
source: /core_styles/images/top_button.png
clip: 26 0 26 26
border: 3
$pressed:
text-translate: 1 1
border-image:
source: /core_styles/images/top_button.png
clip: 52 0 26 26
border: 3
$disabled:
background-color: #ffffff66
TopLeftButton < TopButton
$first:
anchors.top: parent.top
anchors.left: parent.left
margin-top: 4
margin-left: 6
$!first:
anchors.top: prev.top
anchors.left: prev.right
margin-left: 6
TopRightButton < TopButton
$first:
anchors.top: parent.top
anchors.right: parent.right
margin-top: 4
margin-right: 6
$!first:
anchors.top: prev.top
anchors.right: prev.left
margin-right: 6
TopPanel TopPanel
id: topMenu id: topMenu
anchors.top: parent.top anchors.top: parent.top
@ -5,63 +54,19 @@ TopPanel
anchors.right: parent.right anchors.right: parent.right
focusable: false focusable: false
TopButton Panel
id: settingsButton id: leftButtonsPanel
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
margin-top: 4 anchors.right: next.left
margin-left: 6
tooltip: Options
icon: /core_styles/icons/settings.png
@onClick: Options.show()
Panel
TopButton id: rightButtonsPanel
id: enterGameButton
anchors.top: prev.top
anchors.left: prev.right
margin-left: 6
tooltip: Enter game with a character
icon: /core_styles/icons/login.png
@onClick: |
if Game.isOnline() then
CharacterList.show()
elseif not CharacterList.isVisible() then
EnterGame.show()
end
TopButton
id: motdButton
anchors.top: prev.top
anchors.left: prev.right
margin-left: 6
tooltip: Message of the day
icon: /core_styles/icons/motd.png
visible: false
@onClick: EnterGame.displayMotd()
TopButton
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
margin-top: 4 width: 60
margin-right: 6
tooltip: Logout
icon: /core_styles/icons/logout.png
@onClick: |
if Game.isOnline() then
Game.logout(false)
else
exit()
end
TopButton
anchors.top: parent.top
anchors.right: prev.left
margin-top: 4
margin-right: 6
tooltip: About OTClient
icon: /core_styles/icons/about.png
@onClick: About.create()
FrameCounter FrameCounter
id: frameCounter id: frameCounter

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

View File

@ -24,28 +24,3 @@ Button < UIButton
color: #f0ad4d88 color: #f0ad4d88
background-color: #ffffff88 background-color: #ffffff88
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
$hover:
border-image:
source: /core_styles/images/top_button.png
clip: 26 0 26 26
border: 3
$pressed:
text-translate: 1 1
border-image:
source: /core_styles/images/top_button.png
clip: 52 0 26 26
border: 3
$disabled:
background-color: #ffffff66

View File

@ -63,7 +63,7 @@ public:
/// Returns the class name used in Lua /// Returns the class name used in Lua
virtual std::string getLuaObjectName() const { virtual std::string getLuaObjectName() const {
// this could later be cached for more performance // TODO: this could be cached for more performance
return Fw::demangleName(typeid(*this).name()); return Fw::demangleName(typeid(*this).name());
} }

View File

@ -95,6 +95,13 @@ void OTMLNode::addChild(const OTMLNodePtr& newChild)
for(const OTMLNodePtr& node : m_children) { for(const OTMLNodePtr& node : m_children) {
if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) { if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) {
newChild->setUnique(true); newChild->setUnique(true);
if(node->hasChildren() && newChild->hasChildren()) {
OTMLNodePtr tmpNode = node->clone();
tmpNode->merge(newChild);
newChild->copy(tmpNode);
}
replaceChild(node, newChild); replaceChild(node, newChild);
// remove any other child with the same tag // remove any other child with the same tag
@ -140,6 +147,18 @@ bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newC
return false; return false;
} }
void OTMLNode::copy(const OTMLNodePtr& node)
{
setTag(node->tag());
setValue(node->value());
setUnique(node->isUnique());
setNull(node->isNull());
setSource(node->source());
clear();
for(const OTMLNodePtr& child : node->m_children)
addChild(child->clone());
}
void OTMLNode::merge(const OTMLNodePtr& node) void OTMLNode::merge(const OTMLNodePtr& node)
{ {
for(const OTMLNodePtr& child : node->m_children) for(const OTMLNodePtr& child : node->m_children)

View File

@ -63,6 +63,7 @@ public:
void addChild(const OTMLNodePtr& newChild); void addChild(const OTMLNodePtr& newChild);
bool removeChild(const OTMLNodePtr& oldChild); bool removeChild(const OTMLNodePtr& oldChild);
bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild); bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild);
void copy(const OTMLNodePtr& node);
void merge(const OTMLNodePtr& node); void merge(const OTMLNodePtr& node);
void clear(); void clear();

View File

@ -411,6 +411,9 @@ void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason)
bool UILineEdit::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers) bool UILineEdit::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
{ {
if(UIWidget::onKeyPress(keyCode, keyText, keyboardModifiers))
return true;
if(keyCode == Fw::KeyDelete) // erase right character if(keyCode == Fw::KeyDelete) // erase right character
removeCharacter(true); removeCharacter(true);
else if(keyCode == Fw::KeyBackspace) // erase left character { else if(keyCode == Fw::KeyBackspace) // erase left character {
@ -433,8 +436,7 @@ bool UILineEdit::onKeyPress(uchar keyCode, std::string keyText, int keyboardModi
} else if(!keyText.empty() && (keyboardModifiers == Fw::KeyboardNoModifier || keyboardModifiers == Fw::KeyboardShiftModifier)) } else if(!keyText.empty() && (keyboardModifiers == Fw::KeyboardNoModifier || keyboardModifiers == Fw::KeyboardShiftModifier))
appendText(keyText); appendText(keyText);
else else
return UIWidget::onKeyPress(keyCode, keyText, keyboardModifiers); return false;
return true; return true;
} }

View File

@ -1116,8 +1116,12 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty
// anchors // anchors
else if(boost::starts_with(node->tag(), "anchors.")) { else if(boost::starts_with(node->tag(), "anchors.")) {
UIWidgetPtr parent = getParent(); UIWidgetPtr parent = getParent();
if(!parent) if(!parent) {
if(m_firstOnStyle)
throw OTMLException(node, "cannot create anchor, there is no parent widget!"); throw OTMLException(node, "cannot create anchor, there is no parent widget!");
else
continue;
}
UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout(); UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout();
if(!anchorLayout) if(!anchorLayout)
@ -1331,8 +1335,6 @@ void UIWidget::propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton bu
child->setPressed(false); child->setPressed(false);
} }
// fire release events only when pressed
if(isPressed())
onMouseRelease(mousePos, button); onMouseRelease(mousePos, button);
} }