]> Dogcows Code - chaz/openbox/commitdiff
Brand spankin new widgets for otk (Label and Button).
authorDana Jansens <danakj@orodu.net>
Sat, 8 Feb 2003 07:33:48 +0000 (07:33 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 8 Feb 2003 07:33:48 +0000 (07:33 +0000)
Add a new Size class.
Rect, Point, and Size are immutable classes.
Size uses *UNSIGNED* ints. This is causing me headaches * a bajillion right now, so we'll see about that.

28 files changed:
otk/Makefile.am
otk/application.cc
otk/application.hh
otk/appwidget.cc
otk/appwidget.hh
otk/button.cc
otk/button.hh
otk/focuslabel.cc [deleted file]
otk/focuslabel.hh [deleted file]
otk/focuswidget.cc [deleted file]
otk/focuswidget.hh [deleted file]
otk/label.cc
otk/label.hh
otk/otk.hh
otk/otk_test.cc
otk/point.hh
otk/rect.cc [deleted file]
otk/rect.hh
otk/rendercontrol.cc
otk/renderstyle.cc
otk/renderstyle.hh
otk/screeninfo.cc
otk/screeninfo.hh
otk/surface.cc
otk/surface.hh
otk/truerendercontrol.cc
otk/widget.cc
otk/widget.hh

index 504319a7c9cf708d2f8ac0bd9ab7ea0446dd7b9e..0c463b5c60e913bb9048c924a45ab0024411d97d 100644 (file)
@@ -4,18 +4,17 @@ pkgconfigdir = $(libdir)/pkgconfig
 
 CPPFLAGS=$(XFT_CFLAGS) @CPPFLAGS@ -DBUTTONSDIR=\"$(buttonsdir)\"
 
-#noinst_LIBRARIES=libotk.a
 lib_LTLIBRARIES=libotk.la
 
-libotk_la_SOURCES=rendercontrol.cc truerendercontrol.cc surface.cc \
+libotk_la_SOURCES=rendercontrol.cc truerendercontrol.cc surface.cc util.cc \
                   renderstyle.cc rendercolor.cc pseudorendercontrol.cc \
-                  display.cc font.cc \
-                  property.cc rect.cc screeninfo.cc \
-                  timer.cc \
-                  util.cc widget.cc focuswidget.cc \
-                  button.cc eventhandler.cc eventdispatcher.cc ustring.cc \
-                  label.cc focuslabel.cc application.cc appwidget.cc
-includeotk_HEADERS=application.hh appwidget.hh assassin.hh button.hh \
+                  display.cc font.cc screeninfo.cc property.cc timer.cc \
+                  eventdispatcher.cc eventhandler.cc ustring.cc \
+                  widget.cc application.cc label.cc appwidget.cc button.cc
+
+#focuswidget.cc focuslabel.cc
+
+includeotk_HEADERS=application.hh appwidget.hh assassin.hh button.hh size.hh \
                    display.hh eventdispatcher.hh eventhandler.hh \
                    focuslabel.hh focuswidget.hh font.hh label.hh otk.hh \
                    point.hh property.hh pseudorendercontrol.hh rect.hh \
index efe86d153a21490decf652ab396bc9cdaf765c17..ffa33ab800487928b5f0cd2a4fafbe154e043a64 100644 (file)
@@ -6,10 +6,10 @@
 
 #include "application.hh"
 #include "eventhandler.hh"
-#include "widget.hh"
 #include "timer.hh"
 #include "property.hh"
 #include "rendercolor.hh"
+#include "renderstyle.hh"
 
 extern "C" {
 #ifdef HAVE_STDLIB_H
@@ -30,17 +30,19 @@ Application::Application(int argc, char **argv)
   (void)argc;
   (void)argv;
 
+  _screen = DefaultScreen(*_display);
+  
   Timer::initialize();
   RenderColor::initialize();
+  RenderStyle::initialize();
   Property::initialize();
-  _style = new RenderStyle(DefaultScreen(*_display), ""); // XXX: get a path!
 
   loadStyle();
 }
 
 Application::~Application()
 {
-  delete _style;
+  RenderStyle::destroy();
   RenderColor::destroy();
   Timer::destroy();
 }
index 6f1cebc6087100194e71ddb91e3ea6b4d3b750ba..848b79858723a195155b393f99f6a73b79b1612c 100644 (file)
@@ -4,7 +4,6 @@
 
 #include "eventdispatcher.hh"
 #include "display.hh"
-#include "renderstyle.hh"
 
 namespace otk {
 
@@ -17,20 +16,19 @@ public:
   Application(int argc, char **argv);
   virtual ~Application();
 
+  inline int screen() const { return _screen; }
+  
   virtual void run(void);
   // more bummy cool functionality
 
   void setDockable(bool dockable) { _dockable = dockable; }
   inline bool isDockable(void) const { return _dockable; }
 
-  inline RenderStyle *getStyle(void) const { return _style; }
-  // more accessors
-
 private:
   void loadStyle(void);
 
   Display _display;
-  RenderStyle *_style;
+  int _screen;
   bool _dockable;
 
   int _appwidget_count;
index afb86c0bb6a859e564ae9775abdd195a315382f6..5c963f7b58a5acbbf90703c487e7d78eb7b952c5 100644 (file)
@@ -7,6 +7,7 @@
 #include "appwidget.hh"
 #include "application.hh"
 #include "property.hh"
+#include "renderstyle.hh"
 
 extern "C" {
 #include <X11/Xlib.h>
@@ -14,9 +15,8 @@ extern "C" {
 
 namespace otk {
 
-AppWidget::AppWidget(Application *app, Direction direction,
-                     Cursor cursor, int bevel_width)
-  : Widget(app, app->getStyle(), direction, cursor, bevel_width),
+AppWidget::AppWidget(Application *app, Direction direction, int bevel)
+  : Widget(app->screen(), app, direction, bevel),
     _application(app)
 {
   assert(app);
@@ -26,29 +26,28 @@ AppWidget::AppWidget(Application *app, Direction direction,
   protocols[0] = Property::atoms.wm_protocols;
   protocols[1] = Property::atoms.wm_delete_window;
   XSetWMProtocols(**display, window(), protocols, 2);
-
-  setStyle(_style);
 }
 
 AppWidget::~AppWidget()
 {
 }
 
-void AppWidget::setStyle(RenderStyle *style)
+void AppWidget::render()
 {
-  Widget::setStyle(style);
-
-  setTexture(style->titlebarUnfocusBackground());
+  XSetWindowBackground(**display, window(),
+                       RenderStyle::style(screen())->
+                       titlebarUnfocusBackground()->color().pixel());
+  Widget::render();
 }
 
-void AppWidget::show(void)
+void AppWidget::show()
 {
   Widget::show(true);
 
   _application->_appwidget_count++;
 }
 
-void AppWidget::hide(void)
+void AppWidget::hide()
 {
   Widget::hide();
 
index b305dbae4a15e0e5b37a3896817be77818f7655c..b2ea44aadb7f237b80070cd2c593dc9c98cbf1d7 100644 (file)
@@ -11,14 +11,13 @@ class Application;
 class AppWidget : public Widget {
 
 public:
-  AppWidget(Application *app, Direction direction = Horizontal,
-            Cursor cursor = 0, int bevel_width = 1);
+  AppWidget(Application *app, Direction direction = Horizontal, int bevel = 0);
   virtual ~AppWidget();
 
-  virtual void setStyle(RenderStyle *style);
-  
-  virtual void show(void);
-  virtual void hide(void);
+  virtual void render();
+
+  virtual void show();
+  virtual void hide();
 
   virtual void clientMessageHandler(const XClientMessageEvent &e);
   
index c70511fc3b98e6c6bb88bbcd56c6407250f42e7c..8d63ed0c3b71a6268b353904d31040a668907ddd 100644 (file)
@@ -9,73 +9,73 @@
 namespace otk {
 
 Button::Button(Widget *parent)
-  : FocusLabel(parent), _pressed(false), _pressed_focus_tx(0),
-    _pressed_unfocus_tx(0), _unpr_focus_tx(0), _unpr_unfocus_tx(0)
+  : Label(parent), _default(false), _pressed(false)
 {
-  setStyle(_style);
+  setHorizontalJustify(RenderStyle::CenterJustify);
+  setVerticalJustify(RenderStyle::CenterJustify);
+  styleChanged(*RenderStyle::style(screen()));
 }
 
 Button::~Button()
 {
 }
 
-
-void Button::setStyle(RenderStyle *style)
-{
-  FocusLabel::setStyle(style);
-
-  setTexture(style->buttonUnpressFocusBackground());
-  setUnfocusTexture(style->buttonUnpressUnfocusBackground());
-  _pressed_focus_tx = style->buttonPressFocusBackground();
-  _pressed_unfocus_tx = style->buttonPressUnfocusBackground();
-}
-
-
 void Button::press(unsigned int mouse_button)
 {
   if (_pressed) return;
 
-  if (_pressed_unfocus_tx)
-    FocusWidget::setUnfocusTexture(_pressed_unfocus_tx);
-  if (_pressed_focus_tx)
-    FocusWidget::setTexture(_pressed_focus_tx);
   _pressed = true;
   _mouse_button = mouse_button;
+
+  styleChanged(*RenderStyle::style(screen()));
+  refresh();
 }
 
 void Button::release(unsigned int mouse_button)
 {
-  if (_mouse_button != mouse_button) return; // wrong button
+  if (!_pressed || _mouse_button != mouse_button) return; // wrong button
 
-  FocusWidget::setUnfocusTexture(_unpr_unfocus_tx);
-  FocusWidget::setTexture(_unpr_focus_tx);
   _pressed = false;
+
+  styleChanged(*RenderStyle::style(screen()));
+  refresh();
 }
 
-void Button::setTexture(RenderTexture *texture)
+void Button::buttonPressHandler(const XButtonEvent &e)
 {
-  FocusWidget::setTexture(texture);
-  _unpr_focus_tx = texture;
+  Widget::buttonPressHandler(e);
+  press(e.button);
 }
 
-void Button::setUnfocusTexture(RenderTexture *texture)
+void Button::buttonReleaseHandler(const XButtonEvent &e)
 {
-  FocusWidget::setUnfocusTexture(texture);
-  _unpr_unfocus_tx = texture;
+  Widget::buttonReleaseHandler(e);
+  release(e.button);
 }
 
-void Button::buttonPressHandler(const XButtonEvent &e)
+void Button::setDefault(bool d)
 {
-  press(e.button);
-  update();
-  FocusWidget::buttonPressHandler(e);
+  _default = d;
+  styleChanged(*RenderStyle::style(screen()));
+  refresh();
 }
 
-void Button::buttonReleaseHandler(const XButtonEvent &e)
+void Button::styleChanged(const RenderStyle &style)
 {
-  release(e.button);
-  update();
-  FocusWidget::buttonReleaseHandler(e);
+  if (_default) {
+    if (_pressed)
+      _texture = style.buttonPressFocusBackground();
+    else
+      _texture = style.buttonUnpressFocusBackground();
+    _forecolor = style.buttonFocusColor();
+  } else {
+    if (_pressed)
+      _texture = style.buttonPressUnfocusBackground();
+    else
+      _texture = style.buttonUnpressUnfocusBackground();
+    _forecolor = style.buttonUnfocusColor();
+  }
+  Widget::styleChanged(style);
 }
 
 }
index 1483677ea348a93ce548a00e9c159514ebe9ec9e..53d08a8645a145d11d4cfac95fc0a61e212d59b2 100644 (file)
@@ -2,49 +2,33 @@
 #ifndef __button_hh
 #define __button_hh
 
-#include "focuslabel.hh"
+#include "label.hh"
 
 namespace otk {
 
-class Button : public FocusLabel {
+class Button : public Label {
 
 public:
-
   Button(Widget *parent);
-  ~Button();
-
-  inline const RenderTexture *getPressedFocusTexture(void) const
-  { return _pressed_focus_tx; }
-  void setPressedFocusTexture(RenderTexture *texture)
-  { _pressed_focus_tx = texture; }
+  virtual ~Button();
 
-  inline const RenderTexture *getPressedUnfocusTexture(void) const
-  { return _pressed_unfocus_tx; }
-  void setPressedUnfocusTexture(RenderTexture *texture)
-  { _pressed_unfocus_tx = texture; }
-
-  void setTexture(RenderTexture *texture);
-  void setUnfocusTexture(RenderTexture *texture);
+  virtual inline bool isDefault() const { return _default; }
+  virtual void setDefault(bool d);
+  
+  virtual inline bool isPressed() const { return _pressed; }
 
-  inline bool isPressed(void) const { return _pressed; }
-  void press(unsigned int mouse_button);
-  void release(unsigned int mouse_button);
+  virtual void press(unsigned int mouse_button);
+  virtual void release(unsigned int mouse_button);
 
-  void buttonPressHandler(const XButtonEvent &e);
-  void buttonReleaseHandler(const XButtonEvent &e);
+  virtual void buttonPressHandler(const XButtonEvent &e);
+  virtual void buttonReleaseHandler(const XButtonEvent &e);
 
-  virtual void setStyle(RenderStyle *style);
-  
+  virtual void styleChanged(const RenderStyle &style);
 private:
-
+  bool _default;
   bool _pressed;
   unsigned int _mouse_button;
-
-  RenderTexture *_pressed_focus_tx;
-  RenderTexture *_pressed_unfocus_tx;
-
-  RenderTexture *_unpr_focus_tx;
-  RenderTexture *_unpr_unfocus_tx;
 };
 
 }
diff --git a/otk/focuslabel.cc b/otk/focuslabel.cc
deleted file mode 100644 (file)
index 846d035..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
-
-#include "focuslabel.hh"
-#include "display.hh"
-#include "screeninfo.hh"
-
-namespace otk {
-
-FocusLabel::FocusLabel(Widget *parent)
-  : FocusWidget(parent), _text("")
-{
-  setStyle(_style);
-}
-
-FocusLabel::~FocusLabel()
-{
-}
-
-
-void FocusLabel::setStyle(RenderStyle *style)
-{
-  FocusWidget::setStyle(style);
-
-  setTexture(style->labelFocusBackground());
-  setUnfocusTexture(style->labelUnfocusBackground());
-}
-
-void FocusLabel::fitString(const std::string &str)
-{
-  const Font *ft = style()->labelFont();
-  fitSize(ft->measureString(str), ft->height());
-}
-
-void FocusLabel::fitSize(int w, int h)
-{
-  unsigned int sidemargin = _bevel_width * 2;
-  resize(w + sidemargin * 2, h + _bevel_width * 2);
-}
-
-void FocusLabel::update()
-{
-  if (_dirty) {
-    int w = _rect.width(), h = _rect.height();
-    const Font *ft = style()->labelFont();
-    unsigned int sidemargin = _bevel_width * 2;
-    if (!_fixed_width)
-      w = ft->measureString(_text) + sidemargin * 2;
-    if (!_fixed_height)
-      h = ft->height();
-
-    // enforce a minimum size
-    if (w > _rect.width()) {
-      if (h > _rect.height())
-        internalResize(w, h);
-      else
-        internalResize(w, _rect.height());
-    } else if (h > _rect.height())
-      internalResize(_rect.width(), h);
-  }
-  FocusWidget::update();
-}
-
-
-void FocusLabel::renderForeground()
-{
-  FocusWidget::renderForeground();
-
-  const Font *ft = style()->labelFont();
-  RenderColor *text_color = (isFocused() ? style()->textFocusColor()
-                             : style()->textUnfocusColor());
-  unsigned int sidemargin = _bevel_width * 2;
-
-  ustring t = _text; // the actual text to draw
-  int x = sidemargin;    // x coord for the text
-
-  // find a string that will fit inside the area for text
-  int max_length = width() - sidemargin * 2;
-  if (max_length <= 0) {
-    t = ""; // can't fit anything
-  } else {
-    size_t text_len = t.size();
-    int length;
-      
-    do {
-      t.resize(text_len);
-      length = ft->measureString(t);
-    } while (length > max_length && text_len-- > 0);
-
-    // justify the text
-    switch (style()->labelTextJustify()) {
-    case RenderStyle::RightJustify:
-      x += max_length - length;
-      break;
-    case RenderStyle::CenterJustify:
-      x += (max_length - length) / 2;
-      break;
-    case RenderStyle::LeftJustify:
-      break;
-    }
-  }
-
-  display->renderControl(_screen)->
-    drawString(*_surface, *ft, x, _bevel_width, *text_color, t);
-}
-
-}
diff --git a/otk/focuslabel.hh b/otk/focuslabel.hh
deleted file mode 100644 (file)
index c25ab29..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __focuslabel_hh
-#define __focuslabel_hh
-
-#include "focuswidget.hh"
-
-namespace otk {
-
-class FocusLabel : public FocusWidget {
-
-public:
-
-  FocusLabel(Widget *parent);
-  ~FocusLabel();
-
-  inline const ustring &getText(void) const { return _text; }
-  void setText(const ustring &text) { _text = text; _dirty = true; }
-
-  virtual void renderForeground();
-
-  virtual void update();
-
-  void fitString(const std::string &str);
-  void fitSize(int w, int h);
-
-  virtual void setStyle(RenderStyle *style);
-  
-private:
-  //! Text displayed in the label
-  ustring _text;
-};
-
-}
-
-#endif // __focuslabel_hh
diff --git a/otk/focuswidget.cc b/otk/focuswidget.cc
deleted file mode 100644 (file)
index b8e18d7..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
-
-#include "focuswidget.hh"
-
-namespace otk {
-
-FocusWidget::FocusWidget(Widget *parent, Direction direction)
-  : Widget(parent, direction), _unfocus_texture(0), _unfocus_bcolor(0)
-{
-  _focused = true;
-  _focus_texture = parent->texture();
-  _focus_bcolor = parent->borderColor();
-}
-
-FocusWidget::~FocusWidget()
-{
-}
-
-
-void FocusWidget::focus(void)
-{
-  if (_focused)
-    return;
-
-  Widget::focus();
-
-  if (_focus_bcolor)
-    Widget::setBorderColor(_focus_bcolor);
-
-  Widget::setTexture(_focus_texture);
-  update();
-}
-
-void FocusWidget::unfocus(void)
-{
-  if (!_focused)
-    return;
-
-  Widget::unfocus();
-
-  if (_unfocus_bcolor)
-    Widget::setBorderColor(_unfocus_bcolor);
-
-  Widget::setTexture(_unfocus_texture);
-  update();
-}
-
-void FocusWidget::setTexture(RenderTexture *texture)
-{
-  Widget::setTexture(texture);
-  _focus_texture = texture;
-  if (!_focused)
-    Widget::setTexture(_unfocus_texture);
-}
-
-void FocusWidget::setBorderColor(const RenderColor *color)
-{
-  Widget::setBorderColor(color);
-  _focus_bcolor = color;
-}
-
-}
diff --git a/otk/focuswidget.hh b/otk/focuswidget.hh
deleted file mode 100644 (file)
index 886a2e3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __focuswidget_hh
-#define __focuswidget_hh
-
-#include "widget.hh"
-#include "application.hh"
-
-namespace otk {
-
-class FocusWidget : public Widget {
-
-public:
-
-  FocusWidget(Widget *parent, Direction = Horizontal);
-  virtual ~FocusWidget();
-
-  virtual void focus(void);
-  virtual void unfocus(void);
-
-  virtual void setTexture(RenderTexture *texture);
-  virtual void setBorderColor(const RenderColor *color);
-
-  inline void setUnfocusTexture(RenderTexture *texture)
-  { _unfocus_texture = texture; }
-  inline RenderTexture *getUnfocusTexture(void) const
-  { return _unfocus_texture; }
-
-  inline void setUnfocusBorderColor(const RenderColor *color)
-  { _unfocus_bcolor = color; }
-  inline const RenderColor *getUnfocusBorderColor(void) const
-  { return _unfocus_bcolor; }
-
-  inline bool isFocused(void) const { return _focused; }
-  inline bool isUnfocused(void) const { return !_focused; }
-
-private:
-
-  RenderTexture *_unfocus_texture;
-  RenderTexture *_focus_texture;
-
-  const RenderColor *_unfocus_bcolor;
-  const RenderColor *_focus_bcolor;
-};
-
-}
-
-#endif // __focuswidget_hh
index 16bfd5f47cf9cf49d323b2cac2ee6d4a0d655497..0c18b5d03cc001616f4d4a87c8ef65a9cd218713 100644 (file)
 #endif
 
 #include "label.hh"
+#include "display.hh"
+#include "rendercontrol.hh"
+
+#include <string>
 
 namespace otk {
 
 Label::Label(Widget *parent)
-  : Widget(parent), _text("")
+  : Widget(parent),
+    _text(""),
+    _justify_horz(RenderStyle::LeftTopJustify),
+    _justify_vert(RenderStyle::LeftTopJustify)
 {
-  setStyle(_style);
+  styleChanged(*RenderStyle::style(screen()));
 }
 
 Label::~Label()
 {
 }
 
-void Label::setStyle(RenderStyle *style)
+void Label::setHorizontalJustify(RenderStyle::Justify j)
 {
-  Widget::setStyle(style);
+  _justify_horz = j;
+  refresh();
+}
 
-  setTexture(style->labelUnfocusBackground());
+void Label::setVerticalJustify(RenderStyle::Justify j)
+{
+  _justify_vert = j;
+  refresh();
 }
 
-void Label::fitString(const std::string &str)
+void Label::setText(const ustring &text)
 {
-  const Font *ft = style()->labelFont();
-  fitSize(ft->measureString(str), ft->height());
+  bool utf = text.utf8();
+  std::string s = text.c_str(); // use a normal string, for its functionality
+
+  _parsedtext.clear();
+  
+  // parse it into multiple lines
+  std::string::size_type p = 0;
+  while (p != std::string::npos) {
+    std::string::size_type p2 = s.find('\n', p);
+    _parsedtext.push_back(s.substr(p, (p2==std::string::npos?p2:p2-p)));
+    _parsedtext.back().setUtf8(utf);
+    p = (p2==std::string::npos?p2:p2+1);
+  }
+  calcDefaultSizes();
 }
 
-void Label::fitSize(int w, int h)
+void Label::setFont(const Font *f)
 {
-  unsigned int sidemargin = _bevel_width * 2;
-  resize(w + sidemargin * 2, h + _bevel_width * 2);
+  _font = f;
+  calcDefaultSizes();
 }
 
-void Label::update()
+void Label::calcDefaultSizes()
 {
-  if (_dirty) {
-    int w = _rect.width(), h = _rect.height();
-    const Font *ft = style()->labelFont();
-    unsigned int sidemargin = _bevel_width * 2;
-    if (!_fixed_width)
-      w = ft->measureString(_text) + sidemargin * 2;
-    if (!_fixed_height)
-      h = ft->height();
-
-    // enforce a minimum size
-    if (w > _rect.width()) {
-      if (h > _rect.height())
-        internalResize(w, h);
-      else
-        internalResize(w, _rect.height());
-    } else if (h > _rect.height())
-      internalResize(_rect.width(), h);
+  unsigned int longest = 0;
+  // find the longest line
+  std::vector<ustring>::iterator it, end = _parsedtext.end();
+  for (it = _parsedtext.begin(); it != end; ++it) {
+    unsigned int length = _font->measureString(*it);
+    if (length > longest) longest = length;
   }
-  Widget::update();
+  setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4,
+                  _parsedtext.size() * _font->height() + borderWidth() * 2 +
+                  bevel() * 2));
 }
-
-
-void Label::renderForeground(void)
+  
+void Label::styleChanged(const RenderStyle &style)
 {
-  Widget::renderForeground();
-
-  const Font *ft = style()->labelFont();
-  unsigned int sidemargin = _bevel_width * 2;
-
-  ustring t = _text; // the actual text to draw
-  int x = sidemargin;    // x coord for the text
+  _texture = style.labelFocusBackground();
+  _forecolor = style.textFocusColor();
+  _font = style.labelFont();
+  Widget::styleChanged(style);
+  calcDefaultSizes();
+}
 
-  // find a string that will fit inside the area for text
-  int max_length = width() - sidemargin * 2;
-  if (max_length <= 0) {
-    t = ""; // can't fit anything
-  } else {
-    size_t text_len = t.size();
-    int length;
+void Label::renderForeground(Surface &surface)
+{
+  const RenderControl *control = display->renderControl(screen());
+  unsigned int sidemargin = bevel() * 2;
+  int y = bevel();
+  unsigned int w = area().width() - borderWidth() * 2 - sidemargin * 2;
+  unsigned int h = area().height() - borderWidth() * 2 - bevel() * 2;
+
+  switch (_justify_vert) {
+  case RenderStyle::RightBottomJustify:
+    y += h - (_parsedtext.size() * _font->height());
+    if (y < bevel()) y = bevel();
+    break;
+  case RenderStyle::CenterJustify:
+    y += (h - (_parsedtext.size() * _font->height())) / 2;
+    if (y < bevel()) y = bevel();
+    break;
+  case RenderStyle::LeftTopJustify:
+    break;
+  }
+  
+  if (w <= 0) return; // can't fit anything
+  
+  std::vector<ustring>::iterator it, end = _parsedtext.end();
+  for (it = _parsedtext.begin(); it != end; ++it, y += _font->height()) {
+    ustring t = *it; // the actual text to draw
+    int x = sidemargin;    // x coord for the text
+
+    // find a string that will fit inside the area for text
+    ustring::size_type text_len = t.size();
+    unsigned int length;
       
     do {
       t.resize(text_len);
-      length = ft->measureString(t);
-    } while (length > max_length && text_len-- > 0);
+      length = _font->measureString(t);
+    } while (length > w && text_len-- > 0);
+
+    if (text_len <= 0) continue; // won't fit anything
 
     // justify the text
-    switch (style()->labelTextJustify()) {
-    case RenderStyle::RightJustify:
-      x += max_length - length;
+    switch (_justify_horz) {
+    case RenderStyle::RightBottomJustify:
+      x += w - length;
       break;
     case RenderStyle::CenterJustify:
-      x += (max_length - length) / 2;
+      x += (w - length) / 2;
       break;
-    case RenderStyle::LeftJustify:
+    case RenderStyle::LeftTopJustify:
       break;
     }
-  }
-
-  display->renderControl(_screen)->
-    drawString(*_surface, *ft, x, _bevel_width, *style()->textUnfocusColor(), t);
+    control->drawString(surface, *_font, x, y, *_forecolor, t);
+ }
 }
 
 }
index 9c32e544936ea0ebc414633814572690eec585e4..1b31ae79a5b91703096c71f80e295f9241bbb095 100644 (file)
@@ -3,33 +3,54 @@
 #define __label_hh
 
 #include "widget.hh"
+#include "ustring.hh"
+#include "renderstyle.hh"
+#include "font.hh"
+
+#include <vector>
 
 namespace otk {
 
 class Label : public Widget {
 
 public:
-
   Label(Widget *parent);
-  ~Label();
+  virtual ~Label();
 
-  inline const ustring &getText(void) const { return _text; }
-  void setText(const ustring &text) { _text = text; _dirty = true; }
+  inline const ustringgetText(void) const { return _text; }
+  void setText(const ustring &text);
 
-  virtual void renderForeground(void);
+  RenderStyle::Justify horizontalJustify() const { return _justify_horz; }
+  virtual void setHorizontalJustify(RenderStyle::Justify j);
+  RenderStyle::Justify verticalJustify() const { return _justify_vert; }
+  virtual void setVerticalJustify(RenderStyle::Justify j);
 
-  virtual void update();
+  const Font *font() const { return _font; }
+  virtual void setFont(const Font *f);
 
-  void fitString(const std::string &str);
-  void fitSize(int w, int h);
+  virtual void calcDefaultSizes();
 
-  virtual void setStyle(RenderStyle *style);
+  virtual void styleChanged(const RenderStyle &style);
+  
+  virtual void renderForeground(Surface &surface);
 
+protected:
+  //! The color the label will use for rendering its text
+  RenderColor *_forecolor;
+  
 private:
   //! Text to be displayed in the label
   ustring _text;
+  //! Text to be displayed, parsed into its separate lines
+  std::vector<ustring> _parsedtext;
   //! The actual text being shown, may be a subset of _text
   ustring _drawtext;
+  //! The font the text will be rendered with
+  const Font *_font;
+  //! The horizontal justification used for drawing text
+  RenderStyle::Justify _justify_horz;
+  //! The vertical justification used for drawing text
+  RenderStyle::Justify _justify_vert;
   //! The drawing offset for the text
   int _drawx;
 };
index 9be1ec36d131d62255cbe84e23fa45dc1340c31f..62788cba9baf8d1f28a59e8467ce582939ed6dc3 100644 (file)
@@ -7,8 +7,6 @@
 #include "eventdispatcher.hh"
 #include "eventhandler.hh"
 #include "widget.hh"
-#include "focuswidget.hh"
-#include "focuslabel.hh"
 #include "appwidget.hh"
 #include "application.hh"
 #include "assassin.hh"
@@ -17,8 +15,8 @@
 #include "rendercolor.hh"
 #include "display.hh"
 #include "font.hh"
-//#include "gccache.hh"
 #include "rendercontrol.hh"
+#include "size.hh"
 #include "point.hh"
 #include "property.hh"
 #include "rect.hh"
index fb4db8352df5e40f379fc06af9365340ffa4b384..c36abfd189744914d641d04edccec20a9402c968 100644 (file)
@@ -5,75 +5,30 @@
 #endif
 
 #include "application.hh"
-#include "focuswidget.hh"
 #include "appwidget.hh"
+#include "label.hh"
 #include "button.hh"
 
 int main(int argc, char **argv) {
   otk::Application app(argc, argv);
 
-  otk::AppWidget foo(&app);
-
-  foo.resize(600, 500);
-  foo.setTexture(app.getStyle()->titlebarFocusBackground());
-//  foo.setUnfocusTexture(app.getStyle()->titlebarUnfocusBackground());
-
-  foo.setBevelWidth(2);
-  foo.setDirection(otk::Widget::Horizontal);
-
-  otk::FocusWidget left(&foo);
-  otk::FocusWidget right(&foo);
-
-  left.setDirection(otk::Widget::Horizontal);
-  left.setStretchableVert(true);
-  left.setStretchableHorz(true);
-  left.setTexture(app.getStyle()->titlebarFocusBackground());
-  left.setUnfocusTexture(app.getStyle()->titlebarUnfocusBackground());
-  right.setDirection(otk::Widget::Vertical);
-  right.setBevelWidth(10);
-  right.setStretchableVert(true);
-  right.setWidth(300);
-  right.setTexture(app.getStyle()->titlebarFocusBackground());
-  right.setUnfocusTexture(app.getStyle()->titlebarUnfocusBackground());
-  otk::Button iconb(&left);
-  iconb.resize(40,20);
-
-/*  otk::FocusWidget label(&left);
-  otk::Button maxb(&left);
-  otk::Button closeb(&left);
+  otk::AppWidget foo(&app, otk::Widget::Vertical, 3);
+  otk::Label lab(&foo);
+  otk::Label lab2(&foo);
+  otk::Button but(&foo);
+  otk::Button but2(&foo);
   
-  // fixed size
-  iconb.setText("foo");
-  iconb.press(Button1);
-
-  // fix width to 60 and let the height be calculated by its parent
-  //label.setHeight(20);
-  label.setStretchableVert(true);
-  label.setStretchableHorz(true);
-  label.setTexture(app.getStyle()->labelFocusBackground());
-  label.setUnfocusTexture(app.getStyle()->labelUnfocusBackground());
-
-  // fixed size
-  maxb.setText("bar");
-
-  // fixed size
-  closeb.setText("fuubar");
-*/
-  otk::FocusWidget rblef(&right);
-  otk::Button rbutt1(&right);
-  otk::Button rbutt2(&right);
-
-  rblef.setStretchableHorz(true);
-  rblef.setHeight(50);
-  rblef.setTexture(app.getStyle()->handleFocusBackground());
-  rblef.setUnfocusTexture(app.getStyle()->handleUnfocusBackground());
+  foo.resize(otk::Size(100, 150));
+
+  lab.setText("Hi, I'm a sexy\nlabel!!!");
+  lab.setMaxSize(otk::Size(0,0));
+  lab2.setText("Me too!!");
+  lab2.setBorderWidth(10);
+  lab2.setBorderColor(otk::RenderStyle::style(app.screen())->buttonFocusColor());
+  but.setText("Im not the default button...");
+  but2.setText("But I AM!!");
+  but2.setDefault(true);
   
-  rbutt1.setText("this is fucking tight");
-  rbutt2.setText("heh, WOOP");
-
-  // will recursively unfocus its children
-  //foo.unfocus();
 
   foo.show();
 
index 66c3b14d039e57150587b55e7258212a5a72dad4..f438b34710a1f14a744c9ddc51757df079487ba1 100644 (file)
@@ -2,40 +2,22 @@
 #ifndef __point_hh
 #define __point_hh
 
-/*! @file point.hh
-  @brief The Point class contains an x/y pair
-*/
-
 namespace otk {
 
-//! The Point class is an x/y coordinate or size pair
 class Point {
-private:
-  //! The x value
-  int _x;
-  //! The y value
-  int _y;
-
+  int _x, _y;
 public:
-  //! Constructs a new Point with 0,0 values
   Point() : _x(0), _y(0) {}
-  //! Constructs a new Point with given values
   Point(int x, int y) : _x(x), _y(y) {}
+  Point(const Point &p) : _x(p._x), _y(p._y) {}
 
-  //! Changes the x value to the new value specified
-  void setX(int x) { _x = x; }
-  //! Returns the x value
-  int x() const { return _x; }
-
-  //! Changes the y value to the new value specified
-  void setY(int y) { _y = y; }
-  //! Returns the y value
-  int y() const { return _y; }
+  inline int x() const { return _x; }
+  inline int y() const { return _y; }
 
-  //! Changes the x and y values
-  void setPoint(int x, int y) { _x = x; _y = y; }
+  bool operator==(const Point &o) const { return _x == o._x && _y == o._y; }
+  bool operator!=(const Point &o) const { return _x != o._x || _y != o._y; }
 };
 
 }
 
-#endif /* __point_hh */
+#endif // __point_hh
diff --git a/otk/rect.cc b/otk/rect.cc
deleted file mode 100644 (file)
index 7ec5c2c..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
-
-#include "rect.hh"
-
-namespace otk {
-
-void Rect::setX(int x)
-{
-  _x2 += x - _x1;
-  _x1 = x;
-}
-
-
-void Rect::setY(int y)
-{
-  _y2 += y - _y1;
-  _y1 = y;
-}
-
-
-void Rect::setPos(const Point &location)
-{
-  _x2 += location.x() - _x1;
-  _x1 = location.x();
-  _y2 += location.y() - _y1;
-  _y1 = location.y();
-}
-
-
-void Rect::setPos(int x, int y)
-{
-  _x2 += x - _x1;
-  _x1 = x;
-  _y2 += y - _y1;
-  _y1 = y;
-}
-
-
-void Rect::setWidth(int w)
-{
-  _x2 = w + _x1 - 1;
-}
-
-
-void Rect::setHeight(int h)
-{
-  _y2 = h + _y1 - 1;
-}
-
-
-void Rect::setSize(int w, int h)
-{
-  _x2 = w + _x1 - 1;
-  _y2 = h + _y1 - 1;
-}
-
-
-void Rect::setSize(const Point &size)
-{
-  _x2 = size.x() + _x1 - 1;
-  _y2 = size.y() + _y1 - 1;
-}
-
-
-void Rect::setRect(int x, int y, int w, int h)
-{
-  *this = Rect(x, y, w, h);
-}
-
-
-void Rect::setRect(const Point &location, const Point &size)
-{
-  *this = Rect(location, size);
-}
-
-
-void Rect::setCoords(int l, int t, int r, int b)
-{
-  _x1 = l;
-  _y1 = t;
-  _x2 = r;
-  _y2 = b;
-}
-
-
-void Rect::setCoords(const Point &tl, const Point &br)
-{
-  _x1 = tl.x();
-  _y1 = tl.y();
-  _x2 = br.x();
-  _y2 = br.y();
-}
-
-
-Rect Rect::operator|(const Rect &a) const
-{
-  Rect b;
-
-  b._x1 = std::min(_x1, a._x1);
-  b._y1 = std::min(_y1, a._y1);
-  b._x2 = std::max(_x2, a._x2);
-  b._y2 = std::max(_y2, a._y2);
-
-  return b;
-}
-
-
-Rect Rect::operator&(const Rect &a) const
-{
-  Rect b;
-
-  b._x1 = std::max(_x1, a._x1);
-  b._y1 = std::max(_y1, a._y1);
-  b._x2 = std::min(_x2, a._x2);
-  b._y2 = std::min(_y2, a._y2);
-
-  return b;
-}
-
-
-bool Rect::intersects(const Rect &a) const
-{
-  return std::max(_x1, a._x1) <= std::min(_x2, a._x2) &&
-         std::max(_y1, a._y1) <= std::min(_y2, a._y2);
-}
-
-
-bool Rect::contains(int x, int y) const
-{
-  return x >= _x1 && x <= _x2 &&
-         y >= _y1 && y <= _y2;
-}
-
-
-bool Rect::contains(const Point &p) const
-{
-  return contains(p.x(), p.y());
-}
-
-
-bool Rect::contains(const Rect& a) const
-{
-  return a._x1 >= _x1 && a._x2 <= _x2 &&
-         a._y1 >= _y1 && a._y2 <= _y2;
-}
-
-}
index de4f5e0397174700c5b83fb0a7fcd56fc866decb..fe98dcb59d9e45725efc2ea8c0068c7cd2c775da 100644 (file)
 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef   __rect_hh
-#define   __rect_hh
-
-extern "C" {
-#include <X11/Xlib.h>
-}
+#ifndef __rect_hh
+#define __rect_hh
 
 #include "point.hh"
-#include <vector>
+#include "size.hh"
 
 namespace otk {
 
-//! The Rect class defines a rectangle in the plane.
 class Rect {
+  Point _p;
+  Size _s;
 public:
-  //! Constructs an invalid Rect
-  inline Rect(void) : _x1(0), _y1(0), _x2(0), _y2(0) { }
-  //! Constructs a Rect
-  /*!
-    @param x The x component of the point defining the top left corner of the 
-             rectangle
-    @param y The y component of the point defining the top left corner of the
-             rectangle
-    @param w The width of the rectangle
-    @param h The height of the rectangle
-  */
-  inline Rect(int x, int y, int w, int h)
-    : _x1(x), _y1(y), _x2(w + x - 1), _y2(h + y - 1) { }
-  //! Constructs a Rect from 2 Point objects
-  /*!
-    @param location The point defining the top left corner of the rectangle
-    @param size The width and height of the rectangle
-  */
-  inline Rect(const Point &location, const Point &size)
-    : _x1(location.x()), _y1(location.y()),
-      _x2(size.x() + location.x() - 1), _y2(size.y() + location.y() - 1) { }
-  //! Constructs a Rect from another Rect
-  /*!
-    @param rect The rectangle from which to construct this new one
-  */
-  inline Rect(const Rect &rect)
-    : _x1(rect._x1), _y1(rect._y1), _x2(rect._x2), _y2(rect._y2) { }
-  //! Constructs a Rect from an XRectangle
-  inline explicit Rect(const XRectangle& xrect)
-    : _x1(xrect.x), _y1(xrect.y), _x2(xrect.width + xrect.x - 1),
-      _y2(xrect.height + xrect.y - 1) { }
-
-  //! Returns the left coordinate of the Rect. Identical to Rect::x.
-  inline int left(void) const { return _x1; }
-  //! Returns the top coordinate of the Rect. Identical to Rect::y.
-  inline int top(void) const { return _y1; }
-  //! Returns the right coordinate of the Rect
-  inline int right(void) const { return _x2; }
-  //! Returns the bottom coordinate of the Rect
-  inline int bottom(void) const { return _y2; }
-
-  //! The x component of the point defining the top left corner of the Rect
-  inline int x(void) const { return _x1; }
-  //! The y component of the point defining the top left corner of the Rect
-  inline int y(void) const { return _y1; }
-  //! Returns the Point that defines the top left corner of the rectangle
-  inline Point location() const { return Point(_x1, _y1); }
-
-  //! Sets the x coordinate of the Rect.
-  /*!
-    @param x The new x component of the point defining the top left corner of
-             the rectangle
-  */
-  void setX(int x);
-  //! Sets the y coordinate of the Rect.
-  /*!
-    @param y The new y component of the point defining the top left corner of
-             the rectangle
-  */
-  void setY(int y);
-  //! Sets the x and y coordinates of the Rect.
-  /*!
-    @param x The new x component of the point defining the top left corner of
-             the rectangle
-    @param y The new y component of the point defining the top left corner of
-             the rectangle
-  */
-  void setPos(int x, int y);
-  //! Sets the x and y coordinates of the Rect.
-  /*!
-    @param location The point defining the top left corner of the rectangle.
-  */
-  void setPos(const Point &location);
-
-  //! The width of the Rect
-  inline int width(void) const { return _x2 - _x1 + 1; }
-  //! The height of the Rect
-  inline int height(void) const { return _y2 - _y1 + 1; }
-  //! Returns the size of the Rect
-  inline Point size() const { return Point(_x2 - _x1 + 1, _y2 - _y1 + 1); }
-
-  //! Sets the width of the Rect
-  /*!
-    @param w The new width of the rectangle
-  */
-  void setWidth(int w);
-  //! Sets the height of the Rect
-  /*!
-    @param h The new height of the rectangle
-  */
-  void setHeight(int h);
-  //! Sets the size of the Rect.
-  /*!
-    @param w The new width of the rectangle
-    @param h The new height of the rectangle
-  */
-  void setSize(int w, int h);
-  //! Sets the size of the Rect.
-  /*!
-    @param size The new size of the rectangle
-  */
-  void setSize(const Point &size);
-
-  //! Sets the position and size of the Rect
-  /*!
-    @param x The new x component of the point defining the top left corner of
-             the rectangle
-    @param y The new y component of the point defining the top left corner of
-             the rectangle
-    @param w The new width of the rectangle
-    @param h The new height of the rectangle
-   */
-  void setRect(int x, int y, int w, int h);
-  //! Sets the position and size of the Rect
-  /*!
-    @param location The new point defining the top left corner of the rectangle
-    @param size The new size of the rectangle
-   */
-  void setRect(const Point &location, const Point &size);
-
-  //! Sets the position of all 4 sides of the Rect
-  /*!
-    @param l The new left coordinate of the rectangle
-    @param t The new top coordinate of the rectangle
-    @param r The new right coordinate of the rectangle
-    @param b The new bottom coordinate of the rectangle
-   */
-  void setCoords(int l, int t, int r, int b);
-  //! Sets the position of all 4 sides of the Rect
-  /*!
-    @param tl The new point at the top left of the rectangle
-    @param br The new point at the bottom right of the rectangle
-   */
-  void setCoords(const Point &tl, const Point &br);
-
-  //! Determines if two Rect objects are equal
-  /*!
-    The rectangles are considered equal if they are in the same position and
-    are the same size.
-  */
-  inline bool operator==(const Rect &a)
-  { return _x1 == a._x1 && _y1 == a._y1 && _x2 == a._x2 && _y2 == a._y2; }
-  //! Determines if two Rect objects are inequal
-  /*!
-    @see operator==
-  */
-  inline bool operator!=(const Rect &a) { return ! operator==(a); }
-
-  //! Returns the union of two Rect objects
-  /*!
-    The union of the rectangles will consist of the maximimum area that the two
-    rectangles can make up.
-    @param a A second Rect object to form a union with.
-   */
-  Rect operator|(const Rect &a) const;
-  //! Returns the intersection of two Rect objects
-  /*!
-    The intersection of the rectangles will consist of just the area where the
-    two rectangles overlap.
-    @param a A second Rect object to form an intersection with.
-    @return The intersection between this Rect and the one passed to the
-            function
-  */
-  Rect operator&(const Rect &a) const;
-  //! Sets the Rect to the union of itself with another Rect object
-  /*!
-    The union of the rectangles will consist of the maximimum area that the two
-    rectangles can make up.
-    @param a A second Rect object to form a union with.
-    @return The union between this Rect and the one passed to the function
-   */
-  inline Rect &operator|=(const Rect &a) { *this = *this | a; return *this; }
-  //! Sets the Rect to the intersection of itself with another Rect object
-  /*!
-    The intersection of the rectangles will consist of just the area where the
-    two rectangles overlap.
-    @param a A second Rect object to form an intersection with.
-  */
-  inline Rect &operator&=(const Rect &a) { *this = *this & a; return *this; }
-
-  //! Returns if the Rect is valid
-  /*!
-    A rectangle is valid only if its right and bottom coordinates are larger
-    than its left and top coordinates (i.e. it does not have a negative width
-    or height).
-    @return true if the Rect is valid; otherwise, false
-  */
-  inline bool valid(void) const { return _x2 > _x1 && _y2 > _y1; }
-
-  //! Determines if this Rect intersects another Rect
-  /*!
-    The rectangles intersect if any part of them overlaps.
-    @param a Another Rect object to compare this Rect with
-    @return true if the Rect objects overlap; otherwise, false
-  */
-  bool intersects(const Rect &a) const;
-  //! Determines if this Rect contains a point
-  /*!
-    The rectangle contains the point if it falls within the rectangle's
-    boundaries.
-    @param x The x coordinate of the point to operate on
-    @param y The y coordinate of the point to operate on
-    @return true if the point is contained within this Rect; otherwise, false
-  */
-  bool contains(int x, int y) const;
-  //! Determines if this Rect contains a point
-  /*!
-    The rectangle contains the point if it falls within the rectangle's
-    boundaries.
-    @param p The point to operate on
-    @return true if the point is contained within this Rect; otherwise, false
-  */
-  bool contains(const Point &p) const;
-  //! Determines if this Rect contains another Rect entirely
-  /*!
-    This rectangle contains the second rectangle if it is entirely within this
-    rectangle's boundaries.
-    @param a The Rect to test for containment inside of this Rect
-    @return true if the second Rect is contained within this Rect; otherwise,
-            false
-  */
-  bool contains(const Rect &a) const;
-
-private:
-  //! The left coordinate of the Rect
-  int _x1;
-  //! The top coordinate of the Rect
-  int _y1;
-  //! The right coordinate of the Rect
-  int _x2;
-  //! The bottom coordinate of the Rect
-  int _y2;
+  Rect() : _p(), _s() {}
+  Rect(const Point &p, const Size &s) : _p(p), _s(s) {}
+  Rect(const Rect &r) : _p(r._p), _s(r._s) {}
+  Rect(int x, int y, unsigned int w, unsigned int h)
+    : _p(x, y), _s(w, h) {}
+
+  inline int x() const { return _p.x(); }
+  inline int y() const { return _p.y(); }
+  inline unsigned int width() const { return _s.width(); }
+  inline unsigned int height() const { return _s.height(); }
+
+  inline int left() const { return _p.x(); }
+  inline int top() const { return _p.y(); }
+  inline int right() const { return _p.x() + _s.width() - 1; }
+  inline int bottom() const { return _p.y() + _s.height() - 1; }
+
+  inline const Point& position() const { return _p; }
+  inline const Size& size() const { return _s; }
+
+  bool operator==(const Rect &o) const { return _p == o._p && _s == o._s; }
+  bool operator!=(const Rect &o) const { return _p != o._p || _s != o._s; }
 };
 
-//! A list for Rect objects
-typedef std::vector<Rect> RectList;
-
 }
 
 #endif // __rect_hh
index aae6c76bfa3a01f02b3c82f06c3f15f74de8c6e3..bf69a4e5c7c7694cd3322353fd74f86c57752776 100644 (file)
@@ -9,6 +9,7 @@
 #include "pseudorendercontrol.hh"
 #include "rendertexture.hh"
 #include "rendercolor.hh"
+#include "renderstyle.hh"
 #include "display.hh"
 #include "screeninfo.hh"
 #include "surface.hh"
@@ -50,15 +51,11 @@ RenderControl::RenderControl(int screen)
   : _screen(screen)
 {
   printf("Initializing RenderControl\n");
-
-  
 }
 
 RenderControl::~RenderControl()
 {
   printf("Destroying RenderControl\n");
-
-
 }
 
 void RenderControl::drawRoot(const RenderColor &color) const
@@ -120,7 +117,7 @@ void RenderControl::drawSolidBackground(Surface& sf,
   
   sf.setPixmap(texture.color());
 
-  int width = sf.width(), height = sf.height();
+  int width = sf.size().width(), height = sf.size().height();
   int left = 0, top = 0, right = width - 1, bottom = height - 1;
 
   if (texture.interlaced())
index 5e19aa47f8a7e51f5170495bcc097bf6b6dd559d..13d9e577b28811a8b680dea56eb245c405a0309a 100644 (file)
@@ -8,8 +8,49 @@
 #include "display.hh"
 #include "screeninfo.hh"
 
+#include <cassert>
+
 namespace otk {
 
+RenderStyle **RenderStyle::_styles = 0;
+std::list<StyleNotify*> *RenderStyle::_notifies = 0;
+
+void RenderStyle::initialize()
+{
+  int screens = ScreenCount(**display);
+  _styles = new RenderStyle*[screens];
+  for (int i = 0; i < screens; ++i)
+    _styles[i] = new RenderStyle(i, ""); // XXX get a path
+  _notifies = new std::list<StyleNotify*>[screens];
+}
+
+void RenderStyle::destroy()
+{
+  int screens = ScreenCount(**display);
+  for (int i = 0; i < screens; ++i)
+    delete _styles[i];
+  delete [] _styles;
+  delete [] _notifies;
+}
+
+void RenderStyle::registerNotify(int screen, StyleNotify *n)
+{
+  assert(screen >= 0 && screen < ScreenCount(**display));
+  _notifies[screen].push_back(n);
+}
+
+void RenderStyle::unregisterNotify(int screen, StyleNotify *n)
+{
+  assert(screen >= 0 && screen < ScreenCount(**display));
+  _notifies[screen].remove(n);
+}
+
+RenderStyle *RenderStyle::style(int screen)
+{
+  assert(screen >= 0 && screen < ScreenCount(**display));
+  return _styles[screen];
+}
+
 RenderStyle::RenderStyle(int screen, const std::string &stylefile)
   : _screen(screen),
     _file(stylefile)
@@ -175,7 +216,7 @@ RenderStyle::RenderStyle(int screen, const std::string &stylefile)
                                     0x0);
 
   _label_font = new Font(_screen, "Arial,Sans-9:bold", true, 1, 0x40);
-  _label_justify = RightJustify;
+  _label_justify = RightBottomJustify;
 
   _max_mask = new PixmapMask();
   _max_mask->w = _max_mask->h = 8;
index 2d2c325041b5241121183dffdc90058fa858004c..697455337c9cae067952d92cf037016ff7a7f32c 100644 (file)
@@ -7,6 +7,7 @@
 #include "font.hh"
 
 #include <string>
+#include <list>
 
 namespace otk {
 
@@ -16,11 +17,27 @@ struct PixmapMask {
   PixmapMask() { mask = None; w = h = 0; }
 };
 
+class RenderStyle;
+
+class StyleNotify {
+public:
+  //! Called when the style is changed on the same screen as the handler.
+  virtual void styleChanged(const RenderStyle &) {}
+};
+
 class RenderStyle {
+  static RenderStyle **_styles;
+  static std::list<StyleNotify*> *_notifies;
 public:
-  enum TextJustify {
-    LeftJustify,
-    RightJustify,
+  static void initialize();
+  static void destroy();
+  static void registerNotify(int screen, StyleNotify *n);
+  static void unregisterNotify(int screen, StyleNotify *n);
+  static RenderStyle *style(int screen);
+  
+  enum Justify {
+    LeftTopJustify,
+    RightBottomJustify,
     CenterJustify
   };
 
@@ -61,7 +78,7 @@ private:
   RenderTexture *_grip_unfocus;
 
   Font *_label_font;
-  TextJustify _label_justify;
+  Justify _label_justify;
 
   PixmapMask *_max_mask;
   PixmapMask *_icon_mask;
@@ -120,7 +137,7 @@ public:
   inline RenderTexture *gripUnfocusBackground() const { return _grip_unfocus; }
 
   inline Font *labelFont() const { return _label_font; }
-  inline TextJustify labelTextJustify() const { return _label_justify; }
+  inline Justify labelTextJustify() const { return _label_justify; }
 
   inline PixmapMask *maximizeMask() const { return _max_mask; }
   inline PixmapMask *iconifyMask() const { return _icon_mask; }
index 087f4efdcfb5d301e18eaf10d3dfbad64cdca5b8..560a56362a6edd164284c9d2b7de723da29947e9 100644 (file)
@@ -22,8 +22,8 @@ ScreenInfo::ScreenInfo(unsigned int num) {
 
   _root_window = RootWindow(**display, _screen);
 
-  _rect.setSize(WidthOfScreen(ScreenOfDisplay(**display,
-                                              _screen)),
+  _size = Size(WidthOfScreen(ScreenOfDisplay(**display,
+                                             _screen)),
                HeightOfScreen(ScreenOfDisplay(**display,
                                               _screen)));
   /*
index f523d23be64ef9ff5306f009cbe4fd5d1c4e0f7d..440573aa80058325df8c5afe18a64742769f6ff0 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef   __screeninfo_hh
 #define   __screeninfo_hh
 
+#include "size.hh"
 #include "rect.hh"
 
 extern "C" {
@@ -9,6 +10,7 @@ extern "C" {
 }
 
 #include <string>
+#include <vector>
 
 namespace otk {
 
@@ -21,9 +23,9 @@ private:
   int _depth;
   unsigned int _screen;
   std::string _display_string;
-  Rect _rect;
+  Size _size;
 #ifdef XINERAMA
-  RectList _xinerama_areas;
+  std::vector<Rect> _xinerama_areas;
   bool _xinerama_active;
 #endif
 
@@ -35,12 +37,11 @@ public:
   inline Colormap colormap() const { return _colormap; }
   inline int depth() const { return _depth; }
   inline unsigned int screen() const { return _screen; }
-  inline const Rect& rect() const { return _rect; }
-  inline unsigned int width() const { return _rect.width(); }
-  inline unsigned int height() const { return _rect.height(); }
+  inline const Size& size() const { return _size; }
   inline const std::string& displayString() const { return _display_string; }
 #ifdef XINERAMA
-  inline const RectList &xineramaAreas() const { return _xinerama_areas; }
+  inline const std::vector<Rect> &xineramaAreas() const
+    { return _xinerama_areas; }
   inline bool isXineramaActive() const { return _xinerama_active; }
 #endif
 };
index 9dfb88898043faaac22541e4060c4bbb03e63649..aabbf85af8bc4d9042734367f6e8d666cbc6fc06 100644 (file)
@@ -15,7 +15,7 @@ extern "C" {
 
 namespace otk {
 
-Surface::Surface(int screen, const Point &size)
+Surface::Surface(int screen, const Size &size)
   : _screen(screen),
     _size(size),
     _pixmap(None),
@@ -34,19 +34,19 @@ void Surface::setPixmap(const RenderColor &color)
     createObjects();
 
   XFillRectangle(**display, _pixmap, color.gc(), 0, 0,
-                 _size.x(), _size.y());
+                 _size.width(), _size.height());
 }
 
 void Surface::setPixmap(XImage *image)
 {
-  assert(image->width == _size.x());
-  assert(image->height == _size.y());
+  assert((unsigned)image->width == _size.width());
+  assert((unsigned)image->height == _size.height());
   
   if (_pixmap == None)
     createObjects();
 
   XPutImage(**display, _pixmap, DefaultGC(**display, _screen),
-            image, 0, 0, 0, 0, _size.x(), _size.y());
+            image, 0, 0, 0, 0, _size.width(), _size.height());
 }
 
 void Surface::createObjects()
@@ -56,7 +56,7 @@ void Surface::createObjects()
   const ScreenInfo *info = display->screenInfo(_screen);
   
   _pixmap = XCreatePixmap(**display, info->rootWindow(),
-                          _size.x(), _size.y(), info->depth());
+                          _size.width(), _size.height(), info->depth());
   assert(_pixmap != None);
     
   _xftdraw = XftDrawCreate(**display, _pixmap,
index 112bb39233f74ba30b50403b69239357e910c8f8..7a202491f188392b5e0f5d7e354bf2ea6f6febb2 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef __surface_hh
 #define __surface_hh
 
-#include "point.hh"
+#include "size.hh"
 #include "truerendercontrol.hh"
 #include "pseudorendercontrol.hh"
 
@@ -19,7 +19,7 @@ class RenderColor;
 
 class Surface {
   int _screen;
-  Point _size;
+  Size _size;
   Pixmap _pixmap;
   XftDraw *_xftdraw;
 
@@ -31,14 +31,12 @@ protected:
   void setPixmap(const RenderColor &color);
   
 public:
-  Surface(int screen, const Point &size);
+  Surface(int screen, const Size &size);
   virtual ~Surface();
 
   inline int screen(void) const { return _screen; }
 
-  virtual const Point& size() const { return _size; }
-  virtual int width() const { return _size.x(); }
-  virtual int height() const { return _size.y(); }
+  virtual const Size& size() const { return _size; }
 
   virtual Pixmap pixmap() const { return _pixmap; }
 
index 5e9f318817de214fdbf659b6b9ff3d098932c9a5..2c7c42a4188381b21d60cf91ca9b9fb7fef8a977 100644 (file)
@@ -59,13 +59,14 @@ void TrueRenderControl::drawGradientBackground(
      Surface &sf, const RenderTexture &texture) const
 {
   unsigned int r,g,b;
-  int w = sf.width(), h = sf.height(), off, x;
+  unsigned int w = sf.size().width(), h = sf.size().height();
+  unsigned int off, x;
 
   const ScreenInfo *info = display->screenInfo(_screen);
   XImage *im = XCreateImage(**display, info->visual(), info->depth(),
                             ZPixmap, 0, NULL, w, h, 32, 0);
   im->byte_order = endian;
-  pixel32 *data = new pixel32[sf.height()*sf.width()];
+  pixel32 *data = new pixel32[h*w];
   pixel32 current;
 
   switch (texture.gradient()) {
@@ -101,25 +102,29 @@ void TrueRenderControl::drawGradientBackground(
 
   if (texture.relief() != RenderTexture::Flat) {
     if (texture.bevel() == RenderTexture::Bevel1) {
-      for (off = 1, x = 1; x < w - 1; ++x, off++)
-        highlight(data + off,
-                  data + off + (h-1) * w,
-                  texture.relief()==RenderTexture::Raised);
-      for (off = 0, x = 0; x < h; ++x, off++)
-        highlight(data + off * w,
-                  data + off * w + w - 1,
-                  texture.relief()==RenderTexture::Raised);
+      if (w >= 1 && h >= 1) {
+        for (off = 1, x = 1; x < w - 1; ++x, off++)
+          highlight(data + off,
+                    data + off + (h-1) * w,
+                    texture.relief()==RenderTexture::Raised);
+        for (off = 0, x = 0; x < h; ++x, off++)
+          highlight(data + off * w,
+                    data + off * w + w - 1,
+                    texture.relief()==RenderTexture::Raised);
+      }
     }
 
     if (texture.bevel() == RenderTexture::Bevel2) {
-      for (off = 2, x = 2; x < w - 2; ++x, off++)
-        highlight(data + off + w,
-                  data + off + (h-2) * w,
-                  texture.relief()==RenderTexture::Raised);
-      for (off = 1, x = 1; x < h-1; ++x, off++)
-        highlight(data + off * w + 1,
-                  data + off * w + w - 2,
-                  texture.relief()==RenderTexture::Raised);
+      if (w >= 2 && h >= 2) {
+        for (off = 2, x = 2; x < w - 2; ++x, off++)
+          highlight(data + off + w,
+                    data + off + (h-2) * w,
+                    texture.relief()==RenderTexture::Raised);
+        for (off = 1, x = 1; x < h-1; ++x, off++)
+          highlight(data + off * w + 1,
+                    data + off * w + w - 2,
+                    texture.relief()==RenderTexture::Raised);
+      }
     }
   }
 
@@ -141,24 +146,25 @@ void TrueRenderControl::verticalGradient(Surface &sf,
   pixel32 current;
   float dr, dg, db;
   unsigned int r,g,b;
+  unsigned int w = sf.size().width(), h = sf.size().height();
 
   dr = (float)(texture.secondary_color().red() - texture.color().red());
-  dr/= (float)sf.height();
+  dr/= (float)h;
 
   dg = (float)(texture.secondary_color().green() - texture.color().green());
-  dg/= (float)sf.height();
+  dg/= (float)h;
 
   db = (float)(texture.secondary_color().blue() - texture.color().blue());
-  db/= (float)sf.height();
+  db/= (float)h;
 
-  for (int y = 0; y < sf.height(); ++y) {
+  for (unsigned int y = 0; y < h; ++y) {
     r = texture.color().red() + (int)(dr * y);
     g = texture.color().green() + (int)(dg * y);
     b = texture.color().blue() + (int)(db * y);
     current = (r << default_red_shift)
             + (g << default_green_shift)
             + (b << default_blue_shift);
-    for (int x = 0; x < sf.width(); ++x, ++data)
+    for (unsigned int x = 0; x < w; ++x, ++data)
       *data = current;
   }
 }
@@ -170,21 +176,21 @@ void TrueRenderControl::diagonalGradient(Surface &sf,
   pixel32 current;
   float drx, dgx, dbx, dry, dgy, dby;
   unsigned int r,g,b;
+  unsigned int w = sf.size().width(), h = sf.size().height();
 
-
-  for (int y = 0; y < sf.height(); ++y) {
+  for (unsigned int y = 0; y < h; ++y) {
     drx = (float)(texture.secondary_color().red() - texture.color().red());
-    dry = drx/(float)sf.height();
-    drx/= (float)sf.width();
+    dry = drx/(float)h;
+    drx/= (float)w;
 
     dgx = (float)(texture.secondary_color().green() - texture.color().green());
-    dgy = dgx/(float)sf.height();
-    dgx/= (float)sf.width();
+    dgy = dgx/(float)h;
+    dgx/= (float)w;
 
     dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
-    dby = dbx/(float)sf.height();
-    dbx/= (float)sf.width();
-    for (int x = 0; x < sf.width(); ++x, ++data) {
+    dby = dbx/(float)h;
+    dbx/= (float)w;
+    for (unsigned int x = 0; x < w; ++x, ++data) {
       r = texture.color().red() + ((int)(drx * x) + (int)(dry * y))/2;
       g = texture.color().green() + ((int)(dgx * x) + (int)(dgy * y))/2;
       b = texture.color().blue() + ((int)(dbx * x) + (int)(dby * y))/2;
@@ -203,20 +209,21 @@ void TrueRenderControl::crossDiagonalGradient(Surface &sf,
   pixel32 current;
   float drx, dgx, dbx, dry, dgy, dby;
   unsigned int r,g,b;
+  unsigned int w = sf.size().width(), h = sf.size().height();
 
-  for (int y = 0; y < sf.height(); ++y) {
+  for (unsigned int y = 0; y < h; ++y) {
     drx = (float)(texture.secondary_color().red() - texture.color().red());
-    dry = drx/(float)sf.height();
-    drx/= (float)sf.width();
+    dry = drx/(float)h;
+    drx/= (float)w;
 
     dgx = (float)(texture.secondary_color().green() - texture.color().green());
-    dgy = dgx/(float)sf.height();
-    dgx/= (float)sf.width();
+    dgy = dgx/(float)h;
+    dgx/= (float)w;
 
     dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
-    dby = dbx/(float)sf.height();
-    dbx/= (float)sf.width();
-    for (int x = sf.width(); x > 0; --x, ++data) {
+    dby = dbx/(float)h;
+    dbx/= (float)w;
+    for (int x = w; x > 0; --x, ++data) {
       r = texture.color().red() + ((int)(drx * (x-1)) + (int)(dry * y))/2;
       g = texture.color().green() + ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
       b = texture.color().blue() + ((int)(dbx * (x-1)) + (int)(dby * y))/2;
index 67535024721932b2a64a604196a295813c867242..612a252d259ad117ce5ffb30799f72762781e212 100644 (file)
 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
 
-#ifdef    HAVE_CONFIG_H
-#  include "../config.h"
-#endif // HAVE_CONFIG_H
-
+#include "config.h"
 #include "widget.hh"
 #include "display.hh"
-#include "assassin.hh"
+#include "surface.hh"
+#include "rendertexture.hh"
+#include "rendercolor.hh"
+#include "eventdispatcher.hh"
 #include "screeninfo.hh"
-#include "focuslabel.hh"
+
+#include <climits>
+#include <cassert>
 #include <algorithm>
-#include <iostream>
 
 namespace otk {
 
-Widget::Widget(Widget *parent, Direction direction)
-  : EventHandler(),
-    _dirty(false), _focused(false),
-    _parent(parent), _style(parent->style()), _direction(direction),
-    _cursor(parent->cursor()), _bevel_width(parent->bevelWidth()),
-    _ignore_config(0),
-    _visible(false), _grabbed_mouse(false),
-    _grabbed_keyboard(false), _stretchable_vert(false),
-    _stretchable_horz(false), _texture(0), _bg_pixmap(0), _bg_pixel(0),
-    _bcolor(0), _bwidth(0), _rect(0, 0, 1, 1), _screen(parent->screen()),
-    _fixed_width(false), _fixed_height(false),
+Widget::Widget(int screen, EventDispatcher *ed, Direction direction, int bevel,
+               bool overrideredir)
+  : _texture(0),
+    _screen(screen),
+    _parent(0),
+    _window(0),
+    _surface(0),
     _event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                 ExposureMask | StructureNotifyMask),
+    _alignment(RenderStyle::CenterJustify),
+    _direction(direction),
+    _max_size(UINT_MAX, UINT_MAX),
+    _visible(false),
+    _bordercolor(0),
+    _borderwidth(0),
+    _bevel(bevel),
+    _dirty(true),
+    _dispatcher(ed),
+    _ignore_config(0)
+{
+  createWindow(overrideredir);
+  _dispatcher->registerHandler(_window, this);
+}
+
+Widget::Widget(Widget *parent, Direction direction, int bevel)
+  : _texture(0),
+    _screen(parent->_screen),
+    _parent(parent),
+    _window(0),
     _surface(0),
-    _event_dispatcher(parent->eventDispatcher())
-{
-  assert(parent);
-  parent->addChild(this);
-  create();
-  _event_dispatcher->registerHandler(_window, this);
-}
-
-Widget::Widget(EventDispatcher *event_dispatcher, RenderStyle *style,
-               Direction direction, Cursor cursor, int bevel_width,
-               bool override_redirect)
-  : EventHandler(),
-    _dirty(false),_focused(false),
-    _parent(0), _style(style), _direction(direction), _cursor(cursor),
-    _bevel_width(bevel_width), _ignore_config(0), _visible(false),
-    _grabbed_mouse(false), _grabbed_keyboard(false),
-    _stretchable_vert(false), _stretchable_horz(false), _texture(0),
-    _bg_pixmap(0), _bg_pixel(0), _bcolor(0), _bwidth(0), _rect(0, 0, 1, 1),
-    _screen(style->screen()), _fixed_width(false), _fixed_height(false),
     _event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                 ExposureMask | StructureNotifyMask),
-    _surface(0),
-    _event_dispatcher(event_dispatcher)
+    _alignment(RenderStyle::CenterJustify),
+    _direction(direction),
+    _max_size(UINT_MAX, UINT_MAX),
+    _visible(false),
+    _bordercolor(0),
+    _borderwidth(0),
+    _bevel(bevel),
+    _dirty(true),
+    _dispatcher(parent->_dispatcher),
+    _ignore_config(0)
 {
-  assert(event_dispatcher);
-  assert(style);
-  create(override_redirect);
-  _event_dispatcher->registerHandler(_window, this);
+  assert(parent);
+  createWindow(false);
+  parent->addChild(this);
+  parent->layout();
+  _dispatcher->registerHandler(_window, this);
 }
 
 Widget::~Widget()
 {
-  if (_visible)
-    hide();
-
-  if (_surface)
-    delete _surface;
+  assert(_children.empty()); // this would be bad. theyd have a hanging _parent
   
-  _event_dispatcher->clearHandler(_window);
-
-  std::for_each(_children.begin(), _children.end(), PointerAssassin());
-
-  if (_parent)
-    _parent->removeChild(this);
+  if (_surface) delete _surface;
+  if (_parent) _parent->removeChild(this);
 
+  _dispatcher->clearHandler(_window);
   XDestroyWindow(**display, _window);
 }
 
-void Widget::create(bool override_redirect)
+void Widget::show(bool children)
 {
-  const ScreenInfo *scr_info = display->screenInfo(_screen);
-  Window p_window = _parent ? _parent->window() : scr_info->rootWindow();
-
-  _rect.setRect(0, 0, 1, 1); // just some initial values
-
-  XSetWindowAttributes attrib_create;
-  unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
-
-  attrib_create.background_pixmap = None;
-  attrib_create.colormap = scr_info->colormap();
-  attrib_create.event_mask = _event_mask;
-
-  if (override_redirect) {
-    create_mask |= CWOverrideRedirect;
-    attrib_create.override_redirect = true;
+  if (children) {
+    std::list<Widget*>::iterator it , end = _children.end();
+    for (it = _children.begin(); it != end; ++it)
+      (*it)->show(true);
   }
-
-  if (_cursor) {
-    create_mask |= CWCursor;
-    attrib_create.cursor = _cursor;
+  if (!_visible) {
+    _visible = true;
+    XMapWindow(**display, _window);
+    update();
   }
-
-  _window = XCreateWindow(**display, p_window, _rect.x(),
-                          _rect.y(), _rect.width(), _rect.height(), 0,
-                          scr_info->depth(), InputOutput,
-                          scr_info->visual(), create_mask, &attrib_create);
-  _ignore_config++;
 }
 
+void Widget::hide()
+{
+  if (_visible) {
+    _visible = false;
+    XUnmapWindow(**display, _window);
+    if (_parent) _parent->layout();
+  }
+} 
+
 void Widget::setEventMask(long e)
 {
   XSelectInput(**display, _window, e);
   _event_mask = e;
 }
 
-void Widget::setWidth(int w)
-{
-  assert(w > 0);
-  _fixed_width = true;  
-  setGeometry(_rect.x(), _rect.y(), w, _rect.height());
-}
-
-void Widget::setHeight(int h)
-{
-  assert(h > 0);
-  _fixed_height = true;
-  setGeometry(_rect.x(), _rect.y(), _rect.width(), h);
-}
-
-void Widget::move(const Point &to)
-{
-  move(to.x(), to.y());
-}
-
-void Widget::move(int x, int y)
+void Widget::update()
 {
-  _rect.setPos(x, y);
-  XMoveWindow(**display, _window, x, y);
-  _ignore_config++;
+  _dirty = true;
+  if (parent())
+    parent()->layout(); // relay-out us and our siblings
+  else {
+    render();
+    layout();
+  }
 }
 
-void Widget::resize(const Point &to)
+void Widget::moveresize(const Rect &r)
 {
-  resize(to.x(), to.y());
-}
+  unsigned int w, h;
+  w = std::min(std::max(r.width(), minSize().width()), maxSize().width());
+  h = std::min(std::max(r.height(), minSize().height()), maxSize().height());
 
-void Widget::resize(int w, int h)
-{
-  assert(w > 0 && h > 0);
-  _fixed_width = _fixed_height = true;
-  setGeometry(_rect.x(), _rect.y(), w, h);
-}
+  if (r.x() == area().x() && r.y() == area().y() &&
+      w == area().width() && h == area().height()) {
+    return; // no change, don't cause a big layout chain to occur!
+  }
+  
+  internal_moveresize(r.x(), r.y(), w, h);
 
-void Widget::setGeometry(const Rect &new_geom)
-{
-  setGeometry(new_geom.x(), new_geom.y(), new_geom.width(), new_geom.height());
-}
-void Widget::setGeometry(const Point &topleft, int width, int height)
-{
-  setGeometry(topleft.x(), topleft.y(), width, height);
+  update();
 }
 
-void Widget::setGeometry(int x, int y, int width, int height)
+void Widget::internal_moveresize(int x, int y, unsigned w, unsigned int h)
 {
-  _rect = Rect(x, y, width, height);
+  assert(w > 0);
+  assert(h > 0);
+  assert(_borderwidth >= 0);
   _dirty = true;
+  XMoveResizeWindow(**display, _window, x, y,
+                    w - _borderwidth * 2,
+                    h - _borderwidth * 2);
+  _ignore_config++;
 
-  // make all parents dirty too
-  Widget *p = _parent;
-  while (p) {
-    p->_dirty = true;
-    p = p->_parent;
-  }
-
-  // don't use an XMoveResizeWindow here, because it doesn't seem to move
-  // windows with StaticGravity? This works, that didn't.
-  XResizeWindow(**display, _window, width, height);
-  XMoveWindow(**display, _window, x, y);
-  _ignore_config+=2;
+  _area = Rect(x, y, w, h);
 }
 
-void Widget::show(bool recursive)
+void Widget::setAlignment(RenderStyle::Justify a)
 {
-  if (_visible)
-    return;
-
-  // make sure the internal state isn't mangled
-  if (_dirty)
-    update();
-
-  if (recursive) {
-    WidgetList::iterator it = _children.begin(), end = _children.end();
-    for (; it != end; ++it)
-      (*it)->show(recursive);
-  }
-
-  XMapWindow(**display, _window);
-  _visible = true;
+  _alignment = a;  
+  layout();
 }
-
-void Widget::hide(bool recursive)
+  
+void Widget::createWindow(bool overrideredir)
 {
-  if (! _visible)
-    return;
+  const ScreenInfo *info = display->screenInfo(_screen);
+  XSetWindowAttributes attrib;
+  unsigned long mask = CWEventMask | CWBorderPixel;
 
-  if (recursive) {
-    WidgetList::iterator it = _children.begin(), end = _children.end();
-    for (; it != end; ++it)
-      (*it)->hide();
-  }
-  
-  XUnmapWindow(**display, _window);
-  _visible = false;
-}
+  attrib.event_mask = _event_mask;
+  attrib.border_pixel = (_bordercolor ?
+                         _bordercolor->pixel():
+                         BlackPixel(**display, _screen));
 
-void Widget::focus(void)
-{
-  _focused = true;
+  if (overrideredir) {
+    mask |= CWOverrideRedirect;
+    attrib.override_redirect = true;
+  }
   
-  Widget::WidgetList::iterator it = _children.begin(),
-    end = _children.end();
-  for (; it != end; ++it)
-    (*it)->focus();
-}
-
-void Widget::unfocus(void)
-{
-  _focused = false;
+  _window = XCreateWindow(**display, (_parent ?
+                                      _parent->_window :
+                                      RootWindow(**display, _screen)),
+                          _area.x(), _area.y(),
+                          _area.width(), _area.height(),
+                          _borderwidth,
+                          info->depth(),
+                          InputOutput,
+                          info->visual(),
+                          mask,
+                          &attrib);
+  assert(_window != None);
+  ++_ignore_config;
+}
+
+void Widget::setBorderWidth(int w)
+{
+  assert(w >= 0);
+  if (!parent()) return; // top-level windows cannot have borders
+  if (w == borderWidth()) return; // no change
   
-  Widget::WidgetList::iterator it = _children.begin(),
-    end = _children.end();
-  for (; it != end; ++it)
-    (*it)->unfocus();
-}
+  _borderwidth = w;
+  XSetWindowBorderWidth(**display, _window, _borderwidth);
 
-bool Widget::grabMouse(void)
-{
-  Status ret = XGrabPointer(**display, _window, True,
-                            (ButtonPressMask | ButtonReleaseMask |
-                             ButtonMotionMask | EnterWindowMask |
-                             LeaveWindowMask | PointerMotionMask),
-                            GrabModeSync, GrabModeAsync, None, None,
-                            CurrentTime);
-  _grabbed_mouse = (ret == GrabSuccess);
-  return _grabbed_mouse;
+  calcDefaultSizes();
+  update();
 }
 
-void Widget::ungrabMouse(void)
+void Widget::setMinSize(const Size &s)
 {
-  if (! _grabbed_mouse)
-    return;
-
-  XUngrabPointer(**display, CurrentTime);
-  _grabbed_mouse = false;
+  _min_size = s;
+  update();
 }
 
-bool Widget::grabKeyboard(void)
+void Widget::setMaxSize(const Size &s)
 {
-  Status ret = XGrabKeyboard(**display, _window, True,
-                             GrabModeSync, GrabModeAsync, CurrentTime);
-  _grabbed_keyboard = (ret == GrabSuccess);
-  return _grabbed_keyboard;
-
+  _max_size = s;
+  update();
 }
 
-void Widget::ungrabKeyboard(void)
+void Widget::setBorderColor(const RenderColor *c)
 {
-  if (! _grabbed_keyboard)
-    return;
-
-  XUngrabKeyboard(**display, CurrentTime);
-  _grabbed_keyboard = false;
+  _bordercolor = c;
+  XSetWindowBorder(**otk::display, _window,
+                   c ? c->pixel() : BlackPixel(**otk::display, _screen));
 }
 
-void Widget::render(void)
+void Widget::setBevel(int b)
 {
-  if (!_texture) {
-    XSetWindowBackgroundPixmap(**display, _window, ParentRelative);
-    return;
-  }
-
-  Surface *s = _surface; // save the current surface
-  
-  _surface = new Surface(_screen, _rect.size());
-  display->renderControl(_screen)->drawBackground(*_surface, *_texture);
-
-  renderForeground(); // for inherited types to render onto the _surface
-
-  XSetWindowBackgroundPixmap(**display, _window, _surface->pixmap());
-
-  if (s)
-    delete s; // delete the old surface *after* its pixmap isn't in use anymore
+  _bevel = b;
+  calcDefaultSizes();
+  layout();
 }
 
-void Widget::adjust(void)
+void Widget::layout()
 {
   if (_direction == Horizontal)
-    adjustHorz();
+    layoutHorz();
   else
-    adjustVert();
+    layoutVert();
 }
 
-void Widget::adjustHorz(void)
+void Widget::layoutHorz()
 {
-  if (_children.size() == 0)
-    return;
-
-  Widget *tmp;
-  WidgetList::iterator it, end = _children.end();
-
-  int tallest = 0;
-  int width = _bevel_width;
-  WidgetList stretchable;
-
-  for (it = _children.begin(); it != end; ++it) {
-    tmp = *it;
-    if (tmp->isStretchableVert())
-      tmp->setHeight(_rect.height() > _bevel_width * 2 ?
-                     _rect.height() - _bevel_width * 2 : _bevel_width);
-    if (tmp->isStretchableHorz())
-      stretchable.push_back(tmp);
-    else
-      width += tmp->_rect.width() + _bevel_width;
-
-    if (tmp->_rect.height() > tallest)
-      tallest = tmp->_rect.height();
-  }
-
-  if (stretchable.size() > 0) {
-    WidgetList::iterator str_it = stretchable.begin(),
-      str_end = stretchable.end();
+  std::list<Widget*>::iterator it, end;
 
-    int str_width = _rect.width() - width / stretchable.size();
-
-    for (; str_it != str_end; ++str_it)
-      (*str_it)->setWidth(str_width > _bevel_width ? str_width - _bevel_width
-                          : _bevel_width);
+  // work with just the visible children
+  std::list<Widget*> visible = _children;
+  for (it = visible.begin(), end = visible.end(); it != end;) {
+    std::list<Widget*>::iterator next = it; ++next;
+    if (!(*it)->visible())
+      visible.erase(it);
+    it = next;
   }
 
-  Widget *prev_widget = 0;
-
-  for (it = _children.begin(); it != end; ++it) {
-    tmp = *it;
-    int x, y;
+  if (visible.empty()) return;
 
-    if (prev_widget)
-      x = prev_widget->_rect.x() + prev_widget->_rect.width() + _bevel_width;
-    else
-      x = _bevel_width;
-    y = (tallest - tmp->_rect.height()) / 2 + _bevel_width;
-
-    tmp->move(x, y);
+  if ((unsigned)(_borderwidth * 2 + _bevel * 2) > _area.width() ||
+      (unsigned)(_borderwidth * 2 + _bevel * 2) > _area.height())
+    return; // not worth laying anything out!
+  
+  int x, y; unsigned int w, h; // working area
+  x = y = _bevel;
+  w = _area.width() - _borderwidth * 2 - _bevel * 2;
+  h = _area.height() - _borderwidth * 2 - _bevel * 2;
+
+  int free = w - (visible.size() - 1) * _bevel;
+  if (free < 0) free = 0;
+  unsigned int each;
+  
+  std::list<Widget*> adjustable = visible;
+
+  // find the 'free' space, and how many children will be using it
+  for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+    std::list<Widget*>::iterator next = it; ++next;
+    free -= (*it)->minSize().width();
+    if (free < 0) free = 0;
+    if ((*it)->maxSize().width() - (*it)->minSize().width() <= 0)
+      adjustable.erase(it);
+    it = next;
+  }
+  // some widgets may have max widths that restrict them, find the 'true'
+  // amount of free space after these widgets are not included
+  if (!adjustable.empty()) {
+    do {
+      each = free / adjustable.size();
+      for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+        std::list<Widget*>::iterator next = it; ++next;
+        unsigned int m = (*it)->maxSize().width() - (*it)->minSize().width();
+        if (m > 0 && m < each) {
+          free -= m;
+          if (free < 0) free = 0;
+          adjustable.erase(it);
+          break; // if one is found to be fixed, then the free space needs to
+                 // change, and the rest need to be reexamined
+        }
+        it = next;
+      }
+    } while (it != end && !adjustable.empty());
+  }
 
-    prev_widget = tmp;
+  // place/size the widgets
+  if (!adjustable.empty())
+    each = free / adjustable.size();
+  else
+    each = 0;
+  for (it = visible.begin(), end = visible.end(); it != end; ++it) {
+    unsigned int w;
+    // is the widget adjustable?
+    std::list<Widget*>::const_iterator
+      found = std::find(adjustable.begin(), adjustable.end(), *it);
+    if (found != adjustable.end()) {
+      // adjustable
+      w = (*it)->minSize().width() + each;
+    } else {
+      // fixed
+      w = (*it)->minSize().width();
+    }
+    // align it vertically
+    int yy = y;
+    unsigned int hh = std::max(std::min(h, (*it)->_max_size.height()),
+                               (*it)->_min_size.height());
+    if (hh < h) {
+      switch(_alignment) {
+      case RenderStyle::RightBottomJustify:
+        yy += h - hh;
+        break;
+      case RenderStyle::CenterJustify:
+        yy += (h - hh) / 2;
+        break;
+      case RenderStyle::LeftTopJustify:
+        break;
+      }
+    }
+    (*it)->internal_moveresize(x, yy, w, hh);
+    (*it)->render();
+    (*it)->layout();
+    x += w + _bevel;
   }
-  internalResize(width, tallest + _bevel_width * 2);
 }
 
-void Widget::adjustVert(void)
+void Widget::layoutVert()
 {
-  if (_children.size() == 0)
-    return;
-
-  Widget *tmp;
-  WidgetList::iterator it, end = _children.end();
-
-  int widest = 0;
-  int height = _bevel_width;
-  WidgetList stretchable;
-
-  for (it = _children.begin(); it != end; ++it) {
-    tmp = *it;
-    if (tmp->isStretchableHorz())
-      tmp->setWidth(_rect.width() > _bevel_width * 2 ?
-                    _rect.width() - _bevel_width * 2 : _bevel_width);
-    if (tmp->isStretchableVert())
-      stretchable.push_back(tmp);
-    else
-      height += tmp->_rect.height() + _bevel_width;
-
-    if (tmp->_rect.width() > widest)
-      widest = tmp->_rect.width();
-  }
-
-  if (stretchable.size() > 0) {
-    WidgetList::iterator str_it = stretchable.begin(),
-      str_end = stretchable.end();
+  std::list<Widget*>::iterator it, end;
 
-    int str_height = _rect.height() - height / stretchable.size();
-
-    for (; str_it != str_end; ++str_it)
-      (*str_it)->setHeight(str_height > _bevel_width ?
-                           str_height - _bevel_width : _bevel_width);
+  // work with just the visible children
+  std::list<Widget*> visible = _children;
+  for (it = visible.begin(), end = visible.end(); it != end;) {
+    std::list<Widget*>::iterator next = it; ++next;
+    if (!(*it)->visible())
+      visible.erase(it);
+    it = next;
   }
-  if (stretchable.size() > 0)
-    height = _rect.height();
-
-  Widget *prev_widget = 0;
-
-  for (it = _children.begin(); it != end; ++it) {
-    tmp = *it;
-    int x, y;
-
-    if (prev_widget)
-      y = prev_widget->_rect.y() + prev_widget->_rect.height() + _bevel_width;
-    else
-      y = _bevel_width;
-    x = (widest - tmp->_rect.width()) / 2 + _bevel_width;
 
-    tmp->move(x, y);
+  if (visible.empty()) return;
 
-    prev_widget = tmp;
+  if ((unsigned)(_borderwidth * 2 + _bevel * 2) > _area.width() ||
+      (unsigned)(_borderwidth * 2 + _bevel * 2) > _area.height())
+    return; // not worth laying anything out!
+  
+  int x, y; unsigned int w, h; // working area
+  x = y = _bevel;
+  w = _area.width() - _borderwidth * 2 - _bevel * 2;
+  h = _area.height() - _borderwidth * 2 - _bevel * 2;
+
+  int free = h - (visible.size() - 1) * _bevel;
+  if (free < 0) free = 0;
+  unsigned int each;
+
+  std::list<Widget*> adjustable = visible;
+
+  // find the 'free' space, and how many children will be using it
+  for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+    std::list<Widget*>::iterator next = it; ++next;
+    free -= (*it)->minSize().height();
+    if (free < 0) free = 0;
+    if ((*it)->maxSize().height() - (*it)->minSize().height() <= 0)
+      adjustable.erase(it);
+    it = next;
   }
-
-  internalResize(widest + _bevel_width * 2, height);
-}
-
-void Widget::update()
-{
-  WidgetList::iterator it = _children.begin(), end = _children.end();
-  for (; it != end; ++it)
-    (*it)->update();
-
-  if (_dirty) {
-    adjust();
-    render();
-    XClearWindow(**display, _window);
+  // some widgets may have max heights that restrict them, find the 'true'
+  // amount of free space after these widgets are not included
+  if (!adjustable.empty()) {
+    do {
+      each = free / adjustable.size();
+      for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+        std::list<Widget*>::iterator next = it; ++next;
+        unsigned int m = (*it)->maxSize().height() - (*it)->minSize().height();
+        if (m > 0 && m < each) {
+          free -= m;
+          if (free < 0) free = 0;
+          adjustable.erase(it);
+          break; // if one is found to be fixed, then the free space needs to
+                 // change, and the rest need to be reexamined
+        }
+        it = next;
+      }
+    } while (it != end && !adjustable.empty());
   }
 
-  _dirty = false;
+  // place/size the widgets
+  if (!adjustable.empty())
+  each = free / adjustable.size();
+  else
+    each = 0;
+  for (it = visible.begin(), end = visible.end(); it != end; ++it) {
+    unsigned int h;
+    // is the widget adjustable?
+    std::list<Widget*>::const_iterator
+      found = std::find(adjustable.begin(), adjustable.end(), *it);
+    if (found != adjustable.end()) {
+      // adjustable
+      h = (*it)->minSize().height() + each;
+    } else {
+      // fixed
+      h = (*it)->minSize().height();
+    }
+    // align it horizontally
+    int xx = x;
+    unsigned int ww = std::max(std::min(w, (*it)->_max_size.width()),
+                               (*it)->_min_size.width());
+    if (ww < w) {
+      switch(_alignment) {
+      case RenderStyle::RightBottomJustify:
+        xx += w - ww;
+        break;
+      case RenderStyle::CenterJustify:
+        xx += (w - ww) / 2;
+        break;
+      case RenderStyle::LeftTopJustify:
+        break;
+      }
+    }
+    (*it)->internal_moveresize(xx, y, ww, h);
+    (*it)->render();
+    (*it)->layout();
+    y += h + _bevel; 
+  }
 }
 
-void Widget::internalResize(int w, int h)
+void Widget::render()
 {
-  assert(w > 0 && h > 0);
-
-  bool fw = _fixed_width, fh = _fixed_height;
+  if (!_texture || !_dirty) return;
+  if ((unsigned)_borderwidth * 2 > _area.width() ||
+      (unsigned)_borderwidth * 2 > _area.height())
+    return; // no surface to draw on
   
-  if (! fw && ! fh)
-    resize(w, h);
-  else if (! fw)
-    resize(w, _rect.height());
-  else if (! fh)
-    resize(_rect.width(), h);
-
-  _fixed_width = fw;
-  _fixed_height = fh;
-}
+  Surface *s = new Surface(_screen, Size(_area.width() - _borderwidth * 2,
+                                         _area.height() - _borderwidth * 2));
+  display->renderControl(_screen)->drawBackground(*s, *_texture);
 
-void Widget::addChild(Widget *child, bool front)
-{
-  assert(child);
-  if (front)
-    _children.push_front(child);
-  else
-    _children.push_back(child);
-}
+  renderForeground(*s); // for inherited types to render onto the _surface
 
-void Widget::removeChild(Widget *child)
-{
-  assert(child);
-  WidgetList::iterator it, end = _children.end();
-  for (it = _children.begin(); it != end; ++it) {
-    if ((*it) == child)
-      break;
-  }
+  XSetWindowBackgroundPixmap(**display, _window, s->pixmap());
+  XClearWindow(**display, _window);
 
-  if (it != _children.end())
-    _children.erase(it);
-}
+  // delete the old surface *after* its pixmap isn't in use anymore
+  if (_surface) delete _surface;
 
-void Widget::setStyle(RenderStyle *style)
-{
-  assert(style);
-  _style = style;
-  _dirty = true;
+  _surface = s;
 
-  WidgetList::iterator it, end = _children.end();
-  for (it = _children.begin(); it != end; ++it)
-    (*it)->setStyle(style);
+  _dirty = false;
 }
 
-
-void Widget::setEventDispatcher(EventDispatcher *disp)
+void Widget::renderChildren()
 {
-  if (_event_dispatcher)
-    _event_dispatcher->clearHandler(_window);
-  _event_dispatcher = disp;
-  _event_dispatcher->registerHandler(_window, this);
+  std::list<Widget*>::iterator it, end = _children.end();
+  for (it = _children.begin(); it != end; ++it)
+    (*it)->render();
 }
 
 void Widget::exposeHandler(const XExposeEvent &e)
 {
   EventHandler::exposeHandler(e);
-//  XClearArea(**display, _window, e.x, e.y, e.width, e.height, false);
+  XClearArea(**display, _window, e.x, e.y, e.width, e.height, false);
 }
 
 void Widget::configureHandler(const XConfigureEvent &e)
 {
-  EventHandler::configureHandler(e);
-
   if (_ignore_config) {
     _ignore_config--;
   } else {
-    int width = e.width;
-    int height = e.height;
-
     XEvent ev;
-    while (XCheckTypedWindowEvent(**display, _window, ConfigureNotify, &ev)) {
-      width = ev.xconfigure.width;
-      height = ev.xconfigure.height;
-    }
-
-    if (!(width == _rect.width() && height == _rect.height())) {
-      _dirty = true;
-      _rect.setSize(width, height);
+    ev.xconfigure.width = e.width;
+    ev.xconfigure.height = e.height;
+    while (XCheckTypedWindowEvent(**display, window(), ConfigureNotify, &ev));
+
+    if (!((unsigned)ev.xconfigure.width == area().width() &&
+          (unsigned)ev.xconfigure.height == area().height())) {
+      _area = Rect(_area.position(), Size(e.width, e.height));
+      update();
     }
-    update();
   }
 }
 
index 3427e6814942d5a6ee8092ddb973f29fdb5d55db..2e4de47e1adb503e929f852ea82c18060eefdea6 100644 (file)
 #ifndef __widget_hh
 #define __widget_hh
 
+#include "eventhandler.hh"
 #include "rect.hh"
-#include "point.hh"
-#include "rendertexture.hh"
 #include "renderstyle.hh"
-#include "eventdispatcher.hh"
-#include "display.hh"
-#include "surface.hh"
 
-extern "C" {
-#include <assert.h>
-}
-
-#include <string>
 #include <list>
+#include <algorithm>
+#include <cassert>
 
 namespace otk {
 
-class Widget : public EventHandler {
+class Surface;
+class RenderTexture;
+class RenderColor;
+class EventDispatcher;
 
+class Widget : public EventHandler, public StyleNotify {
 public:
-
   enum Direction { Horizontal, Vertical };
 
-  typedef std::list<Widget *> WidgetList;
-
-  Widget(Widget *parent, Direction = Horizontal);
-  Widget(EventDispatcher *event_dispatcher, RenderStyle *style,
-         Direction direction = Horizontal, Cursor cursor = 0,
-         int bevel_width = 1, bool override_redirect = false);
-
+  Widget(int screen, EventDispatcher *ed, Direction direction = Horizontal,
+         int bevel = 3, bool overrideredir = false);
+  Widget(Widget *parent, Direction direction = Horizontal, int bevel = 3);
   virtual ~Widget();
 
-  virtual void update();
-
-  void exposeHandler(const XExposeEvent &e);
-  void configureHandler(const XConfigureEvent &e);
-
-  inline Window window(void) const { return _window; }
-  inline const Widget *parent(void) const { return _parent; }
-  inline const WidgetList &children(void) const { return _children; }
-  inline unsigned int screen(void) const { return _screen; }
-  inline const Rect &rect(void) const { return _rect; }
-
-  void move(const Point &to);
-  void move(int x, int y);
-
-  virtual void setWidth(int);
-  virtual void setHeight(int);
-
-  virtual int width() const { return _rect.width(); }
-  virtual int height() const { return _rect.height(); }
+  inline int screen() const { return _screen; }
+  inline Window window() const { return _window; }
+  inline Widget *parent() const { return _parent; }
+  inline Direction direction() const { return _direction; }
 
-  virtual void resize(const Point &to);
-  virtual void resize(int x, int y);
+  inline RenderStyle::Justify alignment() const { return _alignment; }
+  void setAlignment(RenderStyle::Justify a);
 
-  virtual void setGeometry(const Rect &new_geom);
-  virtual void setGeometry(const Point &topleft, int width, int height);
-  virtual void setGeometry(int x, int y, int width, int height);
-
-  inline bool isVisible(void) const { return _visible; };
-  virtual void show(bool recursive = false);
-  virtual void hide(bool recursive = false);
-
-  inline bool isFocused(void) const { return _focused; };
-  virtual void focus(void);
-  virtual void unfocus(void);
-
-  inline bool hasGrabbedMouse(void) const { return _grabbed_mouse; }
-  bool grabMouse(void);
-  void ungrabMouse(void);
-
-  inline bool hasGrabbedKeyboard(void) const { return _grabbed_keyboard; }
-  bool grabKeyboard(void);
-  void ungrabKeyboard(void);
-
-  inline RenderTexture *texture(void) const { return _texture; }
-  virtual void setTexture(RenderTexture *texture)
-    { _texture = texture; _dirty = true; }
+  inline long eventMask() const { return _event_mask; }
+  virtual void setEventMask(long e);
+  
+  inline const Rect& area() const { return _area; }
+  inline Rect usableArea() const { return Rect(_area.position(),
+                                               Size(_area.width() -
+                                                    _borderwidth * 2,
+                                                    _area.height() -
+                                                    _borderwidth * 2));}
+  inline const Size& minSize() const { return _min_size; }
+  inline const Size& maxSize() const { return _max_size; }
+  virtual void setMaxSize(const Size &s);
+
+  virtual void show(bool children = false);
+  virtual void hide();
+  inline bool visible() const { return _visible; }
 
-  inline const RenderColor *borderColor(void) const { return _bcolor; }
-  virtual void setBorderColor(const RenderColor *color) {
-    assert(color); _bcolor = color;
-    XSetWindowBorder(**display, _window, color->pixel());
-  }
+  virtual void update();
+  virtual void refresh() { _dirty = true; render(); }
+  
+  virtual void setBevel(int b);
+  inline int bevel() const { return _bevel; }
 
-  inline int borderWidth(void) const { return _bwidth; }
-  void setBorderWidth(int width) {
-    _bwidth = width;
-    XSetWindowBorderWidth(**display, _window, width);
-  }
+  void move(const Point &p)
+    { moveresize(Rect(p, _area.size())); }
+  void resize(const Size &s)
+    { moveresize(Rect(_area.position(), s)); }
+  /*!
+    When a widget has a parent, this won't change the widget directly, but will
+    just cause the parent to re-layout all its children.
+  */
+  virtual void moveresize(const Rect &r);
 
-  virtual void addChild(Widget *child, bool front = false);
-  virtual void removeChild(Widget *child);
+  inline const RenderColor *borderColor() const { return _bordercolor; }
+  virtual void setBorderColor(const RenderColor *c);
 
-  inline bool isStretchableHorz(void) const { return _stretchable_horz; }
-  void setStretchableHorz(bool s_horz = true) { _stretchable_horz = s_horz; }
+  inline int borderWidth() const { return _borderwidth; }
+  virtual void setBorderWidth(int w);
 
-  inline bool isStretchableVert(void) const { return _stretchable_vert; }
-  void setStretchableVert(bool s_vert = true)  { _stretchable_vert = s_vert; }
+  const std::list<Widget*>& children() const { return _children; }
 
-  inline Cursor cursor(void) const { return _cursor; }
-  void setCursor(Cursor cursor) {
-    _cursor = cursor;
-    XDefineCursor(**display, _window, _cursor);
-  }
+  virtual void exposeHandler(const XExposeEvent &e);
+  virtual void configureHandler(const XConfigureEvent &e);
+  virtual void styleChanged(const RenderStyle &) {calcDefaultSizes();update();}
 
-  inline int bevelWidth(void) const { return _bevel_width; }
-  void setBevelWidth(int bevel_width)
-    { assert(bevel_width > 0); _bevel_width = bevel_width; }
+protected:
+  virtual void addChild(Widget *w) { assert(w); _children.push_back(w); }
+  virtual void removeChild(Widget *w) { assert(w); _children.remove(w); }
 
-  inline Direction direction(void) const { return _direction; }
-  void setDirection(Direction dir) { _direction = dir; }
+  //! Find the default min/max sizes for the widget. Useful after the in-use
+  //! style has changed.
+  virtual void calcDefaultSizes() {};
 
-  inline RenderStyle *style(void) const { return _style; }
-  virtual void setStyle(RenderStyle *style);
+  virtual void setMinSize(const Size &s);
 
-  inline long eventMask(void) const { return _event_mask; }
-  void setEventMask(long e);
+  //! Arrange the widget's children
+  virtual void layout();
+  virtual void layoutHorz();
+  virtual void layoutVert();
+  virtual void render();
+  virtual void renderForeground(Surface&) {};
+  virtual void renderChildren();
 
-  inline EventDispatcher *eventDispatcher(void)
-    { return _event_dispatcher; }
-  void setEventDispatcher(EventDispatcher *disp);
+  void createWindow(bool overrideredir);
 
-protected:
+  RenderTexture *_texture;
   
-  bool _dirty;
-  bool _focused;
-
-  virtual void adjust(void);
-  virtual void create(bool override_redirect = false);
-  virtual void adjustHorz(void);
-  virtual void adjustVert(void);
-  virtual void internalResize(int width, int height);
-  virtual void render(void);
-  virtual void renderForeground() {} // for overriding
-
-  Window _window;
+private:
+  void internal_moveresize(int x, int y, unsigned w, unsigned int h);
 
+  int _screen;
   Widget *_parent;
-  WidgetList _children;
-
-  RenderStyle *_style;
+  Window _window;
+  Surface *_surface;
+  long _event_mask;
+  
+  RenderStyle::Justify _alignment;
   Direction _direction;
-  Cursor _cursor;
-  int _bevel_width;
-  int _ignore_config;
+  Rect _area;
+  //! This size is the size *inside* the border, so they won't match the
+  //! actual size of the widget
+  Size _min_size;
+  //! This size is the size *inside* the border, so they won't match the
+  //! actual size of the widget 
+  Size _max_size;
 
   bool _visible;
+  
+  const RenderColor *_bordercolor;
+  int _borderwidth;
+  int _bevel;
+  bool _dirty;
 
-  bool _grabbed_mouse;
-  bool _grabbed_keyboard;
-
-  bool _stretchable_vert;
-  bool _stretchable_horz;
-
-  RenderTexture *_texture;
-  Pixmap _bg_pixmap;
-  unsigned int _bg_pixel;
-
-  const RenderColor *_bcolor;
-  unsigned int _bwidth;
-
-  Rect _rect;
-  unsigned int _screen;
-
-  bool _fixed_width;
-  bool _fixed_height;
-
-  long _event_mask;
+  std::list<Widget*> _children;
 
-  Surface *_surface;
+  EventDispatcher *_dispatcher;
 
-  EventDispatcher *_event_dispatcher;
+  int _ignore_config;
 };
 
 }
This page took 0.093873 seconds and 4 git commands to generate.