add modulemanager module

This commit is contained in:
Eduardo Bart 2012-02-05 23:44:47 -02:00
parent a55e138002
commit 64c9e4f1d5
25 changed files with 379 additions and 60 deletions

3
TODO
View File

@ -75,6 +75,8 @@ game/graphics window with options
do lua game event calls from Game instead from GameProtocol do lua game event calls from Game instead from GameProtocol
auto walk auto walk
minimap window
login queue login queue
questlog questlog
edit texts edit texts
@ -82,4 +84,3 @@ trade window
shop window shop window
battle window battle window
hotkeys window hotkeys window
minimap window

View File

@ -1,6 +1,17 @@
function dumpWidgets() function dumpWidgets(widget, level)
for i=1,rootWidget:getChildCount() do widget = widget or rootWidget
print(rootWidget:getChildByIndex(i):getId()) level = level or 0
for i=1,widget:getChildCount() do
local child = widget:getChildByIndex(i)
if child:isVisible() then
local name = child:getId()
if name:match('widget%d+') == nil then
print(string.rep(' ', level) .. name)
end
if child:getId() ~= 'terminalBuffer' then
dumpWidgets(child, level+1)
end
end
end end
end end

View File

@ -12,6 +12,7 @@ Module
- client_about - client_about
- client_options - client_options
- client_entergame - client_entergame
- client_modulemanager
- game - game
onLoad: | onLoad: |

View File

@ -0,0 +1,118 @@
ModuleManager = {}
local moduleManagerWindow
local moduleManagerButton
local moduleList
function ModuleManager.init()
moduleManagerWindow = displayUI('modulemanager.otui')
moduleManagerWindow:hide()
moduleList = moduleManagerWindow:getChildById('moduleList')
connect(moduleList, { onChildFocusChange = function(self, focusedChild)
if focusedChild == nil then return end
ModuleManager.updateModuleInfo(focusedChild:getText())
end })
moduleManagerButton = TopMenu.addButton('moduleManagerButton', 'Module manager', 'modulemanager.png', ModuleManager.toggle)
addEvent(ModuleManager.listModules)
end
function ModuleManager.terminate()
moduleManagerWindow:destroy()
moduleManagerWindow = nil
moduleManagerButton:destroy()
moduleManagerButton = nil
moduleList = nil
end
function ModuleManager.hide()
moduleManagerWindow:hide()
end
function ModuleManager.show()
moduleManagerWindow:show()
moduleManagerWindow:focus()
moduleManagerWindow:raise()
end
function ModuleManager.toggle()
if moduleManagerWindow:isVisible() then
ModuleManager.hide()
else
ModuleManager.show()
end
end
function ModuleManager.refreshModules()
g_modules.discoverModules()
ModuleManager.listModules()
end
function ModuleManager.listModules()
moduleList:destroyChildren()
local modules = g_modules.getModules()
for i,module in ipairs(modules) do
local label = createWidget('ModuleListLabel', moduleList)
label:setText(module:getName())
end
moduleList:focusChild(moduleList:getFirstChild(), ActiveFocusReason)
end
function ModuleManager.updateModuleInfo(moduleName)
local name = ''
local description = ''
local autoLoad = ''
local author = ''
local website = ''
local version = ''
local canLoad = false
local canUnload = false
local module = g_modules.getModule(moduleName)
if module then
name = module:getName()
description = module:getDescription()
author = module:getAuthor()
website = module:getWebsite()
version = module:getVersion()
canUnload = module:isLoaded()
canLoad = not canUnload
end
moduleManagerWindow:recursiveGetChildById('moduleName'):setText(name)
moduleManagerWindow:recursiveGetChildById('moduleDescription'):setText(description)
moduleManagerWindow:recursiveGetChildById('moduleDescription'):wrapText()
moduleManagerWindow:recursiveGetChildById('moduleAuthor'):setText(author)
moduleManagerWindow:recursiveGetChildById('moduleWebsite'):setText(website)
moduleManagerWindow:recursiveGetChildById('moduleVersion'):setText(version)
moduleManagerWindow:recursiveGetChildById('moduleLoadButton'):setEnabled(canLoad)
moduleManagerWindow:recursiveGetChildById('moduleUnloadButton'):setEnabled(canUnload)
end
function ModuleManager.loadCurrentModule()
local focusedChild = moduleList:getFocusedChild()
if focusedChild then
local module = g_modules.getModule(focusedChild:getText())
if module then
module:load()
ModuleManager.updateModuleInfo(module:getName())
end
end
end
function ModuleManager.unloadCurrentModule()
local focusedChild = moduleList:getFocusedChild()
if focusedChild then
local module = g_modules.getModule(focusedChild:getText())
if module then
module:unload()
ModuleManager.updateModuleInfo(module:getName())
end
end
end

View File

@ -0,0 +1,11 @@
Module
name: client_modulemanager
description: Manage other modules
author: OTClient team
website: https://github.com/edubart/otclient
onLoad: |
require 'modulemanager'
ModuleManager.init()
onUnload: |
ModuleManager.terminate()

View File

@ -0,0 +1,117 @@
ModuleListLabel < Label
font: verdana-11px-monochrome
background-color: alpha
text-offset: 2 0
focusable: true
$focus:
background-color: #ffffff22
color: #ffffff
ModuleInfoLabel < Label
$!first:
margin-top: 5
margin-bottom: 2
ModuleValueLabel < UILabel
font: verdana-11px-antialised
color: #aaaaaa
text-offset: 3 0
image-source: /core_styles/images/panel_flat.png
image-border: 1
MainWindow
id: moduleManagerWindow
size: 450 450
text: Module Manager
@onEscape: ModuleManager.hide()
TextList
id: moduleList
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
width: 180
padding: 1
focusable: false
margin-bottom: 30
Button
anchors.top: moduleList.bottom
anchors.horizontalCenter: moduleList.horizontalCenter
margin-top: 8
text: Refresh
@onClick: ModuleManager.refreshModules()
Panel
id: moduleInfo
anchors.left: moduleList.right
anchors.top: parent.top
anchors.right: parent.right
margin: 0 5 5 15
layout:
type: verticalBox
fit-children: true
ModuleInfoLabel
text: Module name
ModuleValueLabel
id: moduleName
ModuleInfoLabel
text: Description
ModuleValueLabel
id: moduleDescription
height: 100
ModuleInfoLabel
text: Loaded
ModuleValueLabel
id: moduleLoaded
//ModuleInfoLabel
// text: Autoload
//ModuleValueLabel
// id: moduleAutoload
//ModuleInfoLabel
// text: Autoload antecedence
//ModuleValueLabel
// id: moduleLoadAntecedence
// text: 1000
ModuleInfoLabel
text: Author
ModuleValueLabel
id: moduleAuthor
ModuleInfoLabel
text: Website
ModuleValueLabel
id: moduleWebsite
ModuleInfoLabel
text: Version
ModuleValueLabel
id: moduleVersion
Button
id: moduleLoadButton
anchors.top: moduleInfo.bottom
anchors.left: moduleInfo.left
margin-top: 8
text: Load
enabled: false
@onClick: ModuleManager.loadCurrentModule()
Button
id: moduleUnloadButton
anchors.top: moduleInfo.bottom
anchors.right: moduleInfo.right
margin-left: 10
margin-top: 8
text: Unload
enabled: false
@onClick: ModuleManager.unloadCurrentModule()

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

View File

@ -6,7 +6,7 @@ TopButton < UIButton
image-color: #ffffffff image-color: #ffffffff
icon-color: #ffffffff icon-color: #ffffffff
$hover: $hover !disabled:
image-color: #ffffff99 image-color: #ffffff99
image-clip: 26 0 26 26 image-clip: 26 0 26 26

View File

@ -7,7 +7,7 @@ Button < UIButton
image-source: /core_styles/images/button.png image-source: /core_styles/images/button.png
image-border: 5 image-border: 5
$hover: $hover !disabled:
image-source: /core_styles/images/button_hover.png image-source: /core_styles/images/button_hover.png
$pressed: $pressed:

View File

@ -8,7 +8,7 @@ CheckBox < UICheckBox
image-offset: 0 2 image-offset: 0 2
image-source: /core_styles/images/checkbox.png image-source: /core_styles/images/checkbox.png
$hover: $hover !disabled:
color: #cccccc color: #cccccc
$!checked: $!checked:
@ -48,7 +48,7 @@ ButtonBox < UICheckBox
image-color: white image-color: white
image-border: 5 image-border: 5
$hover: $hover !disabled:
image-source: /core_styles/images/button_hover.png image-source: /core_styles/images/button_hover.png
$checked: $checked:

View File

@ -6,7 +6,7 @@ ComboBoxPopupMenuButton < UIButton
color: #aaaaaa color: #aaaaaa
background-color: alpha background-color: alpha
$hover: $hover !disabled:
color: #ffffff color: #ffffff
background-color: #ffffff44 background-color: #ffffff44
@ -38,7 +38,7 @@ ComboBox < UIComboBox
image-border-right: 17 image-border-right: 17
image-clip: 0 0 89 20 image-clip: 0 0 89 20
$hover: $hover !disabled:
image-clip: 0 20 89 20 image-clip: 0 20 89 20
$on: $on:

View File

@ -7,7 +7,7 @@ PopupMenuButton < UIButton
color: #aaaaaa color: #aaaaaa
background-color: alpha background-color: alpha
$hover: $hover !disabled:
color: #ffffff color: #ffffff
background-color: #ffffff44 background-color: #ffffff44

View File

@ -1,5 +1,5 @@
Module Module
name: game_minewindow name: game_miniwindow
description: Manage game miniwindow description: Manage game miniwindow
author: OTClient team author: OTClient team
website: https://github.com/edubart/otclient website: https://github.com/edubart/otclient

View File

@ -162,8 +162,6 @@ void Application::terminate()
void Application::run() void Application::run()
{ {
g_lua.callGlobalField("g_app", "onRun");
ticks_t lastPollTicks = g_clock.updateTicks(); ticks_t lastPollTicks = g_clock.updateTicks();
m_stopping = false; m_stopping = false;
m_running = true; m_running = true;

View File

@ -221,7 +221,7 @@ namespace Fw
enum FocusReason { enum FocusReason {
MouseFocusReason = 0, MouseFocusReason = 0,
TabFocusReason, KeyboardFocusReason,
ActiveFocusReason, ActiveFocusReason,
OtherFocusReason OtherFocusReason
}; };

View File

@ -25,6 +25,7 @@
#include <framework/global.h> #include <framework/global.h>
class ModuleManager;
class Module; class Module;
class Event; class Event;
class ScheduledEvent; class ScheduledEvent;

View File

@ -31,36 +31,6 @@ Module::Module(const std::string& name)
m_name = name; m_name = name;
} }
void Module::discover(const OTMLNodePtr& moduleNode)
{
const static std::string none = "none";
m_description = moduleNode->valueAt("description", none);
m_author = moduleNode->valueAt("author", none);
m_website = moduleNode->valueAt("website", none);
m_version = moduleNode->valueAt("version", none);
m_autoLoad = moduleNode->valueAt<bool>("autoLoad", false);
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoLoadAntecedence", 100);
if(OTMLNodePtr node = moduleNode->get("dependencies")) {
for(const OTMLNodePtr& tmp : node->children())
m_dependencies.push_back(tmp->value());
}
// set onLoad callback
if(OTMLNodePtr node = moduleNode->get("onLoad")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_loadCallback = g_lua.polymorphicPop<SimpleCallback>();
}
// set onUnload callback
if(OTMLNodePtr node = moduleNode->get("onUnload")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
}
}
bool Module::load() bool Module::load()
{ {
if(m_loaded) if(m_loaded)
@ -95,3 +65,34 @@ void Module::unload()
m_loaded = false; m_loaded = false;
} }
} }
void Module::discover(const OTMLNodePtr& moduleNode)
{
const static std::string none = "none";
m_description = moduleNode->valueAt("description", none);
m_author = moduleNode->valueAt("author", none);
m_website = moduleNode->valueAt("website", none);
m_version = moduleNode->valueAt("version", none);
m_autoLoad = moduleNode->valueAt<bool>("autoLoad", false);
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoLoadAntecedence", 100);
if(OTMLNodePtr node = moduleNode->get("dependencies")) {
for(const OTMLNodePtr& tmp : node->children())
m_dependencies.push_back(tmp->value());
}
// set onLoad callback
if(OTMLNodePtr node = moduleNode->get("onLoad")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_loadCallback = g_lua.polymorphicPop<SimpleCallback>();
}
// set onUnload callback
if(OTMLNodePtr node = moduleNode->get("onUnload")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
}
}

View File

@ -26,12 +26,12 @@
#include "declarations.h" #include "declarations.h"
#include <framework/otml/declarations.h> #include <framework/otml/declarations.h>
#include <framework/luascript/luaobject.h>
class Module class Module : public LuaObject
{ {
public: public:
Module(const std::string& name); Module(const std::string& name);
void discover(const OTMLNodePtr& moduleNode);
bool load(); bool load();
void unload(); void unload();
@ -46,6 +46,10 @@ public:
bool isAutoLoad() { return m_autoLoad; } bool isAutoLoad() { return m_autoLoad; }
int getAutoLoadAntecedence() { return m_autoLoadAntecedence; } int getAutoLoadAntecedence() { return m_autoLoadAntecedence; }
protected:
void discover(const OTMLNodePtr& moduleNode);
friend class ModuleManager;
private: private:
Boolean<false> m_loaded; Boolean<false> m_loaded;
Boolean<false> m_autoLoad; Boolean<false> m_autoLoad;

View File

@ -30,6 +30,9 @@ ModuleManager g_modules;
void ModuleManager::discoverModules() void ModuleManager::discoverModules()
{ {
// remove modules that are not loaded
m_autoLoadModules.clear();
auto moduleDirs = g_resources.listDirectoryFiles("/"); auto moduleDirs = g_resources.listDirectoryFiles("/");
for(const std::string& moduleDir : moduleDirs) { for(const std::string& moduleDir : moduleDirs) {
auto moduleFiles = g_resources.listDirectoryFiles("/" + moduleDir); auto moduleFiles = g_resources.listDirectoryFiles("/" + moduleDir);
@ -85,11 +88,18 @@ ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
OTMLNodePtr moduleNode = doc->at("Module"); OTMLNodePtr moduleNode = doc->at("Module");
std::string name = moduleNode->valueAt("name"); std::string name = moduleNode->valueAt("name");
if(getModule(name)) //if(getModule(name))
Fw::throwException("module '", name, "' already exists, cannot have duplicate module names"); // Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");
bool push = false;
module = getModule(name);
if(!module) {
module = ModulePtr(new Module(name)); module = ModulePtr(new Module(name));
push = true;
}
module->discover(moduleNode); module->discover(moduleNode);
if(push)
m_modules.push_back(module); m_modules.push_back(module);
} catch(Exception& e) { } catch(Exception& e) {
logError("Unable to discover module from file '", moduleFile, "': ", e.what()); logError("Unable to discover module from file '", moduleFile, "': ", e.what());

View File

@ -36,6 +36,7 @@ public:
void unloadModules(); void unloadModules();
ModulePtr getModule(const std::string& moduleName); ModulePtr getModule(const std::string& moduleName);
std::vector<ModulePtr> getModules() { return m_modules; }
private: private:
std::vector<ModulePtr> m_modules; std::vector<ModulePtr> m_modules;

View File

@ -30,6 +30,8 @@
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/platform/platformwindow.h> #include <framework/platform/platformwindow.h>
#include <framework/core/modulemanager.h>
#include <framework/core/module.h>
void Application::registerLuaFunctions() void Application::registerLuaFunctions()
{ {
@ -83,6 +85,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("ungrabKeyboard", &UIWidget::ungrabKeyboard); g_lua.bindClassMemberFunction<UIWidget>("ungrabKeyboard", &UIWidget::ungrabKeyboard);
g_lua.bindClassMemberFunction<UIWidget>("bindRectToParent", &UIWidget::bindRectToParent); g_lua.bindClassMemberFunction<UIWidget>("bindRectToParent", &UIWidget::bindRectToParent);
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy); g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
g_lua.bindClassMemberFunction<UIWidget>("destroyChildren", &UIWidget::destroyChildren);
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId); g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent); g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent);
g_lua.bindClassMemberFunction<UIWidget>("setLayout", &UIWidget::setLayout); g_lua.bindClassMemberFunction<UIWidget>("setLayout", &UIWidget::setLayout);
@ -361,6 +364,19 @@ void Application::registerLuaFunctions()
// Protocol // Protocol
g_lua.registerClass<Protocol>(); g_lua.registerClass<Protocol>();
// Module
g_lua.registerClass<Module>();
g_lua.bindClassMemberFunction<Module>("load", &Module::load);
g_lua.bindClassMemberFunction<Module>("unload", &Module::unload);
g_lua.bindClassMemberFunction<Module>("isLoaded", &Module::isLoaded);
g_lua.bindClassMemberFunction<Module>("getDescription", &Module::getDescription);
g_lua.bindClassMemberFunction<Module>("getName", &Module::getName);
g_lua.bindClassMemberFunction<Module>("getAuthor", &Module::getAuthor);
g_lua.bindClassMemberFunction<Module>("getWebsite", &Module::getWebsite);
g_lua.bindClassMemberFunction<Module>("getVersion", &Module::getVersion);
g_lua.bindClassMemberFunction<Module>("isAutoLoad", &Module::isAutoLoad);
g_lua.bindClassMemberFunction<Module>("getAutoLoadAntecedence", &Module::getAutoLoadAntecedence);
// network manipulation via lua is disabled for a while // network manipulation via lua is disabled for a while
/* /*
// OutputMessage // OutputMessage
@ -451,6 +467,17 @@ void Application::registerLuaFunctions()
g_lua.bindClassStaticFunction("g_ui", "setDebugBoxesDrawing", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1)); g_lua.bindClassStaticFunction("g_ui", "setDebugBoxesDrawing", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1));
g_lua.bindClassStaticFunction("g_ui", "isDrawingDebugBoxes", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1)); g_lua.bindClassStaticFunction("g_ui", "isDrawingDebugBoxes", std::bind(&UIManager::setDebugBoxesDrawing, &g_ui, _1));
// ModuleManager
g_lua.registerStaticClass("g_modules");
g_lua.bindClassStaticFunction("g_modules", "discoverModulesPath", std::bind(&ModuleManager::discoverModulesPath, &g_modules));
g_lua.bindClassStaticFunction("g_modules", "discoverModules", std::bind(&ModuleManager::discoverModules, &g_modules));
g_lua.bindClassStaticFunction("g_modules", "autoLoadModules", std::bind(&ModuleManager::autoLoadModules, &g_modules, _1));
g_lua.bindClassStaticFunction("g_modules", "discoverModule", std::bind(&ModuleManager::discoverModule, &g_modules, _1));
g_lua.bindClassStaticFunction("g_modules", "ensureModuleLoaded", std::bind(&ModuleManager::ensureModuleLoaded, &g_modules, _1));
g_lua.bindClassStaticFunction("g_modules", "unloadModules", std::bind(&ModuleManager::unloadModules, &g_modules));
g_lua.bindClassStaticFunction("g_modules", "getModule", std::bind(&ModuleManager::getModule, &g_modules, _1));
g_lua.bindClassStaticFunction("g_modules", "getModules", std::bind(&ModuleManager::getModules, &g_modules));
// FontManager // FontManager
g_lua.registerStaticClass("g_fonts"); g_lua.registerStaticClass("g_fonts");
g_lua.bindClassStaticFunction("g_fonts", "importFont", std::bind(&FontManager::importFont, &g_fonts, _1)); g_lua.bindClassStaticFunction("g_fonts", "importFont", std::bind(&FontManager::importFont, &g_fonts, _1));

View File

@ -421,7 +421,7 @@ void UILineEdit::onGeometryChange(const Rect& oldRect, const Rect& newRect)
void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason) void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason)
{ {
if(focused && !m_alwaysActive) { if(focused && !m_alwaysActive) {
if(reason == Fw::TabFocusReason) if(reason == Fw::KeyboardFocusReason)
setCursorPos(m_text.length()); setCursorPos(m_text.length());
else else
blinkCursor(); blinkCursor();
@ -452,7 +452,7 @@ bool UILineEdit::onKeyPress(uchar keyCode, int keyboardModifiers, bool wouldFilt
else if(keyCode == Fw::KeyTab) { else if(keyCode == Fw::KeyTab) {
if(!m_alwaysActive) { if(!m_alwaysActive) {
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
parent->focusNextChild(Fw::TabFocusReason); parent->focusNextChild(Fw::KeyboardFocusReason);
} }
} else } else
return false; return false;

View File

@ -219,6 +219,8 @@ void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason)
oldFocused->updateState(Fw::FocusState); oldFocused->updateState(Fw::FocusState);
oldFocused->updateState(Fw::ActiveState); oldFocused->updateState(Fw::ActiveState);
} }
onChildFocusChange(child, oldFocused, reason);
} }
void UIWidget::focusNextChild(Fw::FocusReason reason) void UIWidget::focusNextChild(Fw::FocusReason reason)
@ -485,7 +487,6 @@ void UIWidget::lower()
void UIWidget::raise() void UIWidget::raise()
{ {
focus();
UIWidgetPtr parent = getParent(); UIWidgetPtr parent = getParent();
if(parent) if(parent)
parent->raiseChild(asUIWidget()); parent->raiseChild(asUIWidget());
@ -546,9 +547,7 @@ void UIWidget::destroy()
parent->removeChild(asUIWidget()); parent->removeChild(asUIWidget());
} }
// destroy children destroyChildren();
while(!m_children.empty())
getFirstChild()->destroy();
callLuaField("onDestroy"); callLuaField("onDestroy");
@ -568,6 +567,12 @@ void UIWidget::destroy()
m_destroyed = true; m_destroyed = true;
} }
void UIWidget::destroyChildren()
{
while(!m_children.empty())
getFirstChild()->destroy();
}
void UIWidget::setId(const std::string& id) void UIWidget::setId(const std::string& id)
{ {
m_id = id; m_id = id;
@ -1108,6 +1113,11 @@ void UIWidget::onFocusChange(bool focused, Fw::FocusReason reason)
callLuaField("onFocusChange", focused, reason); callLuaField("onFocusChange", focused, reason);
} }
void UIWidget::onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason)
{
callLuaField("onChildFocusChange", focusedChild, unfocusedChild, reason);
}
void UIWidget::onHoverChange(bool hovered) void UIWidget::onHoverChange(bool hovered)
{ {
callLuaField("onHoverChange", hovered); callLuaField("onHoverChange", hovered);
@ -1168,7 +1178,7 @@ bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button)
bool UIWidget::onMouseRelease(const Point& mousePos, Fw::MouseButton button) bool UIWidget::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
{ {
if(isPressed() && getRect().contains(mousePos)) if(isPressed() && getRect().contains(mousePos))
callLuaField("onClick"); onClick(mousePos);
UIWidgetPtr draggedWidget = g_ui.getDraggingWidget(); UIWidgetPtr draggedWidget = g_ui.getDraggingWidget();
if(draggedWidget && button == Fw::MouseLeftButton && (containsPoint(mousePos) || asUIWidget() == g_ui.getRootWidget())) { if(draggedWidget && button == Fw::MouseLeftButton && (containsPoint(mousePos) || asUIWidget() == g_ui.getRootWidget())) {
@ -1196,6 +1206,11 @@ bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direc
return callLuaField<bool>("onMouseWheel", mousePos, direction); return callLuaField<bool>("onMouseWheel", mousePos, direction);
} }
bool UIWidget::onClick(const Point& mousePos)
{
return callLuaField<bool>("onClick", mousePos);
}
bool UIWidget::onDoubleClick(const Point& mousePos) bool UIWidget::onDoubleClick(const Point& mousePos)
{ {
return callLuaField<bool>("onDoubleClick", mousePos); return callLuaField<bool>("onDoubleClick", mousePos);

View File

@ -105,6 +105,7 @@ public:
void ungrabKeyboard(); void ungrabKeyboard();
void bindRectToParent(); void bindRectToParent();
void destroy(); void destroy();
void destroyChildren();
void setId(const std::string& id); void setId(const std::string& id);
void setParent(const UIWidgetPtr& parent); void setParent(const UIWidgetPtr& parent);
@ -169,6 +170,7 @@ protected:
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
virtual void onFocusChange(bool focused, Fw::FocusReason reason); virtual void onFocusChange(bool focused, Fw::FocusReason reason);
virtual void onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason);
virtual void onHoverChange(bool hovered); virtual void onHoverChange(bool hovered);
virtual void onDragEnter(const Point& mousePos); virtual void onDragEnter(const Point& mousePos);
virtual void onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos); virtual void onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos);
@ -181,6 +183,7 @@ protected:
virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button); virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button);
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction); virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction);
virtual bool onClick(const Point& mousePos);
virtual bool onDoubleClick(const Point& mousePos); virtual bool onDoubleClick(const Point& mousePos);
bool propagateOnKeyText(const std::string& keyText); bool propagateOnKeyText(const std::string& keyText);