mirror of
https://github.com/edubart/otclient.git
synced 2025-10-19 05:53:26 +02:00
text edit (not finished)
This commit is contained in:
@@ -23,27 +23,16 @@
|
||||
|
||||
|
||||
#include "uibutton.h"
|
||||
#include "graphics/fonts.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
void UIButton::render()
|
||||
void UIButton::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
UIElement::render();
|
||||
|
||||
g_fonts.get("tibia-8px-antialised")->renderText(m_text, getRect(), ALIGN_CENTER, Color(0xFFEEEEEE));
|
||||
}
|
||||
|
||||
bool UIButton::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
if(event.type == EV_MOUSE_LDOWN &&
|
||||
getRect().contains(event.mousePos)) {
|
||||
if(event.type == EV_MOUSE_LDOWN && getRect().contains(event.mousePos)) {
|
||||
m_state = UI::ButtonDown;
|
||||
} else if(m_state == UI::ButtonDown && event.type == EV_MOUSE_LUP) {
|
||||
} else if(event.type == EV_MOUSE_LUP && m_state == UI::ButtonDown) {
|
||||
m_state = UI::ButtonUp;
|
||||
if(getRect().contains(event.mousePos)) {
|
||||
if(m_buttonClickCallback)
|
||||
m_buttonClickCallback();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -40,8 +40,7 @@ public:
|
||||
UIElement();
|
||||
}
|
||||
|
||||
virtual void render();
|
||||
bool onInputEvent(const InputEvent& event);
|
||||
void onInputEvent(const InputEvent& event);
|
||||
|
||||
void setText(const std::string& text) { m_text = text; }
|
||||
const std::string& getText() const { return m_text; }
|
||||
|
@@ -24,27 +24,38 @@
|
||||
|
||||
#include "uibuttonskin.h"
|
||||
#include "uibutton.h"
|
||||
#include "graphics/fonts.h"
|
||||
|
||||
void UIButtonSkin::draw(UIElement *element)
|
||||
{
|
||||
UIButton *button = static_cast<UIButton*>(element);
|
||||
|
||||
Rect textRect = button->getRect();
|
||||
|
||||
if(button->getState() == UI::ButtonDown && m_buttonDownImage) {
|
||||
m_buttonDownImage->draw(element->getRect());
|
||||
textRect.translate(m_buttonDownTranslate);
|
||||
} else if(button->getState() == UI::ButtonMouseOver && m_buttonHoverImage) {
|
||||
m_buttonHoverImage->draw(element->getRect());
|
||||
} else {
|
||||
UIElementSkin::draw(element);
|
||||
}
|
||||
|
||||
g_fonts.get("tibia-8px-antialised")->renderText(button->getText(), textRect, ALIGN_CENTER, Color(0xFFEEEEEE));
|
||||
}
|
||||
|
||||
void UIButtonSkin::load(const YAML::Node& node)
|
||||
{
|
||||
UIElementSkin::load(node);
|
||||
|
||||
if(node.FindValue("down state"))
|
||||
if(node.FindValue("down state")) {
|
||||
m_buttonDownImage = loadImage(node["down state"]);
|
||||
|
||||
if(node["down state"].FindValue("translate"))
|
||||
node["down state"]["translate"] >> m_buttonDownTranslate;
|
||||
}
|
||||
|
||||
if(node.FindValue("mouse over state"))
|
||||
m_buttonHoverImage = loadImage(node["mouse over state"]);
|
||||
|
||||
}
|
||||
|
@@ -41,6 +41,7 @@ public:
|
||||
private:
|
||||
ImagePtr m_buttonDownImage;
|
||||
ImagePtr m_buttonHoverImage;
|
||||
Point m_buttonDownTranslate;
|
||||
};
|
||||
|
||||
#endif // UIBUTTONSKIN_H
|
||||
|
@@ -45,8 +45,8 @@ void UIContainer::addChild(UIElementPtr child)
|
||||
|
||||
void UIContainer::removeChild(UIElementPtr child)
|
||||
{
|
||||
if(m_activeElement == child)
|
||||
setActiveElement(UIElementPtr());
|
||||
if(m_focusedElement == child)
|
||||
setFocusedElement(UIElementPtr());
|
||||
m_children.remove(child);
|
||||
if(child->getParent() == shared_from_this())
|
||||
child->setParent(UIContainerPtr());
|
||||
@@ -96,18 +96,45 @@ void UIContainer::render()
|
||||
}
|
||||
}
|
||||
|
||||
bool UIContainer::onInputEvent(const InputEvent& event)
|
||||
void UIContainer::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
bool ret = false;
|
||||
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
||||
const UIElementPtr& child = (*it);
|
||||
if(child->isEnabled() && child->isVisible())
|
||||
ret = child->onInputEvent(event) || ret;
|
||||
bool shouldFire = false;
|
||||
|
||||
// events should pass only when element is visible and enabled
|
||||
if(child->isEnabled() && child->isVisible()) {
|
||||
if(event.type & EV_KEYBOARD) {
|
||||
// keyboard events only go to focused elements
|
||||
if(child == getFocusedElement()) {
|
||||
shouldFire = true;
|
||||
}
|
||||
// mouse events
|
||||
} else if(event.type & EV_MOUSE) {
|
||||
// mouse down and weel events only go to elements that contains the mouse position
|
||||
if(event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) {
|
||||
if(child->getRect().contains(event.mousePos)) {
|
||||
// focus it
|
||||
if(event.type == EV_MOUSE_LDOWN)
|
||||
setFocusedElement(child);
|
||||
shouldFire = true;
|
||||
}
|
||||
}
|
||||
// mouse move and mouse up events go to all elements
|
||||
else {
|
||||
shouldFire = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(shouldFire)
|
||||
child->onInputEvent(event);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UIContainer::setActiveElement(UIElementPtr activeElement)
|
||||
void UIContainer::setFocusedElement(UIElementPtr focusedElement)
|
||||
{
|
||||
|
||||
if(m_focusedElement)
|
||||
m_focusedElement->setFocused(false);
|
||||
m_focusedElement = focusedElement;
|
||||
}
|
||||
|
@@ -41,10 +41,10 @@ public:
|
||||
UIElementPtr recursiveGetChildById(const std::string& id);
|
||||
|
||||
virtual void render();
|
||||
virtual bool onInputEvent(const InputEvent& event);
|
||||
virtual void onInputEvent(const InputEvent& event);
|
||||
|
||||
void setActiveElement(UIElementPtr activeElement);
|
||||
UIElementPtr getActiveElement() const { return m_activeElement; }
|
||||
void setFocusedElement(UIElementPtr focusedElement);
|
||||
UIElementPtr getFocusedElement() const { return m_focusedElement; }
|
||||
|
||||
virtual UI::EElementType getElementType() const { return UI::Container; }
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
protected:
|
||||
std::list<UIElementPtr> m_children;
|
||||
UIElementPtr m_activeElement;
|
||||
UIElementPtr m_focusedElement;
|
||||
};
|
||||
|
||||
#endif // UICONTAINER_H
|
||||
|
@@ -31,7 +31,8 @@ UIElement::UIElement(UI::EElementType type) :
|
||||
m_type(type),
|
||||
m_skin(NULL),
|
||||
m_visible(true),
|
||||
m_enabled(true)
|
||||
m_enabled(true),
|
||||
m_focused(false)
|
||||
{
|
||||
// set default skin
|
||||
if(type > UI::Container)
|
||||
@@ -58,7 +59,6 @@ void UIElement::render()
|
||||
m_skin->draw(this);
|
||||
}
|
||||
|
||||
|
||||
UIElementPtr UIElement::backwardsGetElementById(const std::string& id)
|
||||
{
|
||||
if(getId() == id)
|
||||
|
@@ -47,7 +47,7 @@ public:
|
||||
virtual ~UIElement() { }
|
||||
|
||||
virtual void render();
|
||||
virtual bool onInputEvent(const InputEvent& event) { return false; }
|
||||
virtual void onInputEvent(const InputEvent& event) { }
|
||||
|
||||
UIElementPtr backwardsGetElementById(const std::string& id);
|
||||
|
||||
@@ -64,6 +64,9 @@ public:
|
||||
void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||
bool isEnabled() const { return m_enabled; }
|
||||
|
||||
void setFocused(bool focused) { m_focused = focused; }
|
||||
bool isFocused() const { return m_focused; }
|
||||
|
||||
void setVisible(bool visible) { m_visible = visible; }
|
||||
bool isVisible() const { return m_visible; }
|
||||
|
||||
@@ -79,6 +82,7 @@ private:
|
||||
std::string m_id;
|
||||
bool m_visible;
|
||||
bool m_enabled;
|
||||
bool m_focused;
|
||||
};
|
||||
|
||||
#endif // UIELEMENT_H
|
||||
|
@@ -52,7 +52,10 @@ int AnchorLine::getPos() const
|
||||
|
||||
void UILayout::setSize(const Size& size)
|
||||
{
|
||||
m_rect.setSize(size);
|
||||
if(m_rect.isValid())
|
||||
m_rect.setSize(size);
|
||||
else
|
||||
m_rect = Rect(0, 0, size);
|
||||
|
||||
// rect updated, recalculate itself and anchored elements positions
|
||||
recalculateAnchors();
|
||||
|
@@ -91,6 +91,8 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
||||
|
||||
// now do the real load
|
||||
loadElements(element, doc.begin().second());
|
||||
|
||||
return element;
|
||||
} catch (YAML::Exception& e) {
|
||||
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ namespace UILoader
|
||||
UIElementPtr createElementFromId(const std::string& id);
|
||||
|
||||
/// Loads an UIElement and it's children from a YAML file
|
||||
UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent);
|
||||
UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent = UIContainer::getRootContainer());
|
||||
|
||||
/// Populate container children from a YAML node
|
||||
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
UITextEdit::UITextEdit(Font* font) :
|
||||
UIElement(UI::TextEdit),
|
||||
m_cursorPos(0),
|
||||
m_startRenderPos(0),
|
||||
m_font(font)
|
||||
{
|
||||
if(!font)
|
||||
@@ -36,10 +38,67 @@ UITextEdit::UITextEdit(Font* font) :
|
||||
void UITextEdit::render()
|
||||
{
|
||||
UIElement::render();
|
||||
m_font->renderText(m_text, getRect(), ALIGN_LEFT, Color(0xFFBFBFBF));
|
||||
|
||||
Rect textRect = getRect();
|
||||
textRect.setLeft(textRect.left() + 2);
|
||||
textRect.setRight(textRect.right() - 2);
|
||||
|
||||
// render text
|
||||
m_font->renderText(m_text, textRect, ALIGN_LEFT, Color(0xFFBFBFBF), Point(m_startRenderPos, 0), m_cursorPos);
|
||||
}
|
||||
|
||||
void UITextEdit::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
if(event.type == EV_TEXT_ENTER) {
|
||||
appendCharacter(event.keychar);
|
||||
} else if(event.type == EV_KEY_DOWN) {
|
||||
if(event.keycode == KC_DELETE)
|
||||
removeCharacter(true);
|
||||
else if(event.keycode == KC_BACK)
|
||||
removeCharacter(false);
|
||||
else if(event.keycode == KC_RIGHT) {
|
||||
if(m_cursorPos < m_text.length())
|
||||
m_cursorPos++;
|
||||
} else if(event.keycode == KC_LEFT) {
|
||||
if(m_cursorPos > 0)
|
||||
m_cursorPos--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UITextEdit::clearText()
|
||||
{
|
||||
m_text = "";
|
||||
m_cursorPos = 0;
|
||||
}
|
||||
|
||||
void UITextEdit::setText(const std::string& text)
|
||||
{
|
||||
m_text = text;
|
||||
m_cursorPos = 0;
|
||||
}
|
||||
|
||||
void UITextEdit::appendCharacter(char c)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp = c;
|
||||
m_text.insert(m_cursorPos, tmp);
|
||||
m_cursorPos++;
|
||||
}
|
||||
|
||||
void UITextEdit::removeCharacter(bool right)
|
||||
{
|
||||
if(right && m_cursorPos < m_text.length())
|
||||
m_text.erase(m_text.begin() + m_cursorPos);
|
||||
else if(m_text.length() >= m_cursorPos && m_cursorPos > 0)
|
||||
m_text.erase(m_text.begin() + (--m_cursorPos));
|
||||
}
|
||||
|
||||
void UITextEdit::setCursorPos(uint pos)
|
||||
{
|
||||
if(pos > m_text.length())
|
||||
m_cursorPos = m_text.length();
|
||||
else
|
||||
m_cursorPos = pos;
|
||||
}
|
||||
|
||||
|
@@ -35,12 +35,24 @@ class UITextEdit : public UIElement
|
||||
public:
|
||||
UITextEdit(Font *font = NULL);
|
||||
|
||||
void onInputEvent(const InputEvent& event);
|
||||
|
||||
void render();
|
||||
|
||||
void clearText();
|
||||
void setText(const std::string& text);
|
||||
const std::string& getText() const { return m_text; }
|
||||
|
||||
void setCursorPos(uint pos);
|
||||
uint getCursorPos() { return m_cursorPos; }
|
||||
|
||||
private:
|
||||
void appendCharacter(char c);
|
||||
void removeCharacter(bool right);
|
||||
void recalculate();
|
||||
|
||||
uint m_cursorPos;
|
||||
int m_startRenderPos;
|
||||
std::string m_text;
|
||||
Font *m_font;
|
||||
};
|
||||
|
Reference in New Issue
Block a user