(svn r9484) [cpp_gui] -Add: Auto layout/resize ability of widgets.
-Add: Panel widget with DoLayout() method that moves/resizes widgets with respect to their minimal sizes.
-Add: QuerySizes() method added to widget. Widgets are now able to calculate their minimal size.
-Add: SizeT class added (similar to PointT) to make Point/Size/Rectangle math simpler
--- a/src/intro_gui.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/intro_gui.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -161,36 +161,117 @@
NULL
};
+template <> struct WindowT<WC_TEST1> : public BaseWindow {
-
-template <> struct WindowT<WC_TEST1> : public BaseWindow {
+ CCountedPtr<gui::Panel> m_panel1;
+ CCountedPtr<gui::Panel> m_panel2;
+ CCountedPtr<gui::Panel> m_panel3;
+ CCountedPtr<gui::Panel> m_panel4;
gui::WidgetPtr m_label1;
gui::WidgetPtr m_button1;
+ CCountedPtr<gui::TextButton> m_button_add;
+ CCountedPtr<gui::TextButton> m_button_remove;
+ //CCountedPtr<gui::WidgetArrayY> m_ary_1;
+
+ int m_num_dyn_buttons;
WindowT()
- : BaseWindow(WC_TEST1, STR_015B_OPENTTD, COLOUR_BROWN, gui::FF_NONE)
+ : BaseWindow(WC_TEST1, STR_015B_OPENTTD, COLOUR_BROWN, gui::FF_NO_RESIZE_BOX)
+ , m_num_dyn_buttons(5)
{
}
/*virtual*/ void CreateWidgets()
{
/* set common window properties */
- SetTopLeft(Point16(140, 40));
- SetSize(Point16(336, 195));
+ SetRect(Rect16(Point16(140, 40), Size16(336, 195)));
- /* add controls */
- m_label1 = new gui::Label(this, 22, gui::FF_NONE, Rect16(104, 155, 231, 166), STR_0305_QUIT_OPENTTD, STR_0305_QUIT_OPENTTD, COLOUR_BROWN);
- m_label1->SetAnchors(PIN_RIGHT | PIN_BOTTOM);
- AddWidget(m_label1);
+ m_panel1 = new gui::Panel(this, gui::FF_NO_FRAME | gui::FF_IGNORE_PARENT_FRAME, 0, COLOUR_TRANSPARENT);
- /* add controls */
- m_button1 = new gui::TextButton(this, 23, gui::FF_NONE, COLOUR_YELLOW, Rect16(104, 175, 231, 186), STR_0305_QUIT_OPENTTD, STR_0304_QUIT);
- m_button1->SetAnchors(PIN_RIGHT | PIN_BOTTOM);
- AddWidget(m_button1);
+ m_button_add = new gui::TextButton(m_panel1, STR_NULL, gui::FF_MIN_SIZE | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_0305_QUIT_OPENTTD, COLOUR_YELLOW);
+ m_button_add->m_text = "Add";
+ m_button_add->AddReflectHandlerT(&WindowT::ButtonAdd_OnClick);
+ m_panel1->AddWidget(m_button_add, gui::Panel::LEFT);
- /* connect control callbacks */
+ m_button_remove = new gui::TextButton(m_panel1, STR_NULL, gui::FF_MIN_SIZE | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_0305_QUIT_OPENTTD, COLOUR_YELLOW);
+ m_button_remove->m_text = "Del";
+ m_button_remove->AddReflectHandlerT(&WindowT::ButtonRemove_OnClick);
+ m_panel1->AddWidget(m_button_remove, gui::Panel::LEFT);
+
+ m_button1 = new gui::TextButton(m_panel1, STR_0304_QUIT, gui::FF_MIN_SIZE | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_0305_QUIT_OPENTTD, COLOUR_YELLOW);
m_button1->AddReflectHandlerT(&WindowT::Button1_OnClick);
+ m_panel1->AddWidget(m_button1, gui::Panel::CENTER);
+
+ m_panel1->AddWidget(new gui::ResizeBox(m_panel1), gui::Panel::RIGHT);
+ AddWidget(m_panel1, gui::Panel::BOTTOM);
+
+
+ m_panel2 = new gui::Panel(this, gui::FF_NONE, 0, COLOUR_GREY);
+ for (int i = 0; i < m_num_dyn_buttons; i++) {
+ CCountedPtr<gui::TextButton> bu = new gui::TextButton(m_panel2, STR_000F_PASSENGERS + i, gui::FF_MIN_SIZE | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel2->AddWidget(bu, gui::Panel::TOP);
+ }
+ AddWidget(m_panel2, gui::Panel::LEFT);
+
+
+ m_panel3 = new gui::Panel(this, gui::FF_NONE, 0, COLOUR_GREY);
+ for (int i = 0; i < m_num_dyn_buttons; i++) {
+ CCountedPtr<gui::TextButton> bu = new gui::TextButton(m_panel3, STR_000F_PASSENGERS + i, gui::FF_MIN_HEIGHT | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel3->AddWidget(bu, gui::Panel::TOP);
+ }
+ AddWidget(m_panel3, gui::Panel::RIGHT);
+
+
+ m_panel4 = new gui::Panel(this, gui::FF_NONE, 0, COLOUR_GREY);
+ for (int i = 0; i < m_num_dyn_buttons; i++) {
+ CCountedPtr<gui::TextButton> bu = new gui::TextButton(m_panel4, STR_000F_PASSENGERS + i, gui::FF_MIN_SIZE | gui::FF_ALIGN_RIGHT | gui::FF_ALIGN_BOTTOM, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel4->AddWidget(bu, gui::Panel::TOP);
+ }
+ AddWidget(m_panel4, gui::Panel::RIGHT);
+
+
+ ///* add controls */
+ //m_label1 = new gui::Label(this, 22, gui::FF_NONE, Rect16(104, 155, 231, 166), STR_0305_QUIT_OPENTTD, STR_0305_QUIT_OPENTTD, COLOUR_BROWN);
+ //m_label1->SetAnchors(PIN_RIGHT | PIN_BOTTOM);
+ //AddWidget(m_label1);
+
+ ///* add controls */
+ //m_button1 = new gui::TextButton(this, 23, gui::FF_NONE, COLOUR_YELLOW, Rect16(104, 175, 231, 186), STR_0305_QUIT_OPENTTD, STR_0304_QUIT);
+ //m_button1->SetAnchors(PIN_RIGHT | PIN_BOTTOM);
+ //AddWidget(m_button1);
+
+ ///* connect control callbacks */
+ //m_button1->AddReflectHandlerT(&WindowT::Button1_OnClick);
+ }
+
+ void ButtonAdd_OnClick(gui::EvtLeftClick &e)
+ {
+ int i = ++m_num_dyn_buttons % (NUM_CARGO * 3);
+
+ CCountedPtr<gui::TextButton> bu;
+
+ bu = new gui::TextButton(m_panel2, STR_000F_PASSENGERS + i, gui::FF_MIN_SIZE | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel2->AddWidget(bu, gui::Panel::TOP);
+
+ bu = new gui::TextButton(m_panel3, STR_000F_PASSENGERS + i, gui::FF_MIN_HEIGHT | gui::FF_ALIGN_HCENTER | gui::FF_ALIGN_VCENTER, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel3->AddWidget(bu, gui::Panel::TOP);
+
+ bu = new gui::TextButton(m_panel4, STR_000F_PASSENGERS + i, gui::FF_MIN_SIZE | gui::FF_ALIGN_RIGHT | gui::FF_ALIGN_BOTTOM, STR_00D0_NOTHING + i, COLOUR_PARENT);
+ m_panel4->AddWidget(bu, gui::Panel::TOP);
+
+ QuerySizes();
+ CheckMinSize();
+ DoLayout();
+ }
+
+ void ButtonRemove_OnClick(gui::EvtLeftClick &e)
+ {
+ m_panel2->RemoveWidget(0);
+ m_panel3->RemoveWidget(0);
+ m_panel4->RemoveWidget(0);
+ QuerySizes();
+ DoLayout();
}
void Button1_OnClick(gui::EvtLeftClick &e)
@@ -198,6 +279,7 @@
/* move window randomly */
SetTopLeft(TopLeft() + Point16(rand() % 21 - 10, rand() % 21 - 10));
SetDirty();
+ Close();
}
};
--- a/src/misc/rect.hpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/misc/rect.hpp Mon Mar 26 21:00:16 2007 +0000
@@ -41,6 +41,11 @@
return PointRaw::x == other.x && PointRaw::y == other.y;
}
+ bool operator !=(const PointRaw &other) const
+ {
+ return PointRaw::x != other.x || PointRaw::y != other.y;
+ }
+
PointT operator -() const
{
return PointT(-PointRaw::x, -PointRaw::y);
@@ -116,10 +121,85 @@
static PointT val(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
return val;
}
-
};
+template <typename T> struct SizeT : public PointT<T> {
+ typedef PointT<T> Point;
+ typedef PointRawT<T> PointRaw;
+ SizeT(T x_a = 0, T y_a = 0)
+ : Point(x_a, y_a)
+ {}
+
+ template <typename Ta> SizeT(const PointRawT<Ta> &src)
+ : Point(src)
+ {}
+
+ SizeT operator -() const
+ {
+ return SizeT(-PointRaw::x, -PointRaw::y);
+ }
+
+ template <typename T2> SizeT operator +(const PointRawT<T2> &offset) const
+ {
+ SizeT pt(*this);
+ pt.DoMove(offset);
+ return pt;
+ }
+
+ template <typename T2> SizeT operator -(const PointRawT<T2> &offset) const
+ {
+ SizeT pt(*this);
+ pt.DoMove(-offset);
+ return pt;
+ }
+
+ SizeT& operator +=(const PointRaw &offset)
+ {
+ DoMove(offset);
+ return *this;
+ }
+
+ SizeT& operator -=(const PointRaw &offset)
+ {
+ DoMove(-offset);
+ return *this;
+ }
+
+ SizeT operator *(T coef) const
+ {
+ return SizeT(PointRaw::x * coef, PointRaw::y * coef);
+ }
+
+ SizeT operator /(T coef) const
+ {
+ return SizeT(PointRaw::x / coef, PointRaw::y / coef);
+ }
+
+ static const SizeT& min()
+ {
+ static SizeT val(std::numeric_limits<T>::min(), std::numeric_limits<T>::min());
+ return val;
+ }
+
+ static const SizeT& zero()
+ {
+ static SizeT val(0, 0);
+ return val;
+ }
+
+ static const SizeT& one()
+ {
+ static SizeT val(1, 1);
+ return val;
+ }
+
+ static const SizeT& max()
+ {
+ static SizeT val(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
+ return val;
+ }
+};
/** Template based rectangle */
template <typename T> struct RectT
@@ -132,6 +212,10 @@
: top_left(left, top), bottom_right(right, bottom)
{}
+ template <typename Ta> RectT(const PointT<Ta> &tl, const SizeT<Ta> &size)
+ : top_left(tl), bottom_right(tl + size - PointT<T>(1, 1))
+ {}
+
template <typename Ta> RectT(const PointT<Ta> &tl, const PointT<Ta> &br)
: top_left(tl), bottom_right(br)
{}
@@ -180,9 +264,9 @@
return bottom_right;
}
- PointT<T> Size() const
+ SizeT<T> Size() const
{
- return (bottom_right - top_left + PointT<T>(1, 1));
+ return SizeT<T>(bottom_right - top_left + PointT<T>(1, 1));
}
PointT<T> CenterPt() const
@@ -323,6 +407,10 @@
typedef PointT<int32> Point32;
typedef PointT<int> Point;
+typedef SizeT<int16> Size16;
+typedef SizeT<int32> Size32;
+typedef SizeT<int> Size;
+
typedef RectT<int16> Rect16;
typedef RectT<int32> Rect32;
--- a/src/misc_gui.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/misc_gui.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -1283,7 +1283,7 @@
if (parent == NULL) parent = BaseWindow::FindById(WC_MAIN_WINDOW, 0);
w->parent = parent;
/* Center window to the center of parent */
- w->SetTopLeft(parent->TopLeft() + (parent->Size() - w->Size()) / 2);
+ w->SetTopLeft(parent->TopLeft() + (parent->GetSize() - w->GetSize()) / 2);
/* Create a backup of the variadic arguments to strings because it will be
--- a/src/widget/widget.h Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget.h Mon Mar 26 21:00:16 2007 +0000
@@ -5,7 +5,8 @@
#include <list>
-#include <vector>
+//#include <vector>
+#include <map>
#include "../macros.h"
#include "../string.h"
#include "../order.h"
@@ -46,13 +47,37 @@
FF_NO_STICKY_BOX = (1 << 2),
FF_NO_RESIZE_BOX = (1 << 3),
FF_UNMOVABLE = (1 << 4),
- FF_TRANSPARENT = (1 << 5),
- FF_TOGGLE_BUTTON = (1 << 6),
- FF_STICKED = (1 << 7),
- FF_FIXED_WIDTH = (1 << 8),
- FF_FIXED_HEIGHT = (1 << 9),
+ FF_NO_FRAME = (1 << 5),
+ FF_IGNORE_PARENT_FRAME = (1 << 6),
+ FF_TOGGLE_BUTTON = (1 << 7),
+ FF_STICKED = (1 << 8),
+ FF_MAX_WIDTH = (1 << 16),
+ FF_MAX_HEIGHT = (1 << 17),
+ FF_MIN_WIDTH = (1 << 18),
+ FF_MIN_HEIGHT = (1 << 19),
+ FF_BEST_WIDTH = (1 << 20),
+ FF_BEST_HEIGHT = (1 << 21),
+ FF_FIXED_WIDTH = (1 << 22),
+ FF_FIXED_HEIGHT = (1 << 23),
+ FF_SAME_WIDTH = (1 << 24),
+ FF_SAME_HEIGHT = (1 << 25),
+ FF_SAME_DIST_X = (1 << 26),
+ FF_SAME_DIST_Y = (1 << 27),
+
+ FF_ALIGN_LEFT = (1 << 28),
+ FF_ALIGN_RIGHT = (1 << 29),
+ FF_ALIGN_TOP = (1 << 30),
+ FF_ALIGN_BOTTOM = (1 << 31),
+
+ FF_MAX_SIZE = FF_MAX_WIDTH | FF_MAX_HEIGHT,
+ FF_MIN_SIZE = FF_MIN_WIDTH | FF_MIN_HEIGHT,
+ FF_BEST_SIZE = FF_BEST_WIDTH | FF_BEST_HEIGHT,
FF_FIXED_SIZE = FF_FIXED_WIDTH | FF_FIXED_HEIGHT,
+ FF_SAME_SIZE = FF_SAME_WIDTH | FF_SAME_HEIGHT,
+
+ FF_ALIGN_HCENTER = FF_ALIGN_LEFT | FF_ALIGN_RIGHT,
+ FF_ALIGN_VCENTER = FF_ALIGN_TOP | FF_ALIGN_BOTTOM,
};
DECLARE_ENUM_AS_BIT_SET(FeatureFlags);
@@ -69,39 +94,39 @@
typedef AdaptT<EventHandlerDelegatePtr> Handler;
typedef std::list<Handler> Handlers;
+ /*------------------------------------------------------------------------------------------*/
+ ZeroInitBegin m_zero_init_area; ///< following members get cleared by constructor
CompositeWidget *m_container; ///< widget container (can be any panel or window)
WidgetId m_id; ///< Widget id in its container
- Rect16 m_rect; ///< The position offsets relative to the container
- uint16 m_data; ///< The String/Image or special code (list-matrices) of a widget
FeatureFlags m_feature_flags; ///< @see FeatureFlags
- byte m_color; ///< Widget color, see docs/ottd-colourtext-palette.png
+ uint16 m_color; ///< Widget color, see docs/ottd-colourtext-palette.png
+ StringID m_tooltips; ///< Tooltips that are shown when right clicking on a widget
+ Anchors m_anchors; ///< Resize/move when container resizes?
bool m_is_closing : 1; ///< Widget was logically destroyed
bool m_dont_clip : 1; ///< should not be clipped by parent (container)
- StringID m_tooltips; ///< Tooltips that are shown when right clicking on a widget
- Anchors m_anchors; ///< Resize/move when container resizes?
- Point16 m_min_size; ///< Minimum size
- Point16 m_max_size; ///< Maximum size
- Point16 m_size_step; ///< When resizing, what step is the best
+ ZeroInitEnd m_zero_init_end; ///< end of zero initialization area
+ /*------------------------------------------------------------------------------------------*/
+ Rect16 m_rect; ///< The position offsets relative to the container and size
+ Size16 m_ext_border; ///< Border around widget (for layout purposes)
+ Size16 m_min_size; ///< Minimum size
+ Size16 m_max_size; ///< Maximum size
+ Size16 m_size_step; ///< When resizing, what step is the best
+
Handlers m_handlers; ///< dynamically registered event handlers
Widget()
- : m_container(NULL), m_id(0), m_rect(), m_data(0), m_feature_flags(FF_NONE), m_color(0)
- , m_is_closing(false), m_tooltips(0), m_anchors(PIN_NONE)
- , m_max_size(Point16::max()), m_size_step(1, 1)
+ : m_zero_init_area(m_zero_init_end)
{}
- Widget(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips)
- : m_container(container)
- , m_id(id)
- , m_rect(rect)
- , m_data(0)
+ Widget(CompositeWidget *container, FeatureFlags feature_flags, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : m_zero_init_area(m_zero_init_end)
+ , m_container(container)
, m_feature_flags(feature_flags)
, m_color(color)
, m_is_closing(false)
, m_dont_clip(false)
, m_tooltips(tooltips)
, m_anchors(PIN_NONE)
- , m_max_size(Point16::max())
, m_size_step(1, 1)
{}
@@ -113,11 +138,13 @@
int16 Height() const;
const Point16& TopLeft() const;
const Point16& BottomRight() const;
- Point16 Size() const;
+ Size16 GetSize() const;
Point16 CenterPt() const;
const Rect16& GetRect() const;
Rect16 GetLocalRect() const;
+ Point16 GetTopLeftInWindow() const;
+
void SetLeft(int16 val);
void SetTop(int16 val);
void SetRight(int16 val);
@@ -128,9 +155,12 @@
void SetBottomRight(const Point16 &pt);
void SetSize(const Point16 &pt);
void SetRect(const Rect16 &rect);
+ void SetSlotRect(const Rect16 &rect);
+ bool CheckMinSize();
- byte GetColor() const;
- void SetColor(byte val);
+ uint16 GetColor() const;
+ byte GetBkColor() const;
+ void SetColor(uint16 val);
void SetAnchors(Anchors a);
@@ -140,7 +170,8 @@
void CallHandlers(EventBase &e);
void Invalidate() {}; ///< now we redraw gui all the time, so no processing is needed here
- static /*static*/ void FillRect(const Rect16 &rc, int color);
+ static Size16 GetStringSize(StringID id);
+// static void FillRect(const Rect16 &rc, int color);
static void DrawFrameRect(int left, int top, int right, int bottom, int ctab, FrameFlags flags);
void DrawFrameRect(int ctab, FrameFlags flags);
void DrawSprite(SpriteID img, SpriteID pal, const Point16 &local_pos);
@@ -150,6 +181,8 @@
virtual void Close();
+ virtual void QuerySizes() {};
+ virtual void DoLayout() {};
virtual void DrawBackground(EvtPaint &ev);
/**
@@ -203,38 +236,54 @@
};
struct CompositeWidget : public Widget {
- struct Slot {
+ typedef Widget super;
+ struct Slot : SimpleCountedObject {
WidgetPtr m_wi;
- uint8 m_span;
+
+ Slot(Widget *wi)
+ : m_wi(wi)
+ {}
+
+ virtual ~Slot() {};
};
- typedef Widget super;
- typedef std::vector<Slot> Widgets;
+ typedef CCountedPtr<Slot> SlotPtr;
+
+ typedef std::list<AdaptT<SlotPtr> > Widgets;
typedef Widgets::iterator WidgetIterator;
typedef Widgets::reverse_iterator WidgetReverseIterator;
protected:
- Widgets m_widgets;
+ Widgets m_widgets;
+public:
+ Size16 m_int_border; ///< Border inside (for layout purposes)
public:
CompositeWidget()
: Widget()
{}
- CompositeWidget(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips)
- : Widget(container, id, feature_flags, color, rect, tooltips)
+ CompositeWidget(CompositeWidget *container, FeatureFlags feature_flags, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : Widget(container, feature_flags, tooltips, color)
{}
- void AddWidget(Widget *wd);
- WidgetIterator FindWidget(WidgetId id);
- Widget* GetWidget(WidgetId id);
- Widget* RemoveWidget(WidgetId id);
+ Size16 CalcInternalBorder();
+
+ virtual int NumWidgets();
+ virtual bool RemoveWidget(int idx);
+ virtual WidgetIterator AddSlot(Slot *ws);
+ //WidgetIterator FindWidget(WidgetId id);
+ //Widget* GetWidget(WidgetId id);
+ //Widget* RemoveWidget(WidgetId id);
/*virtual*/ Widget* WidgetFromPt(const Point16 &pt);
virtual void CreateNcWidgets() {};
- virtual void CreateWidgets() = 0;
- virtual void Close();
+ virtual void CreateWidgets() {};
+ /*virtual*/ void Close();
+
+ /*virtual*/ void QuerySizes();
+ /*virtual*/ void DoLayout();
/*virtual*/ void OnCreate(EvtCreate &ev);
/*virtual*/ void OnPaint(EvtPaint &ev);
@@ -243,6 +292,34 @@
/*virtual*/ void OnResize(EvtResize &ev);
};
+struct Panel : CompositeWidget {
+ typedef CompositeWidget super;
+
+ enum Placement {
+ NONE,
+ LEFT,
+ TOP,
+ RIGHT,
+ BOTTOM,
+ CENTER,
+ };
+
+ static const FeatureFlags DEFAULT_FEATURES = FF_NONE;
+
+ Panel()
+ : CompositeWidget()
+ {}
+
+ Panel(CompositeWidget *container, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : CompositeWidget(container, feature_flags, tooltips, color)
+ {}
+
+ virtual CompositeWidget::WidgetIterator AddWidget(Widget *wd, Placement pp);
+
+ /*virtual*/ void QuerySizes();
+ /*virtual*/ void DoLayout();
+};
+
}; // namespace gui
#endif /* WIDGET_H */
--- a/src/widget/widget_base.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_base.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -12,6 +12,7 @@
#include "../viewport.h"
#include "../console.h"
#include "../variables.h"
+#include "../strings.h"
#include "../table/sprites.h"
#include "../genworld.h"
#include "../helpers.hpp"
@@ -59,7 +60,7 @@
return m_rect.BottomRight();
}
-Point16 Widget::Size() const
+Size16 Widget::GetSize() const
{
return m_rect.Size();
}
@@ -79,6 +80,13 @@
return Rect16(Point16(0, 0), BottomRight() - TopLeft());
}
+Point16 Widget::GetTopLeftInWindow() const
+{
+ Point16 pt = TopLeft();
+ if (m_container != NULL) pt += m_container->GetTopLeftInWindow();
+ return pt;
+}
+
void Widget::SetLeft(int16 val)
{
m_rect.SetRight(Right() + val - Left());
@@ -134,24 +142,80 @@
void Widget::SetSize(const Point16 &pt)
{
- EvtResize evt_resize(pt - Size());
+ EvtResize evt_resize(pt - GetSize());
m_rect.SetSize(pt);
OnResize(evt_resize);
}
void Widget::SetRect(const Rect16 &rect)
{
- EvtResize evt_resize(rect.Size() - Size());
+ EvtResize evt_resize(rect.Size() - GetSize());
m_rect = rect;
OnResize(evt_resize);
}
-byte Widget::GetColor() const
+void Widget::SetSlotRect(const Rect16 &rc_slot)
+{
+ Rect16 rc = rc_slot;
+ if ((m_feature_flags & FF_MIN_WIDTH) != FF_NONE) {
+ switch (m_feature_flags & (FF_ALIGN_LEFT | FF_ALIGN_RIGHT)) {
+ case FF_ALIGN_HCENTER:
+ rc.DoMove((rc.Width() - m_min_size.x) / 2, 0);
+ break;
+ case FF_ALIGN_RIGHT:
+ rc.DoMove(rc.Width() - m_min_size.x, 0);
+ /* fall down to FF_ALIGN_LEFT */
+ case FF_ALIGN_LEFT:
+ default:
+ break;
+ }
+ rc.SetWidth(m_min_size.x);
+ }
+ if ((m_feature_flags & FF_MIN_HEIGHT) != FF_NONE) {
+ switch (m_feature_flags & (FF_ALIGN_TOP | FF_ALIGN_BOTTOM)) {
+ case FF_ALIGN_VCENTER:
+ rc.DoMove(0, (rc.Height() - m_min_size.y) / 2);
+ break;
+ case FF_ALIGN_BOTTOM:
+ rc.DoMove(0, rc.Height() - m_min_size.y);
+ /* fall down to FF_ALIGN_TOP */
+ case FF_ALIGN_TOP:
+ default:
+ break;
+ }
+ rc.SetHeight(m_min_size.y);
+ }
+ SetRect(rc);
+}
+
+/** Check widget size against minimal size and resize if needed. Return true if resized. */
+bool Widget::CheckMinSize()
+{
+ Size16 size = GetSize();
+ Size16 new_size(max(size.x, m_min_size.x), max(size.y, m_min_size.y));
+ if (new_size != size) {
+ /* The current size if smaller then minimal size. */
+ SetSize(new_size);
+ return true;
+ }
+ return false;
+}
+
+uint16 Widget::GetColor() const
{
return m_color;
}
-void Widget::SetColor(byte val)
+byte Widget::GetBkColor() const
+{
+ if (m_color == COLOUR_PARENT || m_color == COLOUR_TRANSPARENT) {
+ if (m_container == NULL) return 0;
+ return m_container->GetBkColor();
+ }
+ return (byte)m_color;
+}
+
+void Widget::SetColor(uint16 val)
{
m_color = val;
}
@@ -182,6 +246,19 @@
}
}
+/*static*/ Size16 Widget::GetStringSize(StringID id)
+{
+ if (id != 0) {
+ char str[512];
+ GetString(str, id, lastof(str));
+ if (str[0] != 0) {
+ BoundingRect br = GetStringBoundingBox(str);
+ return Size(br.width, br.height);
+ }
+ }
+ return Size16(0, 0);
+}
+
/*static*/ void Widget::DrawFrameRect(int left, int top, int right, int bottom, int ctab, FrameFlags flags)
{
uint dark = _colour_gradient[ctab][3];
@@ -236,7 +313,7 @@
/*virtual*/ Widget* Widget::WidgetFromPt(const Point16 &pt)
{
- if (m_rect.PtInRect(pt)) return this;
+ if (GetLocalRect().PtInRect(pt)) return this;
return NULL;
}
@@ -279,7 +356,8 @@
/*virtual*/ void Widget::DrawBackground(EvtPaint &ev)
{
- DrawFrameRect(m_color, FR_NONE);
+ bool draw_frame = (m_feature_flags & FF_NO_FRAME) == FF_NONE;
+ DrawFrameRect(GetBkColor(), draw_frame ? FR_NONE : FR_BG_ONLY);
}
/*virtual*/ void Widget::DispatchEvent(EventBase &ev)
--- a/src/widget/widget_button.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_button.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -25,9 +25,10 @@
BaseWindow *w = GetWindow();
assert(w != NULL);
+ /* translate the global coordinates to our parent space */
+ Point pt_local = e.m_pt - (w->TopLeft() + GetTopLeftInWindow());
+
if (_left_button_down) {
- /* translate the global coordinates to our window space */
- Point16 pt_local = e.m_pt - w->TopLeft();
/* determine the new button push state (is cursor inside button?) */
bool pushed = (WidgetFromPt(pt_local) != NULL);
/* did the push state change */
@@ -49,7 +50,7 @@
Invalidate();
/* issue click event */
- EvtLeftClick ev(e.m_pt - w->TopLeft());
+ EvtLeftClick ev(pt_local);
ev.m_widget = this;
OnLeftClick(ev);
}
@@ -57,7 +58,7 @@
/*virtual*/ void Button::DrawBackground(EvtPaint &ev)
{
- DrawFrameRect(m_color, m_pushed ? FR_LOWERED : FR_NONE);
+ DrawFrameRect(GetBkColor(), m_pushed ? FR_LOWERED : FR_NONE);
}
/*virtual*/ void Button::OnLeftButtonDown(EvtLeftButtonDown &e)
--- a/src/widget/widget_button_txt.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_button_txt.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -20,12 +20,27 @@
namespace gui {
+StringID TextButton::GetTextId()
+{
+ if (m_text_id != STR_NULL) return m_text_id;
+ StringID temp_id = BindCString(m_text.c_str());
+ return temp_id;
+}
+
+/*virtual*/ void TextButton::QuerySizes()
+{
+ static Point16 border_size(6, 2);
+ StringID text_id = GetTextId();
+ m_min_size = GetStringSize(text_id) + border_size;
+}
+
/*virtual*/ void TextButton::OnPaint(EvtPaint &ev)
{
DrawBackground(ev);
- Point center = Size() / 2;
+ Point center = GetSize() / 2;
if (m_pushed) center += Point(1, 1);
- DrawStringCentered(center.x, center.y - 5, m_text, 0);
+ StringID text_id = GetTextId();
+ DrawStringCentered(center.x, center.y - 5, text_id, 16);
ev.SetHandled();
}
--- a/src/widget/widget_caption.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_caption.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -21,6 +21,159 @@
namespace gui {
+struct CloseBox : public Button {
+ typedef Button super;
+
+ static const int16 DEFAULT_WIDTH = 11;
+ static const int16 DEFAULT_HEIGHT = 14;
+ static FeatureFlags DEFAULT_FEATURES() {return FF_MIN_SIZE | FF_IGNORE_PARENT_FRAME;}
+
+public:
+ CloseBox(CompositeWidget *container)
+ : Button(container, DEFAULT_FEATURES(), STR_018B_CLOSE_WINDOW, COLOUR_PARENT)
+ {
+ m_min_size = m_max_size = Size16(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
+
+ ///*virtual*/ void OnCreate(EvtCreate &ev)
+ //{
+ // // move itself to the left of the parent
+ // super::OnCreate(ev);
+ //}
+
+ /*virtual*/ void OnPaint(EvtPaint &ev)
+ {
+ assert(GetSize() == Point16(DEFAULT_WIDTH, DEFAULT_HEIGHT));
+
+ DrawBackground(ev);
+ DrawString(2, 2, STR_00C5, 0);
+ }
+
+ /*virtual*/ void OnLeftClick(EvtLeftClick &ev)
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+ w->Close();
+ }
+};
+
+struct StickyBox : public ImageButton2 {
+ typedef ImageButton2 super;
+
+ static const int16 DEFAULT_WIDTH = 12;
+ static const int16 DEFAULT_HEIGHT = 14;
+ static const FeatureFlags DEFAULT_FEATURES() {return FF_TOGGLE_BUTTON | FF_MIN_SIZE;}
+
+public:
+ StickyBox(CompositeWidget *container)
+ : ImageButton2(container, SPR_PIN_DOWN, Point(0, 1), SPR_PIN_UP, Point(0, 1), DEFAULT_FEATURES(), STR_STICKY_BUTTON, COLOUR_PARENT)
+ {
+ m_min_size = m_max_size = Size16(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
+
+ /*virtual*/ void OnCreate(EvtCreate &ev)
+ {
+ // move itself to the right side of the parent
+ super::OnCreate(ev);
+ }
+
+ /*virtual*/ void OnLeftClick(EvtLeftClick &ev)
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+
+ /* set or reset FF_STICKED according to our 'pushed' state */
+ w->m_feature_flags = (w->m_feature_flags & ~FF_STICKED) | (m_pushed ? FF_STICKED : FF_NONE);
+ }
+
+};
+
+struct Caption : public Widget {
+ typedef Widget super;
+
+ static const FeatureFlags DEFAULT_FEATURES = FF_MIN_HEIGHT;
+
+protected:
+ Point16 m_moving_offset;
+ CaptureTicket m_ticket_moving;
+
+public:
+ Caption()
+ : Widget()
+ {}
+
+ Caption(CompositeWidget *container, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = STR_018C_WINDOW_TITLE_DRAG_THIS, uint16 color = COLOUR_PARENT)
+ : Widget(container, feature_flags, tooltips, color)
+ {}
+
+ /*virtual*/ void QuerySizes()
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+
+ static Point16 border_size(6, 4);
+ m_min_size = GetStringSize(w->m_caption_text) + border_size;
+ }
+
+ /*virtual*/ void DrawBackground(EvtPaint &ev)
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+
+ byte bk_color = GetBkColor();
+ byte caption_color = w->caption_color;
+ assert(Height() == 14); // XXX - to ensure the same sizes are used everywhere!
+ DrawFrameRect(bk_color, FR_BORDERONLY);
+ DrawFrameRect(1, 1, Width() - 2, Height() - 2, bk_color, (caption_color == 0xFF) ? FR_LOWERED | FR_DARKENED : FR_LOWERED | FR_DARKENED | FR_BORDERONLY);
+ if (caption_color != 0xFF) {
+ GfxFillRect(2, 2, Width() - 3, Height() - 3, _colour_gradient[_player_colors[caption_color]][4]);
+ }
+ }
+
+ /*virtual*/ void OnPaint(EvtPaint &ev)
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+
+ DrawBackground(ev);
+ DrawStringCenteredTruncated(2, Width() - 3, 2, w->m_caption_text, 0x84);
+ ev.SetHandled();
+ }
+
+ /*virtual*/ void OnLeftButtonDown(EvtLeftButtonDown &ev)
+ {
+ BaseWindow *w = GetWindow();
+ assert(w != NULL);
+
+ /* if window is unmovable, do nothing */
+ if ((w->m_feature_flags & FF_UNMOVABLE) != FF_NONE) {
+ super::OnLeftButtonDown(ev);
+ return;
+ }
+
+ m_moving_offset = GetTopLeftInWindow() + ev.m_pt;
+ ev.SetHandled();
+ m_ticket_moving = CaptureEventsT(this, &Caption::OnCaptureMoving);
+ Invalidate();
+ }
+
+ void OnCaptureMoving(EvtMouseOver &e)
+ {
+ if (!_left_button_down) {
+ m_ticket_moving.Release();
+
+ EvtLeftClick ev(Point(0, 0));
+ ev.m_widget = this;
+ CallHandlers(ev);
+ return;
+ }
+ GetWindow()->SetTopLeft(e.m_pt - m_moving_offset);
+ e.SetHandled();
+ Invalidate();
+ }
+};
+
+
/*virtual*/ void CaptionBar::CreateWidgets()
{
BaseWindow *w = GetWindow();
@@ -29,83 +182,16 @@
bool make_close_box = ((m_feature_flags & FF_NO_CLOSE_BOX ) == FF_NONE);
bool make_sticky_box = ((m_feature_flags & FF_NO_STICKY_BOX) == FF_NONE);
- Rect16 rc_caption = GetLocalRect();
-
/* add close box */
- if (make_close_box) {
- CloseBox *close_box = new CloseBox(this);
- AddWidget(close_box);
- rc_caption.SetLeft(rc_caption.Left() + CloseBox::DEFAULT_WIDTH);
- }
-
+ if (make_close_box ) AddWidget(new CloseBox (this), Panel::LEFT);
/* add sticky box */
- if (make_sticky_box) {
- StickyBox *sticky_box = new StickyBox(this);
- AddWidget(sticky_box);
- rc_caption.SetRight(rc_caption.Right() - StickyBox::DEFAULT_WIDTH);
- }
-
+ if (make_sticky_box) AddWidget(new StickyBox(this), Panel::RIGHT);
/* add caption */
- Caption *caption = new Caption(this, -100, FF_NONE, m_color, rc_caption, 0x84, STR_018C_WINDOW_TITLE_DRAG_THIS, w->m_caption_text);
- caption->SetAnchors(PIN_LEFT | PIN_TOP | PIN_RIGHT);
- AddWidget(caption);
-}
-
-/*virtual*/ void Caption::DrawBackground(EvtPaint &ev)
-{
- BaseWindow *w = GetWindow();
- assert(w != NULL);
-
- byte caption_color = w->caption_color;
- assert(Height() == 14); // XXX - to ensure the same sizes are used everywhere!
- DrawFrameRect(m_color, FR_BORDERONLY);
- DrawFrameRect(1, 1, Width() - 2, Height() - 2, m_color, (caption_color == 0xFF) ? FR_LOWERED | FR_DARKENED : FR_LOWERED | FR_DARKENED | FR_BORDERONLY);
- if (caption_color != 0xFF) {
- GfxFillRect(2, 2, Width() - 3, Height() - 3, _colour_gradient[_player_colors[caption_color]][4]);
- }
-}
-
-/*virtual*/ void Caption::OnPaint(EvtPaint &ev)
-{
- BaseWindow *w = GetWindow();
- assert(w != NULL);
-
- DrawBackground(ev);
- DrawStringCenteredTruncated(2, Width() - 3, 2, w->m_caption_text, 0x84);
- ev.SetHandled();
-}
-
-/*virtual*/ void Caption::OnLeftButtonDown(EvtLeftButtonDown &ev)
-{
- BaseWindow *w = GetWindow();
- assert(w != NULL);
-
- /* if window is unmovable, do nothing */
- if ((w->m_feature_flags & FF_UNMOVABLE) != FF_NONE) {
- super::OnLeftButtonDown(ev);
- return;
- }
-
- m_moving_offset = ev.m_pt;
- ev.SetHandled();
- m_ticket_moving = CaptureEventsT(this, &Caption::OnCaptureMoving);
- Invalidate();
-}
-
-void Caption::OnCaptureMoving(EvtMouseOver &e)
-{
- if (!_left_button_down) {
- m_ticket_moving.Release();
-
- EvtLeftClick ev(Point(0, 0));
- ev.m_widget = this;
- CallHandlers(ev);
- return;
- }
- GetWindow()->SetTopLeft(e.m_pt - m_moving_offset);
- e.SetHandled();
- Invalidate();
+ AddWidget(new Caption(this), Panel::CENTER);
}
+
+
+
}; // namespace gui
--- a/src/widget/widget_closebox.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_closebox.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -20,31 +20,6 @@
namespace gui {
-/*virtual*/ void CloseBox::OnCreate(EvtCreate &ev)
-{
- Point16 size(DEFAULT_WIDTH, DEFAULT_HEIGHT);
- // move itself to the left of the parent
- SetTopLeft(m_container->TopLeft());
- SetBottomRight(TopLeft() + size - Point16(1, 1));
-
- SetAnchors(PIN_LEFT | PIN_TOP);
- super::OnCreate(ev);
-}
-
-/*virtual*/ void CloseBox::OnPaint(EvtPaint &ev)
-{
- assert(Size() == Point16(DEFAULT_WIDTH, DEFAULT_HEIGHT));
-
- DrawBackground(ev);
- DrawString(Left() + 2, Top() + 2, STR_00C5, 0);
-}
-
-/*virtual*/ void CloseBox::OnLeftClick(EvtLeftClick &ev)
-{
- BaseWindow *w = GetWindow();
- assert(w != NULL);
- w->Close();
-}
}; // namespace gui
--- a/src/widget/widget_composite.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_composite.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -21,21 +21,44 @@
namespace gui {
-
-void CompositeWidget::AddWidget(Widget *wi)
+Size16 CompositeWidget::CalcInternalBorder()
{
- Widgets::value_type new_slot = {wi, 0};
- m_widgets.push_back(new_slot);
+ /* internal border */
+ Size16 int_border = m_int_border;
+ if ((m_feature_flags & FF_NO_FRAME) == FF_NONE) int_border += Size16(2, 2);
+ return int_border;
}
+/*virtual*/ int CompositeWidget::NumWidgets()
+{
+ return m_widgets.size();
+}
+
+/*virtual*/ CompositeWidget::WidgetIterator CompositeWidget::AddSlot(Slot *ws)
+{
+ WidgetIterator it = m_widgets.insert(m_widgets.end(), AdaptT<SlotPtr>(ws));
+ return it;
+}
+
+/*virtual*/ bool CompositeWidget::RemoveWidget(int idx)
+{
+ /* empty loop to find proper it */
+ WidgetIterator it = m_widgets.begin();
+ while (idx > 0 && it != m_widgets.end()) it++;
+ if (it == m_widgets.end()) return false;
+ m_widgets.erase(it);
+ return true;
+}
+
+#if 0
CompositeWidget::WidgetIterator CompositeWidget::FindWidget(WidgetId id)
{
/* iterate through children */
for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); ++it) {
/* get child */
- Slot &child = (*it);
+ WidgetPtr &wi = (*it);
/* check its id */
- if (child.m_wi == NULL || child.m_wi->m_id != id) continue;
+ if (wi == NULL || wi->m_id != id) continue;
return it;
}
return m_widgets.end();
@@ -44,29 +67,29 @@
Widget* CompositeWidget::GetWidget(WidgetId id)
{
WidgetIterator it = FindWidget(id);
- return it != m_widgets.end() ? (*it).m_wi : NULL;
+ return it != m_widgets.end() ? (WidgetPtr&)(*it) : NULL;
}
Widget* CompositeWidget::RemoveWidget(WidgetId id)
{
WidgetIterator it = FindWidget(id);
if (it == m_widgets.end()) return NULL;
- Widget *wd = (*it).m_wi;
+ WidgetPtr &wd = (*it);
assert(wd->m_container == this);
wd->m_container = NULL;
m_widgets.erase(it);
return wd;
}
+#endif /* 0 */
-/*virtual*/ Widget* CompositeWidget::WidgetFromPt(const Point16 &pt_parent)
+/*virtual*/ Widget* CompositeWidget::WidgetFromPt(const Point16 &pt_local)
{
- Point16 pt_local = pt_parent - TopLeft();
- bool inside_me = m_rect.PtInRect(pt_parent);
+ bool inside_me = (super::WidgetFromPt(pt_local) == this);
for (WidgetReverseIterator rit = m_widgets.rbegin(); rit != m_widgets.rend(); ++rit) {
/* get next child */
- Widget *wd_child = (*rit).m_wi;
+ Widget *wd_child = (*rit).m_t->m_wi;
/* ask the child recursively */
- Widget *wd = wd_child->WidgetFromPt(pt_local);
+ Widget *wd = wd_child->WidgetFromPt(pt_local - wd_child->TopLeft());
if (wd != NULL) {
/* if the widget we found is inside me it is what we are searching for */
if (inside_me) return wd;
@@ -81,13 +104,11 @@
/*virtual*/ void CompositeWidget::Close()
{
/* mark all children as closed in safe way */
- for (WidgetReverseIterator rit_next = m_widgets.rbegin(); rit_next != m_widgets.rend(); ) {
- /* save the iterator (it can be invalidated) and move forward */
- WidgetReverseIterator rit = rit_next++;
+ for (WidgetReverseIterator rit = m_widgets.rbegin(); rit != m_widgets.rend(); ) {
/* get child */
- Widget *wd_child = (*rit).m_wi;
+ Widget *wi = (*(rit++)).m_t->m_wi;
/* tell him we are closing */
- wd_child->Close();
+ wi->Close();
}
/* remove children */
m_widgets.clear();
@@ -95,21 +116,45 @@
super::Close();
}
+/*virtual*/ void CompositeWidget::QuerySizes()
+{
+ /* query all children in a safe way */
+ for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); it++) {
+ /* get child */
+ Widget *wi = (*it).m_t->m_wi;
+ /* do query */
+ wi->QuerySizes();
+ }
+ /* query itself too */
+ super::QuerySizes();
+}
+
+/*virtual*/ void CompositeWidget::DoLayout()
+{
+ /* query all children in a safe way */
+ for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); ) {
+ /* dereference the iterator and move forward */
+ Widget *wi = (*(it++)).m_t->m_wi;
+ /* do layout for child */
+ wi->DoLayout();
+ }
+ /* layout itself too */
+ super::DoLayout();
+}
+
/*virtual*/ void CompositeWidget::OnCreate(EvtCreate &ev)
{
- /* create standard children */
- CreateWidgets();
/* if there are any non-client widgets, create them */
CreateNcWidgets();
+ /* create standard children */
+ CreateWidgets();
/* notify all children that we are creating */
- for (WidgetIterator it_next = m_widgets.begin(); it_next != m_widgets.end(); ) {
- /* save the iterator (it can be invalidated) and move forward */
- WidgetIterator it = it_next++;
+ for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); ) {
/* get child */
- Widget *wd_child = (*it).m_wi;
+ Widget *wi = (*(it++)).m_t->m_wi;
/* tell him we are creating window */
- wd_child->OnCreate(ev);
+ wi->OnCreate(ev);
}
super::OnCreate(ev);
@@ -121,23 +166,23 @@
DrawBackground(ev);
/* paint all children */
- for (WidgetIterator it_next = m_widgets.begin(); it_next != m_widgets.end(); ) {
- /* save the iterator (it can be invalidated) and move forward */
- WidgetIterator it = it_next++;
+ for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); ) {
/* get child */
- Widget *wd_child = (*it).m_wi;
+ Widget *wi = (*(it++)).m_t->m_wi;
/* tell him we are painting */
- ClipDrawContext ctx(wd_child->Left(), wd_child->Top(), wd_child->Width(), wd_child->Height());
- if (!ctx.IsEmpty()) wd_child->OnPaint(ev);
+ ClipDrawContext ctx(wi->Left(), wi->Top(), wi->Width(), wi->Height());
+ if (!ctx.IsEmpty()) wi->OnPaint(ev);
}
}
/*virtual*/ void CompositeWidget::OnLeftButtonDown(EvtLeftButtonDown &ev)
{
//Point16 pt(ev->we.click.pt.x, ev->we.click.pt.y);
- Widget *wd_child = WidgetFromPt(ev.m_pt);
- if (wd_child != NULL && wd_child != this) {
- wd_child->OnLeftButtonDown(ev);
+ Widget *wi = WidgetFromPt(ev.m_pt);
+ if (wi != NULL && wi != this) {
+ EvtLeftButtonDown ev_child(ev.m_pt - wi->GetTopLeftInWindow());
+ wi->OnLeftButtonDown(ev_child);
+ ev.SetHandled(ev_child.IsHandled());
return;
}
super::OnLeftButtonDown(ev);
@@ -146,9 +191,9 @@
/*virtual*/ void CompositeWidget::OnRightButtonDown(EvtRightButtonDown &ev)
{
//Point16 pt(ev->we.click.pt.x, ev->we.click.pt.y);
- Widget *wd_child = WidgetFromPt(ev.m_pt);
- if (wd_child != NULL && wd_child != this) {
- wd_child->OnRightButtonDown(ev);
+ Widget *wi = WidgetFromPt(ev.m_pt);
+ if (wi != NULL && wi != this) {
+ wi->OnRightButtonDown(ev);
return;
}
super::OnRightButtonDown(ev);
@@ -160,13 +205,11 @@
EvtResizeParent evp(ev);
/* notify all children */
- for (WidgetIterator it_next = m_widgets.begin(); it_next != m_widgets.end(); ) {
- /* save the iterator (it can be invalidated) and move forward */
- WidgetIterator it = it_next++;
+ for (WidgetIterator it = m_widgets.begin(); it != m_widgets.end(); ) {
/* get child */
- Widget *wd_child = (*it).m_wi;
+ Widget *wi = (*(it++)).m_t->m_wi;
/* tell him we are resizing */
- wd_child->OnResizeParent(evp);
+ wi->OnResizeParent(evp);
}
super::OnResize(ev);
}
--- a/src/widget/widget_label.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_label.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -22,15 +22,14 @@
/*virtual*/ void Label::DrawBackground(EvtPaint &ev)
{
- if ((m_feature_flags & FF_TRANSPARENT) == FF_NONE) {
- DrawFrameRect(m_color, FR_BG_ONLY);
- }
+ if (GetColor() == COLOUR_TRANSPARENT) return;
+ DrawFrameRect(GetBkColor(), FR_BG_ONLY);
}
/*virtual*/ void Label::OnPaint(EvtPaint &ev)
{
DrawBackground(ev);
- Point center = Size() / 2;
+ Point center = GetSize() / 2;
DrawStringCentered(center.x, center.y - 5, m_text, 0);
ev.SetHandled();
}
--- a/src/widget/widget_panel.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_panel.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -15,7 +15,361 @@
#include "../table/sprites.h"
#include "../genworld.h"
#include "../helpers.hpp"
+#include "../misc/blob.hpp"
#include "window_events.hpp"
#include "widget_types.h"
+namespace gui {
+typedef Panel::Placement Placement;
+struct QuerySizesData;
+struct DoLayoutData;
+
+struct PanelSlot : CompositeWidget::Slot {
+ typedef CompositeWidget::Slot super;
+
+ Placement m_placement; ///< which side of the container is this widget sticked to
+ Rect16 m_rc_slot; ///< Bounding rectangle of the widget slot
+ bool m_edge_left : 1; ///< widget is on left edge
+ bool m_edge_top : 1; ///< widget is on top edge
+ bool m_edge_right : 1; ///< widget is on right edge
+ bool m_edge_bottom : 1; ///< widget is on bottom edge
+
+ PanelSlot(Widget *wi, Placement placement)
+ : super(wi)
+ , m_placement(placement)
+ , m_edge_left(false)
+ , m_edge_top(false)
+ , m_edge_right(false)
+ , m_edge_bottom(false)
+ {}
+
+ /*virtual*/ ~PanelSlot() {};
+
+ virtual void QuerySizes(QuerySizesData &d) = 0;
+ virtual void DoLayout(DoLayoutData &d) = 0;
+};
+
+template <Placement Tplacement>
+struct PanelSlotT : PanelSlot {
+ typedef PanelSlot super;
+
+ PanelSlotT(Widget *wi)
+ : PanelSlot(wi, Tplacement)
+ {}
+
+ /*virtual*/ ~PanelSlotT() {};
+
+ /*virtual*/ void QuerySizes(QuerySizesData &d);
+ /*virtual*/ void DoLayout(DoLayoutData &d);
+};
+
+typedef PanelSlotT<Panel::LEFT > PanelSlotLeft;
+typedef PanelSlotT<Panel::TOP > PanelSlotTop;
+typedef PanelSlotT<Panel::RIGHT > PanelSlotRight;
+typedef PanelSlotT<Panel::BOTTOM> PanelSlotBottom;
+typedef PanelSlotT<Panel::CENTER> PanelSlotCenter;
+
+struct QuerySizesData {
+ Panel *m_panel;
+ Size16 m_int_border;
+ Point16 m_accu_top_left;
+ Point16 m_accu_bottom_right;
+ bool m_edge_left : 1; ///< widget is on left edge
+ bool m_edge_top : 1; ///< widget is on top edge
+ bool m_edge_right : 1; ///< widget is on right edge
+ bool m_edge_bottom : 1; ///< widget is on bottom edge
+
+ QuerySizesData(Panel *p)
+ : m_panel(p)
+ , m_int_border(p->CalcInternalBorder())
+ , m_edge_left(true)
+ , m_edge_top(true)
+ , m_edge_right(true)
+ , m_edge_bottom(true)
+ {}
+};
+
+template <Placement Tplacement>
+/*virtual*/ void PanelSlotT<Tplacement>::QuerySizes(QuerySizesData &d)
+{
+ m_edge_left = d.m_edge_left;
+ m_edge_top = d.m_edge_top;
+ m_edge_right = d.m_edge_right;
+ m_edge_bottom = d.m_edge_bottom;
+
+ switch (Tplacement) {
+ case Panel::LEFT: d.m_edge_left = m_edge_right = false; break;
+ case Panel::TOP: d.m_edge_top = m_edge_bottom = false; break;
+ case Panel::RIGHT: d.m_edge_right = m_edge_left = false; break;
+ case Panel::BOTTOM: d.m_edge_bottom = m_edge_top = false; break;
+ case Panel::CENTER: break;
+ default:
+ NOT_REACHED();
+ break;
+ }
+
+ /* Widget min size. */
+ Size16 wi_min_size = m_wi->m_min_size;
+ if ((m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) == FF_NONE) {
+ /* Widget doesn't ignore the parent's internal border. Increase its min size by this border. */
+ if (m_edge_left ) wi_min_size.x += d.m_int_border.x;
+ if (m_edge_top ) wi_min_size.y += d.m_int_border.y;
+ if (m_edge_right ) wi_min_size.x += d.m_int_border.x;
+ if (m_edge_bottom) wi_min_size.y += d.m_int_border.y;
+ }
+
+ /* New widget begins at d.m_accu_left_top. Calculate its end. */
+ Point16 wi_bottom_right = d.m_accu_top_left + wi_min_size;
+
+ /* Move the begin (top-left) of free area right or down */
+ switch (Tplacement) {
+ case Panel::LEFT:
+ case Panel::RIGHT:
+ /* Free area begin moves right by widget width. */
+ d.m_accu_top_left.x += wi_min_size.x;
+ break;
+
+ case Panel::TOP:
+ case Panel::BOTTOM:
+ /* Free area begin moves down by widget height. */
+ d.m_accu_top_left.y += wi_min_size.y;
+ break;
+
+ case Panel::CENTER:
+ break;
+
+ default:
+ NOT_REACHED();
+ break;
+ }
+
+ /* Move the end of free area if the new widget exceeds the end of free area. */
+ d.m_accu_bottom_right.x = max(wi_bottom_right.x, d.m_accu_bottom_right.x);
+ d.m_accu_bottom_right.y = max(wi_bottom_right.y, d.m_accu_bottom_right.y);
+}
+
+
+struct DoLayoutData {
+ Panel *m_panel;
+ Size16 m_int_border;
+ Rect16 m_rc_remaining;
+
+ DoLayoutData(Panel *p)
+ : m_panel(p)
+ , m_int_border(p->CalcInternalBorder())
+ , m_rc_remaining(p->GetLocalRect())
+ {}
+};
+
+
+template <>
+/*virtual*/ void PanelSlotT<Panel::LEFT>::DoLayout(DoLayoutData &d)
+{
+ /* Does this widget respect or ignore parent's internal border? */
+ bool ignore_int_border = (m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) != FF_NONE;
+
+ /* Find out where the remaining rect will split to widget rect and the new remaining rect */
+ int16 split = m_wi->m_min_size.x;
+ int16 split_border = (m_edge_left && !ignore_int_border) ? d.m_int_border.x : 0;
+
+ /* Cut widget rect from left side of the remaining rect. */
+ Rect16 rc_wi = d.m_rc_remaining;
+ rc_wi.SetWidth(split);
+ rc_wi.DoMove(split_border, 0);
+
+ /* Move the left side of remaining rect to the right. */
+ d.m_rc_remaining.SetLeft(d.m_rc_remaining.Left() + split + split_border);
+
+ /* Shrink widget rect vertically if it respects parent's internal border. */
+ if (!ignore_int_border) {
+ if (m_edge_top ) rc_wi.SetTop (rc_wi.Top () + d.m_int_border.y);
+ if (m_edge_bottom) rc_wi.SetBottom(rc_wi.Bottom() - d.m_int_border.y);
+ }
+
+ /* Update the slot rectangle */
+ m_rc_slot = rc_wi;
+
+ /* Make widget to reposition/resize itself inside new slot. */
+// printf("L:(%3d, %3d)..(%3d, %3d)\n", rc_wi.Left(), rc_wi.Top(), rc_wi.Right(), rc_wi.Bottom());
+ m_wi->SetSlotRect(rc_wi);
+}
+
+template <>
+/*virtual*/ void PanelSlotT<Panel::TOP>::DoLayout(DoLayoutData &d)
+{
+ /* Does this widget respect or ignore parent's internal border? */
+ bool ignore_int_border = (m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) != FF_NONE;
+
+ /* Find out where the remaining rect will split to widget rect and the new remaining rect */
+ int16 split = m_wi->m_min_size.y;
+ int16 split_border = (m_edge_top && !ignore_int_border) ? d.m_int_border.y : 0;
+
+ /* Cut widget rect from top of the remaining rect. */
+ Rect16 rc_wi = d.m_rc_remaining;
+ rc_wi.SetHeight(split);
+ rc_wi.DoMove(0, split_border);
+
+ /* Move the top side of remaining rect down. */
+ d.m_rc_remaining.SetTop(d.m_rc_remaining.Top() + split + split_border);
+
+ /* Shrink widget rect horizontally if it respects parent's internal border. */
+ if (!ignore_int_border) {
+ if (m_edge_left ) rc_wi.SetLeft (rc_wi.Left () + d.m_int_border.x);
+ if (m_edge_right) rc_wi.SetRight(rc_wi.Right() - d.m_int_border.x);
+ }
+
+ /* Update the slot rectangle */
+ m_rc_slot = rc_wi;
+
+ /* Make widget to reposition/resize itself inside new slot. */
+// printf("T:(%3d, %3d)..(%3d, %3d)\n", rc_wi.Left(), rc_wi.Top(), rc_wi.Right(), rc_wi.Bottom());
+ m_wi->SetSlotRect(rc_wi);
+}
+
+template <>
+/*virtual*/ void PanelSlotT<Panel::RIGHT>::DoLayout(DoLayoutData &d)
+{
+ /* Does this widget respect or ignore parent's internal border? */
+ bool ignore_int_border = (m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) != FF_NONE;
+
+ /* Find out where the remaining rect will split to widget rect and the new remaining rect */
+ int16 split = d.m_rc_remaining.Width() - m_wi->m_min_size.x;
+ int16 split_border = (m_edge_right && !ignore_int_border) ? d.m_int_border.x : 0;
+
+ /* Cut widget rect from right side of the remaining rect. */
+ Rect16 rc_wi = d.m_rc_remaining;
+ rc_wi.SetLeft(rc_wi.Left() + split);
+ rc_wi.DoMove(-split_border, 0);
+
+ /* Move the right side of remaining rect to the left. */
+ d.m_rc_remaining.SetWidth(split - split_border);
+
+ /* Shrink widget rect vertically if it respects parent's internal border. */
+ if (!ignore_int_border) {
+ if (m_edge_top ) rc_wi.SetTop (rc_wi.Top () + d.m_int_border.y);
+ if (m_edge_bottom) rc_wi.SetBottom(rc_wi.Bottom() - d.m_int_border.y);
+ }
+
+ /* Update the slot rectangle */
+ m_rc_slot = rc_wi;
+
+ /* Make widget to reposition/resize itself inside new slot. */
+// printf("R:(%3d, %3d)..(%3d, %3d)\n", rc_wi.Left(), rc_wi.Top(), rc_wi.Right(), rc_wi.Bottom());
+ m_wi->SetSlotRect(rc_wi);
+}
+
+template <>
+/*virtual*/ void PanelSlotT<Panel::BOTTOM>::DoLayout(DoLayoutData &d)
+{
+ /* Does this widget respect or ignore parent's internal border? */
+ bool ignore_int_border = (m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) != FF_NONE;
+
+ /* Find out where the remaining rect will split to widget rect and the new remaining rect */
+ int16 split = d.m_rc_remaining.Height() - m_wi->m_min_size.y;
+ int16 split_border = (m_edge_bottom && !ignore_int_border) ? d.m_int_border.y : 0;
+
+ /* Cut widget rect from bottom of the remaining rect. */
+ Rect16 rc_wi = d.m_rc_remaining;
+ rc_wi.SetTop(rc_wi.Top() + split);
+ rc_wi.DoMove(0, -split_border);
+
+ /* Move the bottom side of remaining rect up. */
+ d.m_rc_remaining.SetHeight(split - split_border);
+
+ /* Shrink widget rect horizontally if it respects parent's internal border. */
+ if (!ignore_int_border) {
+ if (m_edge_left ) rc_wi.SetLeft (rc_wi.Left () + d.m_int_border.x);
+ if (m_edge_right) rc_wi.SetRight(rc_wi.Right() - d.m_int_border.x);
+ }
+
+ /* Update the slot rectangle */
+ m_rc_slot = rc_wi;
+
+ /* Make widget to reposition/resize itself inside new slot. */
+// printf("B:(%3d, %3d)..(%3d, %3d)\n", rc_wi.Left(), rc_wi.Top(), rc_wi.Right(), rc_wi.Bottom());
+ m_wi->SetSlotRect(rc_wi);
+}
+
+template <>
+/*virtual*/ void PanelSlotT<Panel::CENTER>::DoLayout(DoLayoutData &d)
+{
+ /* Does this widget respect or ignore parent's internal border? */
+ bool ignore_int_border = (m_wi->m_feature_flags & FF_IGNORE_PARENT_FRAME) != FF_NONE;
+
+ /* Widget rect will be the whole remaining rect. */
+ Rect16 rc_wi = d.m_rc_remaining;
+
+ /* Shrink widget rect horizontally if it respects parent's internal border. */
+ if (!ignore_int_border) {
+ if (m_edge_left ) rc_wi.SetLeft (rc_wi.Left () + d.m_int_border.x);
+ if (m_edge_top ) rc_wi.SetTop (rc_wi.Top () + d.m_int_border.y);
+ if (m_edge_right ) rc_wi.SetRight (rc_wi.Right () - d.m_int_border.x);
+ if (m_edge_bottom) rc_wi.SetBottom(rc_wi.Bottom() - d.m_int_border.y);
+ }
+
+ /* Update the slot rectangle */
+ m_rc_slot = rc_wi;
+
+ /* Make widget to reposition/resize itself inside new slot. */
+// printf("C:(%3d, %3d)..(%3d, %3d)\n", rc_wi.Left(), rc_wi.Top(), rc_wi.Right(), rc_wi.Bottom());
+ m_wi->SetSlotRect(rc_wi);
+}
+
+
+
+
+
+/*virtual*/ CompositeWidget::WidgetIterator Panel::AddWidget(Widget *wi, Placement pp)
+{
+ Slot *slot = NULL;
+ switch (pp)
+ {
+ case LEFT: slot = new PanelSlotLeft(wi); break;
+ case TOP: slot = new PanelSlotTop(wi); break;
+ case RIGHT: slot = new PanelSlotRight(wi); break;
+ case BOTTOM: slot = new PanelSlotBottom(wi); break;
+ case CENTER: slot = new PanelSlotCenter(wi); break;
+ default:
+ NOT_REACHED();
+ }
+
+ WidgetIterator wit = super::AddSlot(slot);
+ return wit;
+}
+
+/*virtual*/ void Panel::QuerySizes()
+{
+ /* query children */
+ super::QuerySizes();
+ if (m_widgets.empty()) return;
+
+ QuerySizesData qsd(this);
+ for (WidgetIterator wit = m_widgets.begin(); wit != m_widgets.end(); wit++) {
+ PanelSlot *slot = (PanelSlot*)(CompositeWidget::Slot*)(*wit).m_t;
+ slot->QuerySizes(qsd);
+ }
+ /* Adjust by unbound sides. */
+ int num_bound_x = (qsd.m_edge_left ? 1 : 0) + (qsd.m_edge_right ? 1 : 0);
+ int num_bound_y = (qsd.m_edge_top ? 1 : 0) + (qsd.m_edge_bottom ? 1 : 0);
+
+ if (num_bound_x + num_bound_y == 3) {
+ if (num_bound_x == 1) qsd.m_accu_bottom_right.x += qsd.m_int_border.x;
+ if (num_bound_y == 1) qsd.m_accu_bottom_right.y += qsd.m_int_border.y;
+ }
+
+ m_min_size = qsd.m_accu_bottom_right;
+}
+
+/*virtual*/ void Panel::DoLayout()
+{
+ DoLayoutData dld(this);
+ for (WidgetIterator wit = m_widgets.begin(); wit != m_widgets.end(); wit++) {
+ PanelSlot *slot = (PanelSlot*)(CompositeWidget::Slot*)(*wit).m_t;
+ slot->DoLayout(dld);
+ }
+ /* do layout children */
+ super::DoLayout();
+}
+
+}; // namespace gui
--- a/src/widget/widget_resizebox.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_resizebox.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -23,7 +23,7 @@
/*virtual*/ void ResizeBox::DrawBackground(EvtPaint &ev)
{
bool sizing = m_ticket_sizing.IsActive();
- DrawFrameRect(m_color, sizing ? FR_LOWERED : FR_NONE);
+ DrawFrameRect(GetBkColor(), sizing ? FR_LOWERED : FR_NONE);
}
void ResizeBox::OnCaptureSizing(EvtMouseOver &e)
@@ -39,8 +39,8 @@
BaseWindow *w = GetWindow();
w->SetDirty();
Point16 size = e.m_pt - w->TopLeft() + m_sizing_offset;
- size.x = max(size.x, DEFAULT_WIDTH);
- size.y = max(size.y, DEFAULT_HEIGHT);
+ size.x = max(size.x, w->m_min_size.x);
+ size.y = max(size.y, w->m_min_size.y);
w->SetSize(size);
e.SetHandled();
w->SetDirty();
@@ -58,7 +58,7 @@
/*virtual*/ void ResizeBox::OnPaint(EvtPaint &ev)
{
- assert(Size() == Point16(DEFAULT_WIDTH, DEFAULT_HEIGHT));
+// assert(GetSize() == Point16(DEFAULT_WIDTH, DEFAULT_HEIGHT));
DrawBackground(ev);
bool sizing = m_ticket_sizing.IsActive();
@@ -69,7 +69,7 @@
/*virtual*/ void ResizeBox::OnLeftButtonDown(EvtLeftButtonDown &ev)
{
BaseWindow *w = GetWindow();
- m_sizing_offset = w->Size() - ev.m_pt;
+ m_sizing_offset = w->GetSize() - (GetTopLeftInWindow() + ev.m_pt);
m_ticket_sizing = CaptureEventsT(this, &ResizeBox::OnCaptureSizing);
Invalidate();
ev.SetHandled();
--- a/src/widget/widget_stickybox.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_stickybox.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -19,25 +19,6 @@
namespace gui {
-/*virtual*/ void StickyBox::OnCreate(EvtCreate &ev)
-{
- // move itself to the right side of the parent
- Rect16 rc = m_container->GetRect();
- rc.SetLeft(rc.Right() - (DEFAULT_WIDTH - 1));
- rc.SetBottom(rc.Top() + (DEFAULT_HEIGHT - 1));
- SetRect(rc);
-
- SetAnchors(PIN_TOP | PIN_RIGHT);
- super::OnCreate(ev);
-}
-
-/*virtual*/ void StickyBox::OnLeftClick(EvtLeftClick &ev)
-{
- BaseWindow *w = GetWindow();
- assert(w != NULL);
-
- w->m_feature_flags = (w->m_feature_flags & ~FF_STICKED) | (m_pushed ? FF_STICKED : FF_NONE);
-}
}; // namespace gui
--- a/src/widget/widget_types.h Mon Mar 26 20:50:18 2007 +0000
+++ b/src/widget/widget_types.h Mon Mar 26 21:00:16 2007 +0000
@@ -11,6 +11,8 @@
struct Label : public Widget {
typedef Widget super;
+ static const FeatureFlags DEFAULT_FEATURES = FF_NONE;
+
protected:
StringID m_text;
@@ -19,12 +21,10 @@
: Widget()
{}
- Label(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, const Rect16 &rect, StringID text, StringID tooltip = 0, int color = COLOUR_NONE)
- : Widget(container, id, feature_flags, (byte)color, rect, tooltip)
+ Label(CompositeWidget *container, StringID text, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : Widget(container, feature_flags, tooltips, color)
, m_text(text)
{
- /* make the label transparent (no background) if color not provided */
- if (color == COLOUR_NONE) m_feature_flags |= FF_TRANSPARENT;
}
/*virtual*/ void DrawBackground(EvtPaint &ev);
@@ -45,8 +45,8 @@
, m_pushed(false)
{}
- Button(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips)
- : Widget(container, id, feature_flags, color, rect, tooltips)
+ Button(CompositeWidget *container, FeatureFlags feature_flags, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : Widget(container, feature_flags, tooltips, color)
, m_pushed(false)
{}
@@ -60,6 +60,8 @@
struct ImageButton : public Button {
typedef Button super;
+ static const FeatureFlags DEFAULT_FEATURES = FF_NONE;
+
protected:
SpriteID m_sprite;
Point16 m_sprite_offset;
@@ -70,8 +72,8 @@
, m_sprite(0)
{}
- ImageButton(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips, SpriteID sprite, Point16 sprite_offset)
- : Button(container, id, feature_flags, color, rect, tooltips)
+ ImageButton(CompositeWidget *container, SpriteID sprite, Point16 sprite_offset, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : Button(container, feature_flags, tooltips, color)
, m_sprite(sprite)
, m_sprite_offset(sprite_offset)
{}
@@ -82,6 +84,8 @@
struct ImageButton2 : public ImageButton {
typedef ImageButton super;
+ static const FeatureFlags DEFAULT_FEATURES = FF_NONE;
+
protected:
SpriteID m_sprite_pushed;
Point16 m_sprite_offset_pushed;
@@ -92,8 +96,8 @@
, m_sprite_pushed(0)
{}
- ImageButton2(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips, SpriteID sprite, Point16 sprite_offset, SpriteID sprite_pushed, Point16 sprite_offset_pushed)
- : ImageButton(container, id, feature_flags, color, rect, tooltips, sprite, sprite_offset)
+ ImageButton2(CompositeWidget *container, SpriteID sprite, Point16 sprite_offset, SpriteID sprite_pushed, Point16 sprite_offset_pushed, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : ImageButton(container, sprite, sprite_offset, feature_flags, tooltips, color)
, m_sprite_pushed(sprite_pushed)
, m_sprite_offset_pushed(sprite_offset_pushed)
{}
@@ -104,97 +108,44 @@
struct TextButton : public Button {
typedef Button super;
+ static const FeatureFlags DEFAULT_FEATURES = FF_NONE;
+
protected:
- StringID m_text;
+ StringID m_text_id;
+public:
+ std::string m_text;
public:
TextButton()
: Button()
{}
- TextButton(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 &rect, StringID tooltips, StringID text)
- : Button(container, id, feature_flags, color, rect, tooltips)
- , m_text(text)
+ TextButton(CompositeWidget *container, StringID text_id, FeatureFlags feature_flags = DEFAULT_FEATURES, StringID tooltips = 0, uint16 color = COLOUR_PARENT)
+ : Button(container, feature_flags, tooltips, color)
+ , m_text_id(text_id)
{}
+ StringID GetTextId();
+ /*virtual*/ void QuerySizes();
+
/*virtual*/ void OnPaint(EvtPaint &ev);
};
-struct CloseBox : public Button {
- typedef Button super;
-
- static const int16 DEFAULT_WIDTH = 11;
- static const int16 DEFAULT_HEIGHT = 14;
-
-public:
- CloseBox()
- : Button()
- {}
-
- CloseBox(CompositeWidget *container)
- : Button(container, -102, FF_NONE, container->m_color, Rect16(), STR_018B_CLOSE_WINDOW)
- {}
-
- /*virtual*/ void OnCreate(EvtCreate &ev);
- /*virtual*/ void OnPaint(EvtPaint &ev);
- /*virtual*/ void OnLeftClick(EvtLeftClick &ev);
-};
-
-struct StickyBox : public ImageButton2 {
- typedef ImageButton2 super;
-
- static const int16 DEFAULT_WIDTH = 12;
- static const int16 DEFAULT_HEIGHT = 14;
-
-public:
- StickyBox()
- : ImageButton2()
- {}
-
- StickyBox(CompositeWidget *container)
- : ImageButton2(container, -103, FF_TOGGLE_BUTTON, container->m_color, Rect16(), STR_STICKY_BUTTON, SPR_PIN_DOWN, Point(0, 1), SPR_PIN_UP, Point(0, 1))
- {}
-
- /*virtual*/ void OnCreate(EvtCreate &ev);
- /*virtual*/ void OnLeftClick(EvtLeftClick &ev);
-};
-
-struct Caption : public Widget {
- typedef Widget super;
-
-protected:
- Point16 m_moving_offset;
- CaptureTicket m_ticket_moving;
-
-public:
- Caption()
- : Widget()
- {}
-
- Caption(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color, const Rect16 rect, byte text_color, StringID tooltips, StringID text)
- : Widget(container, id, feature_flags, color, rect, tooltips)
- {}
-
- /*virtual*/ void DrawBackground(EvtPaint &ev);
-
- /*virtual*/ void OnPaint(EvtPaint &ev);
- /*virtual*/ void OnLeftButtonDown(EvtLeftButtonDown &ev);
- void OnCaptureMoving(EvtMouseOver &e);
-};
-
-struct CaptionBar : public CompositeWidget {
- typedef CompositeWidget super;
+struct CaptionBar : public Panel {
+ typedef Panel super;
static const int16 DEFAULT_HEIGHT = 14;
public:
CaptionBar()
- : CompositeWidget()
+ : super()
{}
- CaptionBar(CompositeWidget *container, WidgetId id, FeatureFlags feature_flags, byte color)
- : CompositeWidget(container, id, feature_flags, color, Rect16(0, 0, container->Right(), DEFAULT_HEIGHT - 1), 0)
- {}
+ CaptionBar(CompositeWidget *container, FeatureFlags feature_flags, uint16 color = COLOUR_PARENT)
+ : super(container, feature_flags, 0, color)
+ {
+ m_feature_flags |= FF_NO_FRAME | FF_IGNORE_PARENT_FRAME;
+ }
/*virtual*/ void CreateWidgets();
};
@@ -205,6 +156,7 @@
static const int16 DEFAULT_WIDTH = 11;
static const int16 DEFAULT_HEIGHT = 11;
+ static FeatureFlags DEFAULT_FEATURES() {return FF_MIN_SIZE | FF_ALIGN_RIGHT | FF_ALIGN_BOTTOM;}
protected:
Point16 m_sizing_offset;
@@ -216,8 +168,10 @@
{}
ResizeBox(CompositeWidget *container)
- : Widget(container, -101, FF_NONE, container->m_color, Rect16(), STR_RESIZE_BUTTON)
- {}
+ : Widget(container, DEFAULT_FEATURES(), STR_RESIZE_BUTTON, COLOUR_PARENT)
+ {
+ m_min_size = m_max_size = Size16(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
/*virtual*/ void DrawBackground(EvtPaint &ev);
void OnCaptureSizing(EvtMouseOver &e);
--- a/src/window.cpp Mon Mar 26 20:50:18 2007 +0000
+++ b/src/window.cpp Mon Mar 26 21:00:16 2007 +0000
@@ -275,14 +275,14 @@
if ((m_feature_flags & gui::FF_NO_CAPTION_BAR) == gui::FF_NONE) {
/* add caption bar */
gui::FeatureFlags feature_flags = m_feature_flags & (gui::FF_NO_CLOSE_BOX | gui::FF_NO_STICKY_BOX);
- gui::CaptionBar *capt_bar = new gui::CaptionBar(this, -100, feature_flags, m_color);
- capt_bar->SetAnchors(PIN_LEFT | PIN_TOP | PIN_RIGHT);
- AddWidget(capt_bar);
+ feature_flags |= gui::FF_SAME_HEIGHT | gui::FF_MAX_WIDTH;
+ gui::CaptionBar *capt_bar = new gui::CaptionBar(this, feature_flags);
+ AddWidget(capt_bar, gui::Panel::TOP);
}
if ((m_feature_flags & gui::FF_NO_RESIZE_BOX) == gui::FF_NONE) {
/* add resize box */
gui::ResizeBox *resize_box = new gui::ResizeBox(this);
- AddWidget(resize_box);
+ AddWidget(resize_box, gui::Panel::CENTER);
}
}
@@ -292,12 +292,27 @@
assert(widget != NULL);
}
+/*virtual*/ void BaseWindow::OnCreate(gui::EvtCreate &ev)
+{
+ super::OnCreate(ev);
+ QuerySizes();
+ DoLayout();
+}
+
/*virtual*/ void BaseWindow::OnPaint(gui::EvtPaint &ev)
{
ClipDrawContext ctx(0, 0, Width(), Height());
if (!ctx.IsEmpty()) super::OnPaint(ev);
}
+/*virtual*/ void BaseWindow::OnResize(gui::EvtResize &ev)
+{
+ if (ev.m_change == Point16(0, 0)) return;
+ super::OnResize(ev);
+ QuerySizes();
+ DoLayout();
+}
+
/**
* Open a new window. If there is no space for a new window, close an open
* window. Try to avoid stickied windows, but if there is no else, close one of
--- a/src/window.h Mon Mar 26 20:50:18 2007 +0000
+++ b/src/window.h Mon Mar 26 21:00:16 2007 +0000
@@ -381,9 +381,9 @@
};
-struct BaseWindow : public gui::CompositeWidget {
+struct BaseWindow : public gui::Panel {
public:
- typedef gui::CompositeWidget super;
+ typedef gui::Panel super;
static WindowList s_list;
@@ -421,7 +421,7 @@
protected:
BaseWindow(WindowClass cls, StringID caption_text = 0, byte color = COLOUR_GREY, gui::FeatureFlags feature_flags = gui::FF_NONE)
- : CompositeWidget(NULL, 0, feature_flags, color, Rect16(), 0)
+ : super(NULL, feature_flags, 0, color)
, m_zero_init_area(m_zero_init_end)
, window_class(cls)
, m_caption_text(caption_text)
@@ -457,7 +457,9 @@
/*virtual*/ void CreateNcWidgets();
/*virtual*/ void CreateWidgets(); ///< @TODO remove it when old gui infrastructure will no longer be used
+ /*virtual*/ void OnCreate(gui::EvtCreate &ev);
/*virtual*/ void OnPaint(gui::EvtPaint &ev);
+ /*virtual*/ void OnResize(gui::EvtResize &ev);
static BaseWindow* Allocate(int x, int y, int width, int height, WindowProc *proc, WindowClass cls, const OldWidget *widget);