lua console and some changes
This commit is contained in:
parent
033f14780d
commit
38529ea837
|
@ -84,11 +84,11 @@ SET(SOURCES
|
|||
src/framework/net/rsa.cpp
|
||||
|
||||
# framework util
|
||||
src/framework/util/logger.cpp
|
||||
src/framework/util/color.cpp
|
||||
src/framework/util/translator.cpp
|
||||
|
||||
# framework core
|
||||
src/framework/core/logger.cpp
|
||||
src/framework/core/configs.cpp
|
||||
src/framework/core/resourcemanager.cpp
|
||||
src/framework/core/eventdispatcher.cpp
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
Console = { }
|
||||
local console
|
||||
local logLocked = false
|
||||
|
||||
function Console.onLog(level, message, time)
|
||||
-- avoid logging while reporting logs (would cause a infinite loop)
|
||||
if not logLocked then
|
||||
logLocked = true
|
||||
|
||||
local color
|
||||
if level == LogDebug then
|
||||
color = '#5555ff'
|
||||
elseif level == LogInfo then
|
||||
color = '#55ff55'
|
||||
elseif level == LogWarning then
|
||||
color = '#ffff00'
|
||||
else
|
||||
color = '#ff0000'
|
||||
end
|
||||
|
||||
Console.addLine(message, color)
|
||||
|
||||
logLocked = false
|
||||
end
|
||||
end
|
||||
|
||||
function Console.addLine(text, color)
|
||||
-- create new label
|
||||
local label = UILabel.create()
|
||||
label:setStyle('ConsoleLabel')
|
||||
label:setText(text)
|
||||
label:setForegroundColor(color)
|
||||
|
||||
console:insertChild(label, -1)
|
||||
end
|
||||
|
||||
function Console.create()
|
||||
console = loadUI("/console/console.otui")
|
||||
rootWidget:addChild(console)
|
||||
console:hide()
|
||||
|
||||
Logger.setOnLog(Console.onLog)
|
||||
Logger.fireOldMessages()
|
||||
end
|
||||
|
||||
function Console.destroy()
|
||||
console:destroy()
|
||||
console = nil
|
||||
end
|
||||
|
||||
function Console.show()
|
||||
console.parent:lockChild(console)
|
||||
console.visible = true
|
||||
end
|
||||
|
||||
function Console.hide()
|
||||
console.parent:unlockChild(console)
|
||||
console.visible = false
|
||||
end
|
||||
|
||||
function Console.executeCommand(command)
|
||||
Console.addLine(">> " .. command, "#ffffff")
|
||||
local func, err = loadstring("return (" .. command .. ")", "@")
|
||||
if func then
|
||||
local ok, ret = pcall(func)
|
||||
if ok then
|
||||
Logger.log(LogDebug, "=> " .. tostring(ret))
|
||||
else
|
||||
Logger.log(LogError, 'command failed: ' .. ret)
|
||||
end
|
||||
else
|
||||
Logger.log(LogError, 'incorrect lua syntax: ' .. err:sub(5))
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
Module
|
||||
name: console
|
||||
description: Console for executing lua functions
|
||||
author: OTClient team
|
||||
website: https://github.com/edubart/otclient
|
||||
version: 0.2
|
||||
autoLoad: true
|
||||
dependencies:
|
||||
- core
|
||||
|
||||
onLoad: |
|
||||
require 'console'
|
||||
Console.create()
|
||||
return true
|
||||
|
||||
onUnload: |
|
||||
Console.destroy()
|
|
@ -0,0 +1,35 @@
|
|||
ConsoleLabel < UILabel
|
||||
font: terminus-14px-bold
|
||||
height: 16
|
||||
anchors.bottom: next.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
margin.left: 2
|
||||
|
||||
RectPanel
|
||||
id: consolePanel
|
||||
background-color: #000000
|
||||
opacity: 216
|
||||
anchors.fill: parent
|
||||
|
||||
UILabel
|
||||
size: 18 20
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
margin.left: 2
|
||||
font: terminus-14px-bold
|
||||
text: >>
|
||||
|
||||
UILineEdit
|
||||
id: commandBox
|
||||
height: 20
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: prev.right
|
||||
anchors.right: parent.right
|
||||
margin.left: 2
|
||||
font: terminus-14px-bold
|
||||
onAction: |
|
||||
function(self)
|
||||
Console.executeCommand(self:getText())
|
||||
self:clearText()
|
||||
end
|
|
@ -6,3 +6,11 @@ AnchorLeft = 3
|
|||
AnchorRight = 4
|
||||
AnchorVerticalCenter = 5
|
||||
AnchorHorizontalCenter = 6
|
||||
|
||||
LogDebug = 0
|
||||
LogInfo = 1
|
||||
LogWarning = 2
|
||||
LogError = 3
|
||||
LogFatal = 4
|
||||
|
||||
EmptyFunction = function() end
|
|
@ -11,45 +11,48 @@ function MessageBox.create(title, text, flags)
|
|||
|
||||
-- create messagebox window
|
||||
local window = UIWindow.create()
|
||||
window.id = "messageBoxWindow"
|
||||
window.title = title
|
||||
window:setStyle('Window')
|
||||
window:setId("messageBoxWindow")
|
||||
window:setTitle(title)
|
||||
window:centerIn("parent")
|
||||
rootWidget:addChild(window)
|
||||
window:lock()
|
||||
rootWidget:lockChild(window)
|
||||
|
||||
-- create messagebox label
|
||||
local label = UILabel.create()
|
||||
label.id = "messageBoxLabel"
|
||||
label.text = text
|
||||
label:addAnchor(AnchorHorizontalCenter, window.id, AnchorHorizontalCenter)
|
||||
label:addAnchor(AnchorTop, window.id, AnchorTop)
|
||||
label:setStyle('Label')
|
||||
label:setId("messageBoxLabel")
|
||||
label:setText(text)
|
||||
label:addAnchor(AnchorHorizontalCenter, window:getId(), AnchorHorizontalCenter)
|
||||
label:addAnchor(AnchorTop, window:getId(), AnchorTop)
|
||||
label:setMargin(27, 0)
|
||||
label:resizeToText()
|
||||
window:addChild(label)
|
||||
|
||||
-- set window size based on label size
|
||||
window.width = label.width + 60
|
||||
window.height = label.height + 64
|
||||
window:setWidth(label:getWidth() + 60)
|
||||
window:setHeight(label:getHeight() + 64)
|
||||
|
||||
-- setup messagebox first button
|
||||
local button1 = UIButton.create()
|
||||
button1.id = "messageBoxButton1"
|
||||
button1:addAnchor(AnchorBottom, window.id, AnchorBottom)
|
||||
button1:addAnchor(AnchorRight, window.id, AnchorRight)
|
||||
button1:setStyle('Button')
|
||||
button1:setId("messageBoxButton1")
|
||||
button1:addAnchor(AnchorBottom, window:getId(), AnchorBottom)
|
||||
button1:addAnchor(AnchorRight, window:getId(), AnchorRight)
|
||||
button1:setMargin(10)
|
||||
button1.width = 64
|
||||
button1:setWidth(64)
|
||||
window:addChild(button1)
|
||||
|
||||
if flags == MessageBoxOk then
|
||||
button1.text = "Ok"
|
||||
box.onOk = createEmptyFunction()
|
||||
button1:setText("Ok")
|
||||
box.onOk = EmptyFunction
|
||||
button1.onClick = function()
|
||||
box.onOk()
|
||||
box:destroy()
|
||||
end
|
||||
elseif flags == MessageBoxCancel then
|
||||
button1.text = "Cancel"
|
||||
box.onCancel = createEmptyFunction()
|
||||
button1:setText("Cancel")
|
||||
box.onCancel = EmptyFunction
|
||||
button1.onClick = function()
|
||||
box.onCancel()
|
||||
box:destroy()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
function createEmptyFunction()
|
||||
local emptyFunction = function() end
|
||||
return emptyFunction
|
||||
end
|
||||
|
||||
function print(...)
|
||||
local msg = ""
|
||||
for i,v in ipairs(arg) do
|
||||
msg = msg .. tostring(v) .. "\t"
|
||||
end
|
||||
Logger.log(LogInfo, msg)
|
||||
end
|
|
@ -1,19 +1,19 @@
|
|||
function UIWidget:setMargin(...)
|
||||
local params = {...}
|
||||
if #params == 1 then
|
||||
self.marginTop = params[1]
|
||||
self.marginRight = params[1]
|
||||
self.marginBottom = params[1]
|
||||
self.marginLeft = params[1]
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[1])
|
||||
self:setMarginBottom(params[1])
|
||||
self:setMarginLeft(params[1])
|
||||
elseif #params == 2 then
|
||||
self.marginTop = params[1]
|
||||
self.marginRight = params[2]
|
||||
self.marginBottom = params[1]
|
||||
self.marginLeft = params[2]
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[2])
|
||||
self:setMarginBottom(params[1])
|
||||
self:setMarginLeft(params[2])
|
||||
elseif #params == 4 then
|
||||
self.marginTop = params[1]
|
||||
self.marginRight = params[2]
|
||||
self.marginBottom = params[3]
|
||||
self.marginLeft = params[4]
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[2])
|
||||
self:setMarginBottom(params[3])
|
||||
self:setMarginLeft(params[4])
|
||||
end
|
||||
end
|
|
@ -11,6 +11,7 @@ Module
|
|||
importFont('helvetica-12px-bold')
|
||||
importFont('helvetica-12px')
|
||||
importFont('helvetica-14px-bold')
|
||||
importFont('terminus-14px-bold')
|
||||
|
||||
setDefaultFont('helvetica-12px')
|
||||
return true
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Font
|
||||
name: terminus-14px-bold
|
||||
height: 16
|
||||
spacing: 0 0
|
||||
top margin: 2
|
||||
texture: terminus-14px-bold.png
|
||||
glyph size: 16 16
|
||||
fixed glyph width: 8
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
|
@ -1,6 +1,6 @@
|
|||
Button < UIButton
|
||||
font: helvetica-11px-bold
|
||||
font-color: #f0ad4dff
|
||||
color: #f0ad4dff
|
||||
size: 106 24
|
||||
border-image:
|
||||
source: /core_ui/images/button.png
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 191 B |
|
@ -1,5 +1,8 @@
|
|||
Label < UILabel
|
||||
font: helvetica-12px
|
||||
color: #ffffff
|
||||
|
||||
LargerLabel < Label
|
||||
font: helvetica-12px-bold
|
||||
color: #ffffff
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
LineEdit < UILineEdit
|
||||
font: helvetica-12px
|
||||
size: 86 20
|
||||
text-margin: 3
|
||||
border-image:
|
||||
|
|
|
@ -12,4 +12,4 @@ RoundedPanel < Panel
|
|||
border: 4
|
||||
|
||||
RectPanel < UIWidget
|
||||
image: /core_ui/images/emptyrect.png
|
||||
image: /core_ui/images/empty_rect.png
|
|
@ -1,4 +1,5 @@
|
|||
Window < UIWindow
|
||||
font: helvetica-12px-bold
|
||||
size: 200 200
|
||||
head:
|
||||
height: 20
|
||||
|
@ -17,5 +18,4 @@ Window < UIWindow
|
|||
border.top: 0
|
||||
|
||||
MainWindow < Window
|
||||
anchors.centerIn: parent
|
||||
onLoad: function(self) self:lock() end
|
||||
anchors.centerIn: parent
|
|
@ -3,7 +3,7 @@ GFX = { }
|
|||
function GFX.fadeIn(widget, time, elapsed)
|
||||
if not elapsed then elapsed = 0 end
|
||||
if not time then time = 250 end
|
||||
widget.opacity = math.min((255*elapsed)/time, 255)
|
||||
widget:setOpacity(math.min((255*elapsed)/time, 255))
|
||||
if elapsed < time then
|
||||
scheduleEvent(function()
|
||||
GFX.fadeIn(widget, time, elapsed + 30)
|
||||
|
@ -14,7 +14,7 @@ end
|
|||
function GFX.fadeOut(widget, time, elapsed)
|
||||
if not elapsed then elapsed = 0 end
|
||||
if not time then time = 250 end
|
||||
widget.opacity = (255*(time - elapsed))/time
|
||||
widget:setOpacity((255*(time - elapsed))/time)
|
||||
if elapsed < time then
|
||||
scheduleEvent(function()
|
||||
GFX.fadeOut(widget, time, elapsed + 30)
|
||||
|
|
|
@ -31,8 +31,8 @@ function EnterGame_connectToLoginServer()
|
|||
end
|
||||
|
||||
local enterGameWindow = rootWidget:getChild("enterGameWindow")
|
||||
local account = enterGameWindow:getChild("accountNameLineEdit").text
|
||||
local password = enterGameWindow:getChild("accountPasswordLineEdit").text
|
||||
local account = enterGameWindow:getChild("accountNameLineEdit"):getText()
|
||||
local password = enterGameWindow:getChild("accountPasswordLineEdit"):getText()
|
||||
protocolLogin:login(account, password)
|
||||
|
||||
enterGameWindow:destroy()
|
||||
|
|
|
@ -50,4 +50,4 @@ MainWindow
|
|||
anchors.bottom: parent.bottom
|
||||
margin.bottom: 16
|
||||
margin.right: 16
|
||||
onClick: function(self) GFX.fadeOut(self.parent) end
|
||||
onClick: function(self) GFX.fadeOut(self:getParent()) end
|
||||
|
|
|
@ -58,4 +58,4 @@ MainWindow
|
|||
anchors.top: parent.top
|
||||
margin.top: 191
|
||||
margin.left: 188
|
||||
onClick: function(self) self.parent:destroy() end
|
||||
onClick: function(self) self:getParent():destroy() end
|
||||
|
|
|
@ -113,4 +113,4 @@ MainWindow
|
|||
anchors.bottom: parent.bottom
|
||||
margin.right: 10
|
||||
margin.bottom: 13
|
||||
onClick: function(self) self.parent:destroy() end
|
||||
onClick: function(self) self:getParent():destroy() end
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
|
||||
//namespace fw {
|
||||
|
||||
enum LogLevel {
|
||||
LogDebug = 0,
|
||||
LogInfo,
|
||||
LogWarning,
|
||||
LogError,
|
||||
LogFatal
|
||||
};
|
||||
|
||||
enum AlignmentFlag {
|
||||
AlignLeft = 1,
|
||||
AlignRight = 2,
|
||||
|
|
|
@ -5,17 +5,20 @@
|
|||
|
||||
Configs g_configs;
|
||||
|
||||
bool Configs::load(const std::string& fileName)
|
||||
bool Configs::load(const std::string& file)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
m_fileName = file;
|
||||
|
||||
if(!g_resources.fileExists(file))
|
||||
return false;
|
||||
|
||||
try {
|
||||
OTMLDocumentPtr doc = OTMLDocument::parse(fileName);
|
||||
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
||||
for(const OTMLNodePtr& child : doc->children())
|
||||
m_confsMap[child->tag()] = child->value();
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: could not load configurations: ", e.what());
|
||||
logError("could not load configurations: ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
class Configs
|
||||
{
|
||||
public:
|
||||
bool load(const std::string& fileName);
|
||||
bool load(const std::string& file);
|
||||
bool save();
|
||||
|
||||
void set(const std::string& key, const std::string& value) { m_confsMap[key] = value; }
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#include "logger.h"
|
||||
#include "eventdispatcher.h"
|
||||
|
||||
Logger g_logger;
|
||||
|
||||
Logger::Logger() : m_terminated(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Logger::log(LogLevel level, std::string message)
|
||||
{
|
||||
const static std::string logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " };
|
||||
|
||||
if(!m_terminated) {
|
||||
message.insert(0, logPrefixes[level]);
|
||||
std::cout << message << std::endl;
|
||||
|
||||
std::size_t now = std::time(NULL);
|
||||
m_logMessages.push_back(LogMessage(level, message, now));
|
||||
|
||||
if(m_onLog)
|
||||
g_dispatcher.addEvent(std::bind(m_onLog, level, message, now));
|
||||
}
|
||||
|
||||
if(level == LogFatal) {
|
||||
m_terminated = true;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::logFunc(LogLevel level, const std::string& message, std::string prettyFunction)
|
||||
{
|
||||
std::stringstream ss;
|
||||
prettyFunction = prettyFunction.substr(0, prettyFunction.find_first_of('('));
|
||||
if(prettyFunction.find_last_of(' ') != std::string::npos)
|
||||
prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1);
|
||||
|
||||
if(!prettyFunction.empty())
|
||||
ss << "[" << prettyFunction << "] ";
|
||||
|
||||
ss << message;
|
||||
log(level, ss.str());
|
||||
}
|
||||
|
||||
void Logger::fireOldMessages()
|
||||
{
|
||||
if(m_onLog) {
|
||||
for(const LogMessage& logMessage : m_logMessages)
|
||||
g_dispatcher.addEvent(std::bind(m_onLog, logMessage.level, logMessage.message, logMessage.when));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "../util/tools.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
struct LogMessage {
|
||||
LogMessage(LogLevel level, const std::string& message, std::size_t when) : level(level), message(message), when(when) { }
|
||||
LogLevel level;
|
||||
std::string message;
|
||||
std::size_t when;
|
||||
};
|
||||
|
||||
class Logger
|
||||
{
|
||||
typedef std::function<void(LogLevel, std::string, std::size_t)> OnLogCallback;
|
||||
|
||||
public:
|
||||
Logger();
|
||||
|
||||
void log(LogLevel level, std::string message);
|
||||
void logFunc(LogLevel level, const std::string& message, std::string prettyFunction);
|
||||
|
||||
void fireOldMessages();
|
||||
void setOnLog(const OnLogCallback& onLog) { m_onLog = onLog; }
|
||||
|
||||
private:
|
||||
std::vector<LogMessage> m_logMessages;
|
||||
OnLogCallback m_onLog;
|
||||
bool m_terminated;
|
||||
};
|
||||
|
||||
extern Logger g_logger;
|
||||
|
||||
// specialized logging
|
||||
#define logDebug(...) g_logger.log(LogDebug, fw::mkstr(__VA_ARGS__))
|
||||
#define logInfo(...) g_logger.log(LogInfo, fw::mkstr(__VA_ARGS__))
|
||||
#define logWarning(...) g_logger.log(LogWarning, fw::mkstr(__VA_ARGS__))
|
||||
#define logError(...) g_logger.log(LogError, fw::mkstr(__VA_ARGS__))
|
||||
#define logFatal(...) g_logger.log(LogFatal, fw::mkstr(__VA_ARGS__))
|
||||
|
||||
#define logTrace() g_logger.logFunc(LogDebug, "", __PRETTY_FUNCTION__)
|
||||
#define logTraceDebug(...) g_logger.logFunc(LogDebug, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceInfo(...) g_logger.logFunc(LogInfo, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceWarning(...) g_logger.logFunc(LogWarning, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceError(...) g_logger.logFunc(LogError, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
|
||||
#endif
|
|
@ -54,7 +54,7 @@ bool Module::load()
|
|||
logInfo("Loaded module '", m_name, "'");
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: failed to load module '", m_name, "': ", e.what());
|
||||
logError("failed to load module '", m_name, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ bool ModuleManager::discoverModule(const std::string& file)
|
|||
module->discover(moduleNode);
|
||||
m_modules.push_back(module);
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: failed to load module from '", file, "': ", e.what());
|
||||
logError("failed to load module from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -30,14 +30,14 @@ void ResourceManager::init(const char* argv0)
|
|||
}
|
||||
|
||||
if(!found)
|
||||
logFatal("FATAL ERROR: could not find modules directory");
|
||||
logFatal("could not find modules directory");
|
||||
|
||||
// setup write directory
|
||||
std::string dir = g_platform.getAppUserDir();
|
||||
if(g_resources.setWriteDir(dir))
|
||||
g_resources.addToSearchPath(dir);
|
||||
else
|
||||
logError("ERROR: could not setup write directory");
|
||||
logError("could not setup write directory");
|
||||
}
|
||||
|
||||
void ResourceManager::terminate()
|
||||
|
|
|
@ -41,13 +41,15 @@
|
|||
// additional utilities
|
||||
#include "util/types.h"
|
||||
#include "util/tools.h"
|
||||
#include "util/logger.h"
|
||||
#include "util/translator.h"
|
||||
#include "util/point.h"
|
||||
#include "util/color.h"
|
||||
#include "util/rect.h"
|
||||
#include "util/size.h"
|
||||
|
||||
// logger
|
||||
#include "core/logger.h"
|
||||
|
||||
// easy typing for _1, _2, ...
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
|
|
@ -18,8 +18,11 @@ void Font::load(const OTMLNodePtr& fontNode)
|
|||
if(!m_texture)
|
||||
throw std::runtime_error("failed to load texture for font");
|
||||
|
||||
// auto calculate widths
|
||||
calculateGlyphsWidthsAutomatically(glyphSize);
|
||||
if(OTMLNodePtr node = fontNode->get("fixed glyph width")) {
|
||||
for(int glyph = m_firstGlyph; glyph < 256; ++glyph)
|
||||
m_glyphsSize[glyph] = Size(node->value<int>(), m_glyphHeight);
|
||||
} else
|
||||
calculateGlyphsWidthsAutomatically(glyphSize);
|
||||
|
||||
// read custom widths
|
||||
if(OTMLNodePtr node = fontNode->get("glyph widths")) {
|
||||
|
|
|
@ -34,7 +34,7 @@ bool FontManager::importFont(std::string fontFile)
|
|||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: could not load font from '", fontFile, "': ", e.what());
|
||||
logError("could not load font from '", fontFile, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,6 @@ FontPtr FontManager::getDefaultFont()
|
|||
{
|
||||
// default font should always exists, otherwise the app may crash
|
||||
if(!m_defaultFont)
|
||||
logFatal("FATAL ERROR: no default font to display, cannot continue to run");
|
||||
logFatal("no default font to display, cannot continue to run");
|
||||
return m_defaultFont;
|
||||
}
|
||||
|
|
|
@ -194,8 +194,7 @@ void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords,
|
|||
stopDrawing();
|
||||
}
|
||||
|
||||
void Graphics::drawFilledRect(const Rect& screenCoords,
|
||||
const Color& color)
|
||||
void Graphics::drawFilledRect(const Rect& screenCoords)
|
||||
{
|
||||
assert(!m_drawing);
|
||||
|
||||
|
@ -208,8 +207,6 @@ void Graphics::drawFilledRect(const Rect& screenCoords,
|
|||
int top = screenCoords.top();
|
||||
int left = screenCoords.left();
|
||||
|
||||
glPushAttrib(GL_CURRENT_BIT);
|
||||
glColor4ubv(color.rgbaPtr());
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
|
@ -220,12 +217,10 @@ void Graphics::drawFilledRect(const Rect& screenCoords,
|
|||
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
void Graphics::drawBoundingRect(const Rect& screenCoords,
|
||||
const Color& color,
|
||||
int innerLineWidth)
|
||||
{
|
||||
assert(!m_drawing);
|
||||
|
@ -239,8 +234,6 @@ void Graphics::drawBoundingRect(const Rect& screenCoords,
|
|||
int top = screenCoords.top();
|
||||
int left = screenCoords.left();
|
||||
|
||||
glPushAttrib(GL_CURRENT_BIT);
|
||||
glColor4ubv(color.rgbaPtr());
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
|
@ -270,7 +263,6 @@ void Graphics::drawBoundingRect(const Rect& screenCoords,
|
|||
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void Graphics::bindColor(const Color& color)
|
||||
|
|
|
@ -45,11 +45,9 @@ public:
|
|||
const TexturePtr& texture,
|
||||
const Rect& textureCoords);
|
||||
|
||||
void drawFilledRect(const Rect& screenCoords,
|
||||
const Color& color);
|
||||
void drawFilledRect(const Rect& screenCoords);
|
||||
|
||||
void drawBoundingRect(const Rect& screenCoords,
|
||||
const Color& color = Color::green,
|
||||
int innerLineWidth = 1);
|
||||
|
||||
const Size& getScreenSize() const { return m_screenSize; }
|
||||
|
|
|
@ -35,7 +35,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
|||
|
||||
// checks texture max size
|
||||
if(width > maxTexSize || height > maxTexSize) {
|
||||
logError("ERROR: loading texture with size ", width, "x", height, " failed, "
|
||||
logError("loading texture with size ", width, "x", height, " failed, "
|
||||
"the maximum size allowed by the graphics card is ", maxTexSize, "x", maxTexSize, ",",
|
||||
"to prevent crashes the texture will be displayed as a blank texture");
|
||||
return 0;
|
||||
|
|
|
@ -31,7 +31,7 @@ TexturePtr TextureManager::getTexture(const std::string& textureFile)
|
|||
g_resources.loadFile(textureFile, fin);
|
||||
texture = loadPNG(fin);
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: unable to load texture '",textureFile,"': ", e.what());
|
||||
logError("unable to load texture '",textureFile,"': ", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,51 +10,71 @@ void LuaInterface::registerFunctions()
|
|||
// UIWidget
|
||||
g_lua.registerClass<UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create);
|
||||
|
||||
g_lua.bindClassMemberFunction("destroy", &UIWidget::destroy);
|
||||
g_lua.bindClassMemberFunction("addChild", &UIWidget::addChild);
|
||||
|
||||
g_lua.bindClassMemberField<UIWidget>("id", &UIWidget::getId, &UIWidget::setId);
|
||||
g_lua.bindClassMemberField<UIWidget>("enabled", &UIWidget::isEnabled, &UIWidget::setEnabled);
|
||||
g_lua.bindClassMemberField<UIWidget>("visible", &UIWidget::isVisible, &UIWidget::setVisible);
|
||||
g_lua.bindClassMemberField<UIWidget>("width", &UIWidget::getWidth, &UIWidget::setWidth);
|
||||
g_lua.bindClassMemberField<UIWidget>("height", &UIWidget::getHeight, &UIWidget::setHeight);
|
||||
g_lua.bindClassMemberField<UIWidget>("parent", &UIWidget::getParent, &UIWidget::setParent);
|
||||
g_lua.bindClassMemberField<UIWidget>("color", &UIWidget::getColor, &UIWidget::setColor);
|
||||
g_lua.bindClassMemberField<UIWidget>("opacity", &UIWidget::getOpacity, &UIWidget::setOpacity);
|
||||
g_lua.bindClassMemberField<UIWidget>("marginTop", &UIWidget::getMarginTop, &UIWidget::setMarginTop);
|
||||
g_lua.bindClassMemberField<UIWidget>("marginBottom", &UIWidget::getMarginBottom, &UIWidget::setMarginBottom);
|
||||
g_lua.bindClassMemberField<UIWidget>("marginLeft", &UIWidget::getMarginLeft, &UIWidget::setMarginLeft);
|
||||
g_lua.bindClassMemberField<UIWidget>("marginRight", &UIWidget::getMarginRight, &UIWidget::setMarginRight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setEnabled", &UIWidget::setEnabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isVisible", &UIWidget::isVisible);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setVisible", &UIWidget::setVisible);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getWidth", &UIWidget::getWidth);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setWidth", &UIWidget::setWidth);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getHeight", &UIWidget::getHeight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setHeight", &UIWidget::setHeight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getParent", &UIWidget::getParent);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getBackgroundColor", &UIWidget::getBackgroundColor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setBackgroundColor", &UIWidget::setBackgroundColor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getForegroundColor", &UIWidget::getForegroundColor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setForegroundColor", &UIWidget::setForegroundColor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getOpacity", &UIWidget::getOpacity);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setOpacity", &UIWidget::setOpacity);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setStyle", &UIWidget::setStyle);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginTop", &UIWidget::getMarginTop);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginTop", &UIWidget::setMarginTop);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginBottom", &UIWidget::getMarginBottom);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginBottom", &UIWidget::setMarginBottom);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginLeft", &UIWidget::getMarginLeft);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginRight", &UIWidget::getMarginRight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginRight", &UIWidget::setMarginRight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("fill", &UIWidget::fill);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("centerIn", &UIWidget::centerIn);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("addAnchor", &UIWidget::addAnchor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChild", &UIWidget::getChildById);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("insertChild", &UIWidget::insertChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("removeChild", &UIWidget::removeChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("addChild", &UIWidget::addChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("lock", &UIWidget::lock);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
|
||||
|
||||
|
||||
// UILabel
|
||||
g_lua.registerClass<UILabel, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UILabel>("create", &UILabel::create);
|
||||
g_lua.bindClassMemberField("text", &UILabel::getText, &UILabel::setText);
|
||||
g_lua.bindClassMemberFunction<UILabel>("getText", &UILabel::getText);
|
||||
g_lua.bindClassMemberFunction<UILabel>("setText", &UILabel::setText);
|
||||
g_lua.bindClassMemberFunction("resizeToText", &UILabel::resizeToText);
|
||||
|
||||
// UIButton
|
||||
g_lua.registerClass<UIButton, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIButton>("create", &UIButton::create);
|
||||
g_lua.bindClassMemberField("text", &UIButton::getText, &UIButton::setText);
|
||||
g_lua.bindClassMemberFunction<UIButton>("getText", &UIButton::getText);
|
||||
g_lua.bindClassMemberFunction<UIButton>("setText", &UIButton::setText);
|
||||
|
||||
// UILineEdit
|
||||
g_lua.registerClass<UILineEdit, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UILineEdit>("create", &UILineEdit::create);
|
||||
g_lua.bindClassMemberField("text", &UILineEdit::getText, &UILineEdit::setText);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("getText", &UILineEdit::getText);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("setText", &UILineEdit::setText);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("clearText", &UILineEdit::clearText);
|
||||
|
||||
// UIWindow
|
||||
g_lua.registerClass<UIWindow, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWindow>("create", &UIWindow::create);
|
||||
g_lua.bindClassMemberField("title", &UIWindow::getTitle, &UIWindow::setTitle);
|
||||
g_lua.bindClassMemberFunction<UIWindow>("getTitle", &UIWindow::getTitle);
|
||||
g_lua.bindClassMemberFunction<UIWindow>("setTitle", &UIWindow::setTitle);
|
||||
|
||||
// Protocol
|
||||
g_lua.registerClass<Protocol>();
|
||||
|
@ -64,6 +84,12 @@ void LuaInterface::registerFunctions()
|
|||
g_lua.bindClassStaticFunction<Configs>("set", std::bind(&Configs::set, &g_configs, _1, _2));
|
||||
g_lua.bindClassStaticFunction<Configs>("get", std::bind(&Configs::get, &g_configs, _1));
|
||||
|
||||
// Logger
|
||||
g_lua.registerClass<Logger>();
|
||||
g_lua.bindClassStaticFunction<Logger>("log", std::bind(&Logger::log, &g_logger, _1, _2));
|
||||
g_lua.bindClassStaticFunction<Logger>("fireOldMessages", std::bind(&Logger::fireOldMessages, &g_logger));
|
||||
g_lua.bindClassStaticFunction<Logger>("setOnLog", std::bind(&Logger::setOnLog, &g_logger, _1));
|
||||
|
||||
// global functions
|
||||
g_lua.bindGlobalFunction("importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
||||
g_lua.bindGlobalFunction("importStyles", std::bind(&UIManager::importStyles, &g_ui, _1));
|
||||
|
|
|
@ -422,7 +422,7 @@ int LuaInterface::protectedCall(int numArgs, int requestedResults)
|
|||
throw LuaException("attempt to call a non function value", 0);
|
||||
}
|
||||
} catch(LuaException &e) {
|
||||
logError(e.what());
|
||||
logError("protected lua call failed: ", e.what());
|
||||
}
|
||||
|
||||
// pushes nil values if needed
|
||||
|
@ -457,7 +457,7 @@ int LuaInterface::luaScriptLoader(lua_State* L)
|
|||
g_lua.loadScript(fileName);
|
||||
return 1;
|
||||
} catch(LuaException& e) {
|
||||
logError("ERROR: failed to load script file '", fileName, "' :'", e.what());
|
||||
logError("failed to load script file '", fileName, "' :'", e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ int LuaInterface::luaCppFunctionCallback(lua_State* L)
|
|||
numRets = (*(funcPtr->get()))(&g_lua);
|
||||
assert(numRets == g_lua.stackSize());
|
||||
} catch(LuaException &e) {
|
||||
logError(e.what());
|
||||
logError("lua cpp callback failed: ", e.what());
|
||||
}
|
||||
|
||||
return numRets;
|
||||
|
|
|
@ -7,10 +7,10 @@ LuaObject::LuaObject() : m_fieldsTableRef(-1)
|
|||
|
||||
LuaObject::~LuaObject()
|
||||
{
|
||||
luaReleaseFieldsTable();
|
||||
releaseLuaFieldsTable();
|
||||
}
|
||||
|
||||
void LuaObject::luaReleaseFieldsTable()
|
||||
void LuaObject::releaseLuaFieldsTable()
|
||||
{
|
||||
if(m_fieldsTableRef != -1)
|
||||
g_lua.unref(m_fieldsTableRef);
|
||||
|
|
|
@ -15,6 +15,8 @@ public:
|
|||
/// @return the number of results
|
||||
template<typename... T>
|
||||
int callLuaField(const std::string& field, const T&... args);
|
||||
template<typename R, typename... T>
|
||||
R callLuaField(const std::string& field, const T&... args);
|
||||
|
||||
/// Sets a field in this lua object
|
||||
template<typename T>
|
||||
|
@ -25,7 +27,7 @@ public:
|
|||
T getLuaField(const std::string& key);
|
||||
|
||||
/// Release fields table reference
|
||||
void luaReleaseFieldsTable();
|
||||
void releaseLuaFieldsTable();
|
||||
|
||||
/// Sets a field from this lua object, the value must be on the stack
|
||||
void luaSetField(const std::string& key);
|
||||
|
@ -61,12 +63,28 @@ int LuaObject::callLuaField(const std::string& field, const T&... args) {
|
|||
g_lua.pushObject(asLuaObject());
|
||||
g_lua.getField(field);
|
||||
|
||||
// the first argument is always this object (self)
|
||||
g_lua.insert(-2);
|
||||
g_lua.polymorphicPush(args...);
|
||||
return g_lua.protectedCall(1 + sizeof...(args));
|
||||
if(!g_lua.isNil()) {
|
||||
// the first argument is always this object (self)
|
||||
g_lua.insert(-2);
|
||||
g_lua.polymorphicPush(args...);
|
||||
return g_lua.protectedCall(1 + sizeof...(args));
|
||||
} else {
|
||||
g_lua.pop(2);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename R, typename... T>
|
||||
R LuaObject::callLuaField(const std::string& field, const T&... args) {
|
||||
R result;
|
||||
int rets = callLuaField(field, args...);
|
||||
if(rets > 0) {
|
||||
assert(rets == 1);
|
||||
result = g_lua.polymorphicPop<R>();
|
||||
} else
|
||||
return 0;
|
||||
result = R();
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -81,4 +99,4 @@ T LuaObject::getLuaField(const std::string& key) {
|
|||
return g_lua.polymorphicPop<T>();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -42,6 +42,20 @@ bool luavalue_cast(int index, double& d)
|
|||
return true;
|
||||
}
|
||||
|
||||
// size_t
|
||||
void push_luavalue(std::size_t s)
|
||||
{
|
||||
push_luavalue((double)s);
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, std::size_t& s)
|
||||
{
|
||||
double d;
|
||||
bool ret = luavalue_cast(index, d);
|
||||
s = d;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// string
|
||||
void push_luavalue(const char* cstr)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,10 @@ bool luavalue_cast(int index, int& i);
|
|||
void push_luavalue(double d);
|
||||
bool luavalue_cast(int index, double& d);
|
||||
|
||||
// size_t
|
||||
void push_luavalue(std::size_t s);
|
||||
bool luavalue_cast(int index, std::size_t& s);
|
||||
|
||||
// string
|
||||
void push_luavalue(const char* cstr);
|
||||
void push_luavalue(const std::string& str);
|
||||
|
@ -131,7 +135,7 @@ bool luavalue_cast(int index, std::function<void(Args...)>& func) {
|
|||
"did you forget to hold a reference for that function?", 0);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
logError(e.what());
|
||||
logError("lua function callback failed: ", e.what());
|
||||
}
|
||||
};
|
||||
return true;
|
||||
|
@ -165,7 +169,7 @@ luavalue_cast(int index, std::function<Ret(Args...)>& func) {
|
|||
"did you forget to hold a reference for that function?", 0);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
logError(e.what());
|
||||
logError("lua function callback failed: ", e.what());
|
||||
}
|
||||
return Ret();
|
||||
};
|
||||
|
|
|
@ -67,7 +67,7 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
|||
uint32 checksum = getAdlerChecksum(m_inputMessage.getBuffer() + InputMessage::DATA_POS, m_inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH);
|
||||
if(m_inputMessage.getU32() != checksum) {
|
||||
// error
|
||||
logError("ERROR: got a network message with invalid checksum");
|
||||
logError("got a network message with invalid checksum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
|||
// FIXME: this function has not been tested yet
|
||||
uint16 messageSize = inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH;
|
||||
if(messageSize % 8 != 0) {
|
||||
logError("ERROR: invalid encrypted network message");
|
||||
logError("invalid encrypted network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
|||
|
||||
int tmp = inputMessage.getU16();
|
||||
if(tmp > inputMessage.getMessageSize() - 4) {
|
||||
logDebug("ERROR: invalid decrypted a network message");
|
||||
logError("invalid decrypted a network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
class OTMLDocument : public OTMLNode
|
||||
{
|
||||
public:
|
||||
OTMLDocument() { }
|
||||
virtual ~OTMLDocument() { }
|
||||
|
||||
/// Create a new OTML document for filling it with nodes
|
||||
|
@ -24,6 +23,9 @@ public:
|
|||
|
||||
/// Save this document to a file
|
||||
bool save(const std::string& fileName);
|
||||
|
||||
private:
|
||||
OTMLDocument() { }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -161,7 +161,6 @@ enum PlatformEventType {
|
|||
EventMouseLeftButton = 32,
|
||||
EventMouseRightButton = 64,
|
||||
EventMouseMidButton = 128,
|
||||
EventTextEnter = 256,
|
||||
EventKeyDown = EventKeyboardAction | EventDown,
|
||||
EventKeyUp = EventKeyboardAction | EventUp,
|
||||
EventMouseMove = EventMouseAction | 512,
|
||||
|
|
|
@ -217,17 +217,17 @@ void Platform::init(PlatformListener* platformListener, const char *appName)
|
|||
// open display
|
||||
x11.display = XOpenDisplay(0);
|
||||
if(!x11.display)
|
||||
logFatal("FATAL ERROR: Failed to open X display");
|
||||
logFatal("Failed to open X display");
|
||||
|
||||
// check if GLX is supported on this display
|
||||
if(!glXQueryExtension(x11.display, 0, 0))
|
||||
logFatal("FATAL ERROR: GLX not supported");
|
||||
logFatal("GLX not supported");
|
||||
|
||||
// retrieve GLX version
|
||||
int glxMajor;
|
||||
int glxMinor;
|
||||
if(!glXQueryVersion(x11.display, &glxMajor, &glxMinor))
|
||||
logFatal("FATAL ERROR: Unable to query GLX version");
|
||||
logFatal("Unable to query GLX version");
|
||||
logInfo("GLX version ",glxMajor,".",glxMinor);
|
||||
|
||||
// clipboard related atoms
|
||||
|
@ -313,6 +313,7 @@ void Platform::poll()
|
|||
inputEvent.ctrl = (event.xkey.state & ControlMask);
|
||||
inputEvent.shift = (event.xkey.state & ShiftMask);
|
||||
inputEvent.alt = (event.xkey.state & Mod1Mask);
|
||||
inputEvent.keychar = 0;
|
||||
|
||||
// fire enter text event
|
||||
if(event.type == KeyPress && !inputEvent.ctrl && !inputEvent.alt) {
|
||||
|
@ -325,7 +326,7 @@ void Platform::poll()
|
|||
}
|
||||
|
||||
if(len > 0 &&
|
||||
// for some reason these keys produces characters and we don't want that
|
||||
// these keys produces characters that we don't want to capture
|
||||
keysym != XK_BackSpace &&
|
||||
keysym != XK_Return &&
|
||||
keysym != XK_Delete &&
|
||||
|
@ -333,10 +334,7 @@ void Platform::poll()
|
|||
(uchar)(buf[0]) >= 32
|
||||
) {
|
||||
//logDebug("char: ", buf[0], " code: ", (uint)buf[0]);
|
||||
inputEvent.type = EventTextEnter;
|
||||
inputEvent.keychar = buf[0];
|
||||
inputEvent.keycode = KC_UNKNOWN;
|
||||
m_listener->onPlatformEvent(inputEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,13 +342,19 @@ void Platform::poll()
|
|||
event.xkey.state &= ~(ShiftMask | LockMask);
|
||||
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, 0);
|
||||
|
||||
// fire key up/down event
|
||||
if(x11.keyMap.find(keysym) != x11.keyMap.end()) {
|
||||
inputEvent.keycode = x11.keyMap[keysym];
|
||||
inputEvent.type = (event.type == KeyPress) ? EventKeyDown : EventKeyUp;
|
||||
if(inputEvent.keychar == 0)
|
||||
inputEvent.keychar = (len > 0) ? buf[0] : 0;
|
||||
|
||||
if(x11.keyMap.find(keysym) != x11.keyMap.end())
|
||||
inputEvent.keycode = x11.keyMap[keysym];
|
||||
else
|
||||
inputEvent.keycode = KC_UNKNOWN;
|
||||
|
||||
inputEvent.keycode = x11.keyMap[keysym];
|
||||
inputEvent.type = (event.type == KeyPress) ? EventKeyDown : EventKeyUp;
|
||||
|
||||
if(inputEvent.keycode != KC_UNKNOWN || inputEvent.keychar != 0)
|
||||
m_listener->onPlatformEvent(inputEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ButtonPress:
|
||||
|
@ -480,12 +484,12 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
|
|||
// choose OpenGL, RGBA, double buffered, visual
|
||||
x11.visual = glXChooseVisual(x11.display, DefaultScreen(x11.display), attrList);
|
||||
if(!x11.visual)
|
||||
logFatal("FATAL ERROR: RGBA/Double buffered visual not supported");
|
||||
logFatal("RGBA/Double buffered visual not supported");
|
||||
|
||||
// create GLX context
|
||||
x11.glxContext = glXCreateContext(x11.display, x11.visual, 0, GL_TRUE);
|
||||
if(!x11.glxContext)
|
||||
logFatal("FATAL ERROR: Unable to create GLX context");
|
||||
logFatal("Unable to create GLX context");
|
||||
|
||||
// color map
|
||||
x11.colormap = XCreateColormap(x11.display,
|
||||
|
@ -518,7 +522,7 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
|
|||
&wa);
|
||||
|
||||
if(!x11.window)
|
||||
logFatal("FATAL ERROR: Unable to create X window");
|
||||
logFatal("Unable to create X window");
|
||||
|
||||
// create input context (to have better key input handling)
|
||||
if(XSupportsLocale()) {
|
||||
|
@ -530,11 +534,11 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
|
|||
XIMPreeditNothing | XIMStatusNothing,
|
||||
XNClientWindow, x11.window, NULL);
|
||||
if(!x11.xic)
|
||||
logError("ERROR: Unable to create the input context");
|
||||
logError("Unable to create the input context");
|
||||
} else
|
||||
logError("ERROR: Failed to open an input method");
|
||||
logError("Failed to open an input method");
|
||||
} else
|
||||
logError("ERROR: X11 does not support the current locale");
|
||||
logError("X11 does not support the current locale");
|
||||
|
||||
if(!x11.xic)
|
||||
logWarning("Input of special keys maybe messed up because we couldn't create an input context");
|
||||
|
@ -823,6 +827,6 @@ std::string Platform::getAppUserDir()
|
|||
std::stringstream sdir;
|
||||
sdir << PHYSFS_getUserDir() << "." << x11.appName;
|
||||
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
|
||||
logError("ERROR: Couldn't create directory for saving configuration file. (",sdir.str(),")");
|
||||
logError("Couldn't create directory for saving configuration file. (",sdir.str(),")");
|
||||
return sdir.str();
|
||||
}
|
|
@ -9,7 +9,8 @@ enum UIWidgetType {
|
|||
UITypeButton,
|
||||
UITypeLineEdit,
|
||||
UITypeWindow,
|
||||
UITypeList
|
||||
UITypeList,
|
||||
UITypeConsole
|
||||
};
|
||||
|
||||
enum FocusReason {
|
||||
|
|
|
@ -13,6 +13,7 @@ class UILabel;
|
|||
class UIButton;
|
||||
class UILineEdit;
|
||||
class UIWindow;
|
||||
class UIConsole;
|
||||
|
||||
typedef std::shared_ptr<UIWidget> UIWidgetPtr;
|
||||
typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
|
||||
|
@ -25,5 +26,6 @@ typedef std::shared_ptr<UILabel> UILabelPtr;
|
|||
typedef std::shared_ptr<UIButton> UIButtonPtr;
|
||||
typedef std::shared_ptr<UILineEdit> UILineEditPtr;
|
||||
typedef std::shared_ptr<UIWindow> UIWindowPtr;
|
||||
typedef std::shared_ptr<UIConsole> UIConsolePtr;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,23 +8,32 @@ bool UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, AnchorPoint an
|
|||
|
||||
/*
|
||||
if(!anchorLineWidget) {
|
||||
logError("ERROR: could not find the widget to anchor on, wrong id?");
|
||||
logError("could not find the widget to anchor on, wrong id?");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// we can never anchor with itself
|
||||
if(anchoredWidget == anchorLineWidget) {
|
||||
logError("ERROR: anchoring with itself is not possible");
|
||||
logError("anchoring with itself is not possible");
|
||||
return false;
|
||||
}
|
||||
|
||||
// we must never anchor to an anchor child
|
||||
if(anchoredWidget && hasWidgetInAnchorTree(anchorLineWidget, anchoredWidget)) {
|
||||
logError("ERROR: anchors is miss configured, you must never make an anchor chains in loops");
|
||||
logError("anchors is miss configured, you must never make an anchor chains in loops");
|
||||
return false;
|
||||
}
|
||||
|
||||
// avoid duplicated anchors
|
||||
for(auto it = m_anchors.begin(); it != m_anchors.end(); ++it) {
|
||||
const UIAnchor& otherAnchor = *it;
|
||||
if(otherAnchor.getAnchoredWidget() == anchoredWidget && otherAnchor.getAnchoredEdge() == anchoredEdge) {
|
||||
m_anchors.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// setup the anchor
|
||||
m_anchors.push_back(anchor);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <framework/graphics/font.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
#include <framework/luascript/luainterface.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
UIButton::UIButton(): UIWidget(UITypeButton)
|
||||
{
|
||||
|
@ -25,8 +26,8 @@ void UIButton::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
|
||||
for(int i=0; i<3; ++i) {
|
||||
m_statesStyle[i].image = m_image;
|
||||
m_statesStyle[i].color = m_color;
|
||||
m_statesStyle[i].fontColor = m_fontColor;
|
||||
m_statesStyle[i].color = m_backgroundColor;
|
||||
m_statesStyle[i].foregroundColor = m_foregroundColor;
|
||||
m_statesStyle[i].textTranslate = Point(0,0);
|
||||
}
|
||||
|
||||
|
@ -40,8 +41,8 @@ void UIButton::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
m_text = styleNode->valueAt("text", fw::empty_string);
|
||||
|
||||
if(OTMLNodePtr node = styleNode->get("onClick")) {
|
||||
g_lua.loadFunction(node->value<std::string>(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
luaSetField("onClick");
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
luaSetField(node->tag());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,20 +53,24 @@ void UIButton::loadStateStyle(ButtonStateStyle& stateStyle, const OTMLNodePtr& s
|
|||
if(OTMLNodePtr node = stateStyleNode->get("image"))
|
||||
stateStyle.image = Image::loadFromOTML(node);
|
||||
stateStyle.textTranslate = stateStyleNode->valueAt("text-translate", Point());
|
||||
stateStyle.color = stateStyleNode->valueAt("font-color", m_fontColor);
|
||||
stateStyle.color = stateStyleNode->valueAt("color", m_color);
|
||||
stateStyle.color = stateStyleNode->valueAt("font-color", m_foregroundColor);
|
||||
stateStyle.color = stateStyleNode->valueAt("color", m_backgroundColor);
|
||||
}
|
||||
|
||||
void UIButton::render()
|
||||
{
|
||||
UIWidget::render();
|
||||
|
||||
const ButtonStateStyle& currentStyle = m_statesStyle[m_state];
|
||||
Rect textRect = getGeometry();
|
||||
|
||||
if(currentStyle.image)
|
||||
if(currentStyle.image) {
|
||||
g_graphics.bindColor(currentStyle.color);
|
||||
currentStyle.image->draw(textRect);
|
||||
}
|
||||
|
||||
textRect.translate(currentStyle.textTranslate);
|
||||
getFont()->renderText(m_text, textRect, AlignCenter, currentStyle.fontColor);
|
||||
m_font->renderText(m_text, textRect, AlignCenter, currentStyle.foregroundColor);
|
||||
}
|
||||
|
||||
void UIButton::onHoverChange(UIHoverEvent& event)
|
||||
|
|
|
@ -8,7 +8,7 @@ class UIButton : public UIWidget
|
|||
struct ButtonStateStyle {
|
||||
ImagePtr image;
|
||||
Point textTranslate;
|
||||
Color fontColor;
|
||||
Color foregroundColor;
|
||||
Color color;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ UILabel::UILabel() : UIWidget(UITypeLabel)
|
|||
UILabelPtr UILabel::create()
|
||||
{
|
||||
UILabelPtr label(new UILabel);
|
||||
label->setStyle("Label");
|
||||
return label;
|
||||
}
|
||||
|
||||
|
@ -23,17 +22,23 @@ void UILabel::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
if(styleNode->hasChildAt("align"))
|
||||
m_align = fw::translateAlignment(styleNode->valueAt("align"));
|
||||
|
||||
// auto resize if no size supplied
|
||||
if(!m_text.empty() && !getGeometry().isValid())
|
||||
resizeToText();
|
||||
// auto resize if needed
|
||||
if(!m_text.empty() && !m_rect.isValid()) {
|
||||
Size textSize = m_font->calculateTextRectSize(m_text);
|
||||
if(m_rect.width() <= 0)
|
||||
m_rect.setWidth(textSize.width());
|
||||
if(m_rect.height() <= 0)
|
||||
m_rect.setHeight(textSize.height());
|
||||
}
|
||||
}
|
||||
|
||||
void UILabel::render()
|
||||
{
|
||||
m_font->renderText(m_text, m_rect, m_align, m_fontColor);
|
||||
UIWidget::render();
|
||||
m_font->renderText(m_text, m_rect, m_align, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UILabel::resizeToText()
|
||||
{
|
||||
resize(getFont()->calculateTextRectSize(m_text));
|
||||
resize(m_font->calculateTextRectSize(m_text));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ UILineEdit::UILineEdit() : UIWidget(UITypeLabel)
|
|||
m_textHorizontalMargin = 3;
|
||||
m_focusable = true;
|
||||
blinkCursor();
|
||||
|
||||
m_onAction = [this]() { this->callLuaField("onAction"); };
|
||||
}
|
||||
|
||||
UILineEditPtr UILineEdit::create()
|
||||
|
@ -26,6 +28,11 @@ void UILineEdit::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
UIWidget::loadStyleFromOTML(styleNode);
|
||||
|
||||
setText(styleNode->valueAt("text", getText()));
|
||||
|
||||
if(OTMLNodePtr node = styleNode->get("onAction")) {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
luaSetField(node->tag());
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::render()
|
||||
|
@ -53,7 +60,7 @@ void UILineEdit::render()
|
|||
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
||||
else
|
||||
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
||||
g_graphics.drawFilledRect(cursorRect, m_color);
|
||||
g_graphics.drawFilledRect(cursorRect);
|
||||
} else if(ticks - m_cursorTicks >= 2*delay) {
|
||||
m_cursorTicks = ticks;
|
||||
}
|
||||
|
@ -255,7 +262,7 @@ void UILineEdit::setCursorPos(int pos)
|
|||
}
|
||||
}
|
||||
|
||||
void UILineEdit::enableCursor(bool enable)
|
||||
void UILineEdit::setCursorEnabled(bool enable)
|
||||
{
|
||||
if(enable) {
|
||||
m_cursorPos = 0;
|
||||
|
@ -357,7 +364,10 @@ void UILineEdit::onKeyPress(UIKeyEvent& event)
|
|||
setCursorPos(0);
|
||||
else if(event.keyCode() == KC_END) // move cursor to last character
|
||||
setCursorPos(m_text.length());
|
||||
else if(event.keyChar() != 0) {
|
||||
else if(event.keyCode() == KC_RETURN) {
|
||||
if(m_onAction)
|
||||
m_onAction();
|
||||
} else if(event.keyChar() != 0) {
|
||||
if(event.keyCode() != KC_TAB && event.keyCode() != KC_RETURN)
|
||||
appendCharacter(event.keyChar());
|
||||
else
|
||||
|
|
|
@ -18,8 +18,9 @@ public:
|
|||
void setText(const std::string& text);
|
||||
void setAlign(AlignmentFlag align);
|
||||
void setCursorPos(int pos);
|
||||
void enableCursor(bool enable = true);
|
||||
void setCursorEnabled(bool enable = true);
|
||||
|
||||
void clearText() { setText(""); }
|
||||
void moveCursor(bool right);
|
||||
void appendCharacter(char c);
|
||||
void removeCharacter(bool right);
|
||||
|
@ -45,6 +46,7 @@ private:
|
|||
int m_startRenderPos;
|
||||
int m_cursorTicks;
|
||||
int m_textHorizontalMargin;
|
||||
SimpleCallback m_onAction;
|
||||
|
||||
std::vector<Rect> m_glyphsCoords;
|
||||
std::vector<Rect> m_glyphsTexCoords;
|
||||
|
|
|
@ -97,7 +97,7 @@ bool UIManager::importStyles(const std::string& file)
|
|||
importStyleFromOTML(styleNode);
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: failed to import ui styles from '", file, "':\n", e.what());
|
||||
logError("failed to import ui styles from '", file, "':\n", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
|
||||
auto it = m_styles.find(name);
|
||||
if(it != m_styles.end())
|
||||
logWarning("WARNING: style '", name, "' is being redefined");
|
||||
logWarning("style '", name, "' is being redefined");
|
||||
|
||||
OTMLNodePtr style = getStyle(base)->clone();
|
||||
style->merge(styleNode);
|
||||
|
@ -158,11 +158,9 @@ UIWidgetPtr UIManager::loadUI(const std::string& file)
|
|||
}
|
||||
}
|
||||
|
||||
// schedule onLoad events
|
||||
widget->load();
|
||||
return widget;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: failed to load ui from '", file, "':\n", e.what());
|
||||
logError("failed to load ui from '", file, "':\n", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ UIWidget::UIWidget(UIWidgetType type)
|
|||
m_updateScheduled = false;
|
||||
m_opacity = 255;
|
||||
m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = 0;
|
||||
m_color = Color::white;
|
||||
m_fontColor = Color::white;
|
||||
m_backgroundColor = Color::white;
|
||||
m_foregroundColor = Color::white;
|
||||
|
||||
// generate an unique id, this is need because anchored layouts find widgets by id
|
||||
static unsigned long id = 1;
|
||||
|
@ -33,13 +33,12 @@ UIWidget::~UIWidget()
|
|||
{
|
||||
//logTraceDebug(m_id);
|
||||
if(!m_destroyed)
|
||||
logWarning("WARNING: widget '", m_id, "' was destructed without being explicit destroyed");
|
||||
logWarning("widget '", m_id, "' was destructed without being explicit destroyed");
|
||||
}
|
||||
|
||||
UIWidgetPtr UIWidget::create()
|
||||
{
|
||||
UIWidgetPtr widget(new UIWidget);
|
||||
//widget->setStyle("Widget");
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
@ -48,6 +47,8 @@ void UIWidget::destroy()
|
|||
//TODO: onDestroy event
|
||||
// destroy only once
|
||||
if(!m_destroyed) {
|
||||
releaseLuaFieldsTable();
|
||||
|
||||
// clear additional reference
|
||||
m_lockedWidgets.clear();
|
||||
m_focusedChild.reset();
|
||||
|
@ -68,7 +69,7 @@ void UIWidget::destroy()
|
|||
m_enabled = false;
|
||||
m_visible = false;
|
||||
} else
|
||||
logWarning("WARNING: attempt to destroy widget '", m_id, "' again");
|
||||
logWarning("attempt to destroy widget '", m_id, "' again");
|
||||
}
|
||||
|
||||
void UIWidget::destroyCheck()
|
||||
|
@ -81,21 +82,7 @@ void UIWidget::destroyCheck()
|
|||
|
||||
// check for leaks upon widget destruction
|
||||
if(realUseCount > 0)
|
||||
logWarning("WARNING: destroyed widget with id '",m_id,"', but it still have ",realUseCount," references left");
|
||||
}
|
||||
|
||||
void UIWidget::load()
|
||||
{
|
||||
for(const UIWidgetPtr& child : m_children)
|
||||
child->load();
|
||||
|
||||
// schedule onLoad
|
||||
UIWidgetPtr self = asUIWidget();
|
||||
g_dispatcher.addEvent([self]() {
|
||||
// this widget could be destroyed before the event happens
|
||||
if(!self->isDestroyed())
|
||||
self->callLuaField("onLoad");
|
||||
});
|
||||
logWarning("destroyed widget with id '",m_id,"', but it still have ",realUseCount," references left");
|
||||
}
|
||||
|
||||
void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
||||
|
@ -120,12 +107,12 @@ void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
setFont(g_fonts.getFont(node->value()));
|
||||
}
|
||||
// font color
|
||||
else if(node->tag() == "font-color") {
|
||||
setFontColor(node->value<Color>());
|
||||
else if(node->tag() == "color") {
|
||||
setForegroundColor(node->value<Color>());
|
||||
}
|
||||
// color
|
||||
else if(node->tag() == "color") {
|
||||
setColor(node->value<Color>());
|
||||
else if(node->tag() == "background-color") {
|
||||
setBackgroundColor(node->value<Color>());
|
||||
}
|
||||
// opacity
|
||||
else if(node->tag() == "opacity") {
|
||||
|
@ -197,9 +184,6 @@ void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode)
|
|||
luaSetField("onLoad");
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_font)
|
||||
m_font = g_fonts.getDefaultFont();
|
||||
}
|
||||
|
||||
void UIWidget::render()
|
||||
|
@ -215,9 +199,13 @@ void UIWidget::render()
|
|||
if(child->getOpacity() < oldOpacity)
|
||||
g_graphics.setOpacity(child->getOpacity());
|
||||
|
||||
g_graphics.bindColor(child->getColor());
|
||||
g_graphics.bindColor(child->getBackgroundColor());
|
||||
child->render();
|
||||
|
||||
// debug draw box
|
||||
//g_graphics.bindColor(Color::green);
|
||||
//g_graphics.drawBoundingRect(child->getGeometry());
|
||||
|
||||
g_graphics.setOpacity(oldOpacity);
|
||||
}
|
||||
}
|
||||
|
@ -227,8 +215,10 @@ void UIWidget::updateGeometry()
|
|||
{
|
||||
assert(!m_destroyed);
|
||||
|
||||
if(UILayoutPtr layout = getLayout())
|
||||
if(UILayoutPtr layout = getLayout()) {
|
||||
layout->updateWidget(asUIWidget());
|
||||
layout->updateWidgetChildren(asUIWidget());
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::setParent(const UIWidgetPtr& parent)
|
||||
|
@ -260,7 +250,7 @@ void UIWidget::setStyle(const std::string& styleName)
|
|||
// forces layout recalculation
|
||||
updateGeometry();
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: couldn't change widget '", m_id, "' style: ", e.what());
|
||||
logError("couldn't change widget '", m_id, "' style: ", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,15 +277,6 @@ void UIWidget::setGeometry(const Rect& rect)
|
|||
}
|
||||
}
|
||||
|
||||
void UIWidget::lock()
|
||||
{
|
||||
assert(!m_destroyed);
|
||||
|
||||
UIWidgetPtr parent = getParent();
|
||||
if(parent)
|
||||
parent->lockChild(asUIWidget());
|
||||
}
|
||||
|
||||
bool UIWidget::isEnabled()
|
||||
{
|
||||
if(!m_enabled)
|
||||
|
@ -401,7 +382,7 @@ UIWidgetPtr UIWidget::getChildByPos(const Point& childPos)
|
|||
|
||||
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
|
||||
const UIWidgetPtr& widget = (*it);
|
||||
if(widget->getGeometry().contains(childPos))
|
||||
if(widget->isVisible() && widget->getGeometry().contains(childPos))
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
@ -533,14 +514,40 @@ void UIWidget::addChild(const UIWidgetPtr& childToAdd)
|
|||
m_children.push_back(childToAdd);
|
||||
childToAdd->setParent(asUIWidget());
|
||||
|
||||
// updates child position
|
||||
childToAdd->updateGeometry();
|
||||
// updates geometry
|
||||
updateGeometry();
|
||||
|
||||
// focus it if there is no focused child yet
|
||||
if(!m_focusedChild && childToAdd->isFocusable())
|
||||
focusChild(childToAdd, ActiveFocusReason);
|
||||
}
|
||||
|
||||
void UIWidget::insertChild(const UIWidgetPtr& childToInsert, int index)
|
||||
{
|
||||
assert(!m_destroyed);
|
||||
|
||||
if(!childToInsert)
|
||||
return;
|
||||
|
||||
assert(!hasChild(childToInsert));
|
||||
|
||||
if(index < 0)
|
||||
index = m_children.size() + index -1;
|
||||
|
||||
assert((uint)index <= m_children.size());
|
||||
|
||||
auto it = m_children.begin() + index;
|
||||
m_children.insert(it, childToInsert);
|
||||
childToInsert->setParent(asUIWidget());
|
||||
|
||||
// updates geometry
|
||||
updateGeometry();
|
||||
|
||||
// focus it if there is no focused child yet
|
||||
if(!m_focusedChild && childToInsert->isFocusable())
|
||||
focusChild(childToInsert, ActiveFocusReason);
|
||||
}
|
||||
|
||||
void UIWidget::removeChild(const UIWidgetPtr& childToRemove)
|
||||
{
|
||||
assert(!m_destroyed);
|
||||
|
@ -612,6 +619,9 @@ void UIWidget::lockChild(const UIWidgetPtr& childToLock)
|
|||
}
|
||||
|
||||
m_lockedWidgets.push_front(childToLock);
|
||||
|
||||
// move locked child to top
|
||||
moveChildToTop(childToLock);
|
||||
}
|
||||
|
||||
void UIWidget::unlockChild(const UIWidgetPtr& childToUnlock)
|
||||
|
@ -619,21 +629,21 @@ void UIWidget::unlockChild(const UIWidgetPtr& childToUnlock)
|
|||
assert(hasChild(childToUnlock));
|
||||
|
||||
auto it = std::find(m_lockedWidgets.begin(), m_lockedWidgets.end(), childToUnlock);
|
||||
if(it != m_lockedWidgets.end()) {
|
||||
if(it != m_lockedWidgets.end())
|
||||
m_lockedWidgets.erase(it);
|
||||
UIWidgetPtr newLockedWidget;
|
||||
if(m_lockedWidgets.size() > 0)
|
||||
newLockedWidget = m_lockedWidgets.front();
|
||||
|
||||
for(const UIWidgetPtr& child : m_children) {
|
||||
if(newLockedWidget) {
|
||||
if(child == newLockedWidget)
|
||||
child->setEnabled(true);
|
||||
else
|
||||
child->setEnabled(false);
|
||||
} else
|
||||
UIWidgetPtr newLockedWidget;
|
||||
if(m_lockedWidgets.size() > 0)
|
||||
newLockedWidget = m_lockedWidgets.front();
|
||||
|
||||
for(const UIWidgetPtr& child : m_children) {
|
||||
if(newLockedWidget) {
|
||||
if(child == newLockedWidget)
|
||||
child->setEnabled(true);
|
||||
}
|
||||
else
|
||||
child->setEnabled(false);
|
||||
} else
|
||||
child->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ public:
|
|||
|
||||
static UIWidgetPtr create();
|
||||
|
||||
/// Must be called just after the widget creation
|
||||
virtual void setup() { }
|
||||
|
||||
/// Remove this widget from parent then destroy it and its children
|
||||
virtual void destroy();
|
||||
|
||||
/// Called after the widget is loaded from OTML file, to execute onLoad event
|
||||
virtual void load();
|
||||
|
||||
/// Load style from otml node
|
||||
virtual void loadStyleFromOTML(const OTMLNodePtr& styleNode);
|
||||
|
||||
|
@ -50,8 +50,8 @@ public:
|
|||
void setImage(const ImagePtr& image) { m_image = image; }
|
||||
virtual void setFont(const FontPtr& font) { m_font = font; }
|
||||
void setOpacity(int opacity) { m_opacity = opacity; }
|
||||
void setColor(const Color& color) { m_color = color; }
|
||||
void setFontColor(const Color& color) { m_fontColor = color; }
|
||||
void setBackgroundColor(const Color& color) { m_backgroundColor = color; }
|
||||
void setForegroundColor(const Color& color) { m_foregroundColor = color; }
|
||||
void setMarginLeft(int margin) { m_marginLeft = margin; updateGeometry(); }
|
||||
void setMarginRight(int margin) { m_marginRight = margin; updateGeometry(); }
|
||||
void setMarginTop(int margin) { m_marginTop = margin; updateGeometry(); }
|
||||
|
@ -61,7 +61,6 @@ public:
|
|||
void show() { setVisible(true); }
|
||||
void disable() { setEnabled(false); }
|
||||
void enable() { setEnabled(true); }
|
||||
void lock();
|
||||
|
||||
bool isEnabled();
|
||||
bool isExplicitlyEnabled() const { return m_enabled; }
|
||||
|
@ -88,8 +87,8 @@ public:
|
|||
|
||||
ImagePtr getImage() const { return m_image; }
|
||||
FontPtr getFont() const { return m_font; }
|
||||
Color getFontColor() const { return m_fontColor; }
|
||||
Color getColor() const { return m_color; }
|
||||
Color getForegroundColor() const { return m_foregroundColor; }
|
||||
Color getBackgroundColor() const { return m_backgroundColor; }
|
||||
int getOpacity() const { return m_opacity; }
|
||||
int getMarginLeft() const { return m_marginLeft; }
|
||||
int getMarginRight() const { return m_marginRight; }
|
||||
|
@ -108,6 +107,7 @@ public:
|
|||
UIWidgetPtr backwardsGetWidgetById(const std::string& id);
|
||||
|
||||
void addChild(const UIWidgetPtr& childToAdd);
|
||||
void insertChild(const UIWidgetPtr& childToInsert, int index);
|
||||
void removeChild(const UIWidgetPtr& childToRemove);
|
||||
void focusChild(const UIWidgetPtr& childToFocus, FocusReason reason);
|
||||
void focusNextChild(FocusReason reason);
|
||||
|
@ -169,8 +169,8 @@ protected:
|
|||
ImagePtr m_image;
|
||||
FontPtr m_font;
|
||||
int m_opacity;
|
||||
Color m_color;
|
||||
Color m_fontColor;
|
||||
Color m_backgroundColor;
|
||||
Color m_foregroundColor;
|
||||
int m_marginLeft;
|
||||
int m_marginRight;
|
||||
int m_marginTop;
|
||||
|
|
|
@ -55,7 +55,7 @@ void UIWindow::render()
|
|||
headTextRect.addLeft(-m_headMargin);
|
||||
else if(m_titleAlign & AlignRight)
|
||||
headTextRect.addRight(-m_headMargin);
|
||||
m_font->renderText(m_title, headTextRect, m_titleAlign, m_fontColor);
|
||||
m_font->renderText(m_title, headTextRect, m_titleAlign, m_foregroundColor);
|
||||
}
|
||||
|
||||
// draw window body
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define COLOR_H
|
||||
|
||||
#include "types.h"
|
||||
#include <sstream>
|
||||
#include "tools.h"
|
||||
|
||||
typedef uint32 RGBA;
|
||||
|
||||
|
@ -69,10 +69,19 @@ inline std::istream& operator>>(std::istream& in, Color& color)
|
|||
using namespace std;
|
||||
|
||||
if(in.get() == '#') {
|
||||
uint32 tmp;
|
||||
in >> hex >> tmp;
|
||||
color.setABGR(tmp);
|
||||
in >> dec;
|
||||
std::string tmp;
|
||||
in >> tmp;
|
||||
|
||||
if(tmp.length() == 6 || tmp.length() == 8) {
|
||||
color.setRed((uint8)fw::hex2dec(tmp.substr(0, 2)));
|
||||
color.setGreen((uint8)fw::hex2dec(tmp.substr(2, 2)));
|
||||
color.setBlue((uint8)fw::hex2dec(tmp.substr(4, 2)));
|
||||
if(tmp.length() == 8)
|
||||
color.setAlpha((uint8)fw::hex2dec(tmp.substr(6, 2)));
|
||||
else
|
||||
color.setAlpha(255);
|
||||
} else
|
||||
in.seekg(-tmp.length()-1, ios_base::cur);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#include "logger.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
void Logger::log(LogLevel level, const std::string& message, std::string prettyFunction)
|
||||
{
|
||||
if(!prettyFunction.empty()) {
|
||||
prettyFunction = prettyFunction.substr(0, prettyFunction.find_first_of('('));
|
||||
if(prettyFunction.find_last_of(' ') != std::string::npos)
|
||||
prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1);
|
||||
if(!prettyFunction.empty())
|
||||
std::cout << "[" << prettyFunction << "] ";
|
||||
}
|
||||
|
||||
std::cout << message << std::endl;
|
||||
|
||||
if(level == LogFatal)
|
||||
exit(-1);
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
//TODO: a real logger
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
enum LogLevel {
|
||||
LogDebug = 0,
|
||||
LogInfo,
|
||||
LogWarning,
|
||||
LogError,
|
||||
LogFatal
|
||||
};
|
||||
static void log(LogLevel level, const std::string& message, std::string prettyFunction = "");
|
||||
};
|
||||
|
||||
// specialized logging
|
||||
#define logDebug(...) Logger::log(Logger::LogDebug, fw::mkstr(__VA_ARGS__))
|
||||
#define logInfo(...) Logger::log(Logger::LogInfo, fw::mkstr(__VA_ARGS__))
|
||||
#define logWarning(...) Logger::log(Logger::LogWarning, fw::mkstr(__VA_ARGS__))
|
||||
#define logError(...) Logger::log(Logger::LogError, fw::mkstr(__VA_ARGS__))
|
||||
#define logFatal(...) Logger::log(Logger::LogFatal, fw::mkstr(__VA_ARGS__))
|
||||
|
||||
#define logTrace() Logger::log(Logger::LogDebug, "", __PRETTY_FUNCTION__)
|
||||
#define logTraceDebug(...) Logger::log(Logger::LogDebug, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceInfo(...) Logger::log(Logger::LogInfo, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceWarning(...) log(Logger::LogWarning, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
#define logTraceError(...) Logger::log(Logger::LogError, fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
|
||||
|
||||
#endif
|
|
@ -197,7 +197,7 @@ R unsafe_cast(const T& t, R def = R()) {
|
|||
try {
|
||||
return safe_cast<R,T>(t);
|
||||
} catch(bad_cast& e) {
|
||||
println(e.what());
|
||||
println("CAST ERROR: ", e.what());
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
@ -212,6 +212,21 @@ T fromstring(const std::string& str, T def = T()) {
|
|||
return unsafe_cast<T, std::string>(str, def);
|
||||
}
|
||||
|
||||
inline std::string dec2hex(unsigned int num) {
|
||||
std::string str;
|
||||
std::ostringstream o;
|
||||
o << std::hex << num;
|
||||
str = o.str();
|
||||
return str;
|
||||
}
|
||||
|
||||
inline unsigned int hex2dec(const std::string& str) {
|
||||
unsigned int num;
|
||||
std::istringstream i(str);
|
||||
i >> std::hex >> num;
|
||||
return num;
|
||||
}
|
||||
|
||||
// an empty string to use anywhere needed
|
||||
const static std::string empty_string;
|
||||
|
||||
|
|
|
@ -60,8 +60,15 @@ void Creature::draw(int x, int y)
|
|||
}
|
||||
|
||||
Rect healthRect = Rect(x - 14, y - 11, 27, 4);
|
||||
g_graphics.drawBoundingRect(healthRect, Color::black);
|
||||
g_graphics.drawFilledRect(healthRect.expanded(-1), healthColor);
|
||||
|
||||
g_graphics.bindColor(Color::black);
|
||||
g_graphics.drawBoundingRect(healthRect);
|
||||
|
||||
g_graphics.bindColor(healthColor);
|
||||
g_graphics.drawFilledRect(healthRect.expanded(-1));
|
||||
|
||||
// restore white color
|
||||
g_graphics.bindColor(Color::white);
|
||||
}
|
||||
|
||||
const ThingAttributes& Creature::getAttributes()
|
||||
|
|
|
@ -34,7 +34,7 @@ bool DatManager::load(const std::string& file)
|
|||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("ERROR: failed to load dat from '", file, "': ", e.what());
|
||||
logError("failed to load dat from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,12 @@ void Map::draw(int x, int y)
|
|||
}
|
||||
|
||||
// debug draws
|
||||
g_graphics.drawBoundingRect(Rect(7*32, 5*32, 32, 32), Color::red);
|
||||
g_graphics.bindColor(Color::red);
|
||||
g_graphics.drawBoundingRect(Rect(7*32, 5*32, 32, 32));
|
||||
|
||||
m_framebuffer->unbind();
|
||||
|
||||
g_graphics.bindColor(Color::white);
|
||||
m_framebuffer->draw(Rect(x, y, g_graphics.getScreenSize()));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,16 +10,16 @@ SpriteManager::SpriteManager()
|
|||
m_signature = 0;
|
||||
}
|
||||
|
||||
bool SpriteManager::load(const std::string &filename)
|
||||
bool SpriteManager::load(const std::string& file)
|
||||
{
|
||||
try {
|
||||
g_resources.loadFile(filename, m_fin);
|
||||
g_resources.loadFile(file, m_fin);
|
||||
m_signature = fw::getu32(m_fin);
|
||||
m_spritesCount = fw::getu16(m_fin);
|
||||
m_sprites.resize(m_spritesCount);
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError(e.what());
|
||||
logError("faile to load sprites from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class SpriteManager
|
|||
public:
|
||||
SpriteManager();
|
||||
|
||||
bool load(const std::string& filename);
|
||||
bool load(const std::string& file);
|
||||
void unload();
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
|
|
|
@ -92,7 +92,7 @@ void OTClient::run()
|
|||
m_running = true;
|
||||
|
||||
if(g_ui.getRootWidget()->getChildCount() == 0) {
|
||||
logError("ERROR: there is no root widgets to display, the app will close");
|
||||
logError("there is no root widgets to display, the app will close");
|
||||
m_stopping = true;
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ void OTClient::saveConfigurations()
|
|||
|
||||
// saves user configuration
|
||||
if(!g_configs.save())
|
||||
logError("ERROR: configurations are lost because it couldn't be saved");
|
||||
logError("configurations are lost because it couldn't be saved");
|
||||
}
|
||||
|
||||
void OTClient::onClose()
|
||||
|
@ -270,28 +270,43 @@ void OTClient::onResize(const Size& size)
|
|||
|
||||
void OTClient::onPlatformEvent(const PlatformEvent& event)
|
||||
{
|
||||
g_ui.inputEvent(event);
|
||||
bool fireUi = true;
|
||||
|
||||
if(event.type == EventKeyDown) {
|
||||
if(!event.ctrl) {
|
||||
if(!event.ctrl && !event.alt && !event.shift) {
|
||||
if(event.keycode == KC_UP)
|
||||
g_game.walk(DIRECTION_NORTH);
|
||||
if(event.keycode == KC_RIGHT)
|
||||
else if(event.keycode == KC_RIGHT)
|
||||
g_game.walk(DIRECTION_EAST);
|
||||
if(event.keycode == KC_DOWN)
|
||||
else if(event.keycode == KC_DOWN)
|
||||
g_game.walk(DIRECTION_SOUTH);
|
||||
if(event.keycode == KC_LEFT)
|
||||
else if(event.keycode == KC_LEFT)
|
||||
g_game.walk(DIRECTION_WEST);
|
||||
}
|
||||
else {
|
||||
else if(event.ctrl && !event.alt && !event.shift) {
|
||||
if(event.keycode == KC_UP)
|
||||
g_game.turn(DIRECTION_NORTH);
|
||||
if(event.keycode == KC_RIGHT)
|
||||
else if(event.keycode == KC_RIGHT)
|
||||
g_game.turn(DIRECTION_EAST);
|
||||
if(event.keycode == KC_DOWN)
|
||||
else if(event.keycode == KC_DOWN)
|
||||
g_game.turn(DIRECTION_SOUTH);
|
||||
if(event.keycode == KC_LEFT)
|
||||
else if(event.keycode == KC_LEFT)
|
||||
g_game.turn(DIRECTION_WEST);
|
||||
else if(event.keycode == KC_APOSTROPHE) {
|
||||
// TODO: move these events to lua
|
||||
UIWidgetPtr console = g_ui.getRootWidget()->getChildById("consolePanel");
|
||||
if(!console->isVisible()) {
|
||||
g_ui.getRootWidget()->lockChild(console);
|
||||
console->setVisible(true);
|
||||
} else {
|
||||
g_ui.getRootWidget()->unlockChild(console);
|
||||
console->setVisible(false);
|
||||
}
|
||||
fireUi = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fireUi)
|
||||
g_ui.inputEvent(event);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef OTCLIENT_H
|
||||
#define OTCLIENT_H
|
||||
|
||||
#include <framework/ui/declarations.h>
|
||||
#include <framework/platform/platformlistener.h>
|
||||
|
||||
class OTClient : public PlatformListener
|
||||
|
|
Loading…
Reference in New Issue