raven/src/Widget.hpp

142 lines
4.1 KiB
C++

#pragma once
#include <memory>
#include <utility>
#include <vector>
#include <string>
#include <functional>
#include "Box.hpp"
#include "Events.hpp"
#include "Forward.hpp"
#include "RGB.hpp"
#include "GenericStyle.hpp"
#include "Styles.hpp"
namespace Raven {
enum class WidgetType {
Widget = 0,
Button,
Label,
Control
};
enum class ControlWidgetType {
Widget = 0,
NewRow
};
class Widget {
public:
Widget() {}
Widget(WidgetType type)
: m_type(type) {}
Widget(ControlWidgetType type)
: m_control_type(type) {
m_type = WidgetType::Control;
m_control_type = type;
m_accepts_events = false;
}
virtual ~Widget() {};
std::function<void(Event&)> on_event { [](Event&){} };
void fit_text(std::string &text);
void move_to(double x, double y);
bool resize(double width, double height);
bool resize(Point &point) { return resize(point.x(), point.y()); }
std::vector<std::shared_ptr<Widget>> &children() { return m_children; }
bool add_child(std::shared_ptr<Widget> child);
void remove_child(std::shared_ptr<Widget> child);
Box &rect() { return m_rect; }
void set_rect(Box rect) { m_rect = rect; reflow(); }
void set_rect(Box rect, bool is_pure) { m_rect = rect; if (!is_pure) { reflow(); } }
Point window_relative();
WidgetType type() { return m_type; }
ControlWidgetType control_type() { return m_control_type; }
Widget *parent() { return m_parent; }
void set_parent(Widget *parent) { m_parent = parent; }
Window *window() { return m_window; }
void set_window(Window *window);
GenericStyle *style() { return m_style; }
void set_style(GenericStyle *style) { m_style = style; reflow(); }
bool did_init() { return m_did_init; }
bool is_focused() { return m_is_focused; }
bool is_active() { return m_is_active; }
bool consumes_hits() { return m_consumes_hits; }
void set_consumes_hits(bool consumes_hits) { m_consumes_hits = consumes_hits; }
bool accepts_events() { return m_accepts_events; }
void set_accepts_events(bool accepts_events) { m_accepts_events = accepts_events; }
bool absolute() { return m_absolute; }
void set_absolute(bool absolute) { m_absolute = absolute; }
void set_layout(std::shared_ptr<Layout> layout);
std::shared_ptr<Layout> layout() { return m_layout; }
void dispatch_event(Event &event);
template<typename T, class... Args>
std::shared_ptr<T> set_layout(Args&&... args) {
std::shared_ptr<T> layout = std::make_shared<T>(std::forward<Args>(args)...);
set_layout(layout);
return layout;
}
template<typename T, class... Args>
std::shared_ptr<T> add(Args&&... args) {
std::shared_ptr<T> child = std::make_shared<T>(std::forward<Args>(args)...);
add_child(child);
return child;
}
protected:
WidgetType m_type { WidgetType::Widget };
virtual void on_init() { set_did_init(true); }
virtual void on_mouse_button(MouseButtonEvent &event) {}
virtual void on_mouse_move(MouseMoveEvent &event) {}
virtual void on_focus_update(FocusUpdateEvent &event) {}
virtual void on_activation_update(ActivationUpdateEvent &event) {}
virtual void on_paint() {}
void set_did_init(bool did_init) { m_did_init = did_init; }
void repaint();
void reflow();
private:
void do_layout();
void handle_repaint_rect(RepaintRectEvent &event);
void handle_relayout_subtree();
void handle_mouse_move_event(MouseMoveEvent &event);
void handle_mouse_button_event(MouseButtonEvent &event);
Box m_rect { 0, 0, 0, 0 };
std::vector<std::shared_ptr<Widget>> m_children;
Widget *m_parent { nullptr };
Window *m_window { nullptr };
GenericStyle *m_style { &default_widget_style };
std::shared_ptr<Layout> m_layout { nullptr };
bool m_did_init { false };
bool m_is_focused { false };
bool m_is_active { false };
bool m_consumes_hits { false };
bool m_accepts_events { true };
bool m_absolute { false };
ControlWidgetType m_control_type { ControlWidgetType::Widget };
};
}