lua console and some changes

This commit is contained in:
Eduardo Bart
2011-08-20 17:30:41 -03:00
parent 033f14780d
commit 38529ea837
70 changed files with 672 additions and 305 deletions

View File

@@ -9,7 +9,8 @@ enum UIWidgetType {
UITypeButton,
UITypeLineEdit,
UITypeWindow,
UITypeList
UITypeList,
UITypeConsole
};
enum FocusReason {

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

View File

@@ -8,7 +8,7 @@ class UIButton : public UIWidget
struct ButtonStateStyle {
ImagePtr image;
Point textTranslate;
Color fontColor;
Color foregroundColor;
Color color;
};

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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