Brand spankin new widgets for otk (Label and Button).
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.
This commit is contained in:
parent
d2df40965b
commit
99cd843fc6
28 changed files with 908 additions and 1578 deletions
|
@ -4,18 +4,17 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
|
||||||
CPPFLAGS=$(XFT_CFLAGS) @CPPFLAGS@ -DBUTTONSDIR=\"$(buttonsdir)\"
|
CPPFLAGS=$(XFT_CFLAGS) @CPPFLAGS@ -DBUTTONSDIR=\"$(buttonsdir)\"
|
||||||
|
|
||||||
#noinst_LIBRARIES=libotk.a
|
|
||||||
lib_LTLIBRARIES=libotk.la
|
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 \
|
renderstyle.cc rendercolor.cc pseudorendercontrol.cc \
|
||||||
display.cc font.cc \
|
display.cc font.cc screeninfo.cc property.cc timer.cc \
|
||||||
property.cc rect.cc screeninfo.cc \
|
eventdispatcher.cc eventhandler.cc ustring.cc \
|
||||||
timer.cc \
|
widget.cc application.cc label.cc appwidget.cc button.cc
|
||||||
util.cc widget.cc focuswidget.cc \
|
|
||||||
button.cc eventhandler.cc eventdispatcher.cc ustring.cc \
|
#focuswidget.cc focuslabel.cc
|
||||||
label.cc focuslabel.cc application.cc appwidget.cc
|
|
||||||
includeotk_HEADERS=application.hh appwidget.hh assassin.hh button.hh \
|
includeotk_HEADERS=application.hh appwidget.hh assassin.hh button.hh size.hh \
|
||||||
display.hh eventdispatcher.hh eventhandler.hh \
|
display.hh eventdispatcher.hh eventhandler.hh \
|
||||||
focuslabel.hh focuswidget.hh font.hh label.hh otk.hh \
|
focuslabel.hh focuswidget.hh font.hh label.hh otk.hh \
|
||||||
point.hh property.hh pseudorendercontrol.hh rect.hh \
|
point.hh property.hh pseudorendercontrol.hh rect.hh \
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#include "application.hh"
|
#include "application.hh"
|
||||||
#include "eventhandler.hh"
|
#include "eventhandler.hh"
|
||||||
#include "widget.hh"
|
|
||||||
#include "timer.hh"
|
#include "timer.hh"
|
||||||
#include "property.hh"
|
#include "property.hh"
|
||||||
#include "rendercolor.hh"
|
#include "rendercolor.hh"
|
||||||
|
#include "renderstyle.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
|
@ -30,17 +30,19 @@ Application::Application(int argc, char **argv)
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
|
_screen = DefaultScreen(*_display);
|
||||||
|
|
||||||
Timer::initialize();
|
Timer::initialize();
|
||||||
RenderColor::initialize();
|
RenderColor::initialize();
|
||||||
|
RenderStyle::initialize();
|
||||||
Property::initialize();
|
Property::initialize();
|
||||||
_style = new RenderStyle(DefaultScreen(*_display), ""); // XXX: get a path!
|
|
||||||
|
|
||||||
loadStyle();
|
loadStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
delete _style;
|
RenderStyle::destroy();
|
||||||
RenderColor::destroy();
|
RenderColor::destroy();
|
||||||
Timer::destroy();
|
Timer::destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "eventdispatcher.hh"
|
#include "eventdispatcher.hh"
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "renderstyle.hh"
|
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
|
@ -17,20 +16,19 @@ public:
|
||||||
Application(int argc, char **argv);
|
Application(int argc, char **argv);
|
||||||
virtual ~Application();
|
virtual ~Application();
|
||||||
|
|
||||||
|
inline int screen() const { return _screen; }
|
||||||
|
|
||||||
virtual void run(void);
|
virtual void run(void);
|
||||||
// more bummy cool functionality
|
// more bummy cool functionality
|
||||||
|
|
||||||
void setDockable(bool dockable) { _dockable = dockable; }
|
void setDockable(bool dockable) { _dockable = dockable; }
|
||||||
inline bool isDockable(void) const { return _dockable; }
|
inline bool isDockable(void) const { return _dockable; }
|
||||||
|
|
||||||
inline RenderStyle *getStyle(void) const { return _style; }
|
|
||||||
// more accessors
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadStyle(void);
|
void loadStyle(void);
|
||||||
|
|
||||||
Display _display;
|
Display _display;
|
||||||
RenderStyle *_style;
|
int _screen;
|
||||||
bool _dockable;
|
bool _dockable;
|
||||||
|
|
||||||
int _appwidget_count;
|
int _appwidget_count;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "appwidget.hh"
|
#include "appwidget.hh"
|
||||||
#include "application.hh"
|
#include "application.hh"
|
||||||
#include "property.hh"
|
#include "property.hh"
|
||||||
|
#include "renderstyle.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
@ -14,9 +15,8 @@ extern "C" {
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
AppWidget::AppWidget(Application *app, Direction direction,
|
AppWidget::AppWidget(Application *app, Direction direction, int bevel)
|
||||||
Cursor cursor, int bevel_width)
|
: Widget(app->screen(), app, direction, bevel),
|
||||||
: Widget(app, app->getStyle(), direction, cursor, bevel_width),
|
|
||||||
_application(app)
|
_application(app)
|
||||||
{
|
{
|
||||||
assert(app);
|
assert(app);
|
||||||
|
@ -26,29 +26,28 @@ AppWidget::AppWidget(Application *app, Direction direction,
|
||||||
protocols[0] = Property::atoms.wm_protocols;
|
protocols[0] = Property::atoms.wm_protocols;
|
||||||
protocols[1] = Property::atoms.wm_delete_window;
|
protocols[1] = Property::atoms.wm_delete_window;
|
||||||
XSetWMProtocols(**display, window(), protocols, 2);
|
XSetWMProtocols(**display, window(), protocols, 2);
|
||||||
|
|
||||||
setStyle(_style);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AppWidget::~AppWidget()
|
AppWidget::~AppWidget()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWidget::setStyle(RenderStyle *style)
|
void AppWidget::render()
|
||||||
{
|
{
|
||||||
Widget::setStyle(style);
|
XSetWindowBackground(**display, window(),
|
||||||
|
RenderStyle::style(screen())->
|
||||||
setTexture(style->titlebarUnfocusBackground());
|
titlebarUnfocusBackground()->color().pixel());
|
||||||
|
Widget::render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWidget::show(void)
|
void AppWidget::show()
|
||||||
{
|
{
|
||||||
Widget::show(true);
|
Widget::show(true);
|
||||||
|
|
||||||
_application->_appwidget_count++;
|
_application->_appwidget_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWidget::hide(void)
|
void AppWidget::hide()
|
||||||
{
|
{
|
||||||
Widget::hide();
|
Widget::hide();
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,13 @@ class Application;
|
||||||
class AppWidget : public Widget {
|
class AppWidget : public Widget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AppWidget(Application *app, Direction direction = Horizontal,
|
AppWidget(Application *app, Direction direction = Horizontal, int bevel = 0);
|
||||||
Cursor cursor = 0, int bevel_width = 1);
|
|
||||||
virtual ~AppWidget();
|
virtual ~AppWidget();
|
||||||
|
|
||||||
virtual void setStyle(RenderStyle *style);
|
virtual void render();
|
||||||
|
|
||||||
virtual void show(void);
|
virtual void show();
|
||||||
virtual void hide(void);
|
virtual void hide();
|
||||||
|
|
||||||
virtual void clientMessageHandler(const XClientMessageEvent &e);
|
virtual void clientMessageHandler(const XClientMessageEvent &e);
|
||||||
|
|
||||||
|
|
|
@ -9,73 +9,73 @@
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
Button::Button(Widget *parent)
|
Button::Button(Widget *parent)
|
||||||
: FocusLabel(parent), _pressed(false), _pressed_focus_tx(0),
|
: Label(parent), _default(false), _pressed(false)
|
||||||
_pressed_unfocus_tx(0), _unpr_focus_tx(0), _unpr_unfocus_tx(0)
|
|
||||||
{
|
{
|
||||||
setStyle(_style);
|
setHorizontalJustify(RenderStyle::CenterJustify);
|
||||||
|
setVerticalJustify(RenderStyle::CenterJustify);
|
||||||
|
styleChanged(*RenderStyle::style(screen()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Button::~Button()
|
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)
|
void Button::press(unsigned int mouse_button)
|
||||||
{
|
{
|
||||||
if (_pressed) return;
|
if (_pressed) return;
|
||||||
|
|
||||||
if (_pressed_unfocus_tx)
|
|
||||||
FocusWidget::setUnfocusTexture(_pressed_unfocus_tx);
|
|
||||||
if (_pressed_focus_tx)
|
|
||||||
FocusWidget::setTexture(_pressed_focus_tx);
|
|
||||||
_pressed = true;
|
_pressed = true;
|
||||||
_mouse_button = mouse_button;
|
_mouse_button = mouse_button;
|
||||||
|
|
||||||
|
styleChanged(*RenderStyle::style(screen()));
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::release(unsigned int mouse_button)
|
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;
|
_pressed = false;
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setTexture(RenderTexture *texture)
|
styleChanged(*RenderStyle::style(screen()));
|
||||||
{
|
refresh();
|
||||||
FocusWidget::setTexture(texture);
|
|
||||||
_unpr_focus_tx = texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setUnfocusTexture(RenderTexture *texture)
|
|
||||||
{
|
|
||||||
FocusWidget::setUnfocusTexture(texture);
|
|
||||||
_unpr_unfocus_tx = texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::buttonPressHandler(const XButtonEvent &e)
|
void Button::buttonPressHandler(const XButtonEvent &e)
|
||||||
{
|
{
|
||||||
|
Widget::buttonPressHandler(e);
|
||||||
press(e.button);
|
press(e.button);
|
||||||
update();
|
|
||||||
FocusWidget::buttonPressHandler(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::buttonReleaseHandler(const XButtonEvent &e)
|
void Button::buttonReleaseHandler(const XButtonEvent &e)
|
||||||
{
|
{
|
||||||
|
Widget::buttonReleaseHandler(e);
|
||||||
release(e.button);
|
release(e.button);
|
||||||
update();
|
}
|
||||||
FocusWidget::buttonReleaseHandler(e);
|
|
||||||
|
void Button::setDefault(bool d)
|
||||||
|
{
|
||||||
|
_default = d;
|
||||||
|
styleChanged(*RenderStyle::style(screen()));
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::styleChanged(const RenderStyle &style)
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,49 +2,33 @@
|
||||||
#ifndef __button_hh
|
#ifndef __button_hh
|
||||||
#define __button_hh
|
#define __button_hh
|
||||||
|
|
||||||
#include "focuslabel.hh"
|
#include "label.hh"
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
class Button : public FocusLabel {
|
class Button : public Label {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Button(Widget *parent);
|
Button(Widget *parent);
|
||||||
~Button();
|
virtual ~Button();
|
||||||
|
|
||||||
inline const RenderTexture *getPressedFocusTexture(void) const
|
virtual inline bool isDefault() const { return _default; }
|
||||||
{ return _pressed_focus_tx; }
|
virtual void setDefault(bool d);
|
||||||
void setPressedFocusTexture(RenderTexture *texture)
|
|
||||||
{ _pressed_focus_tx = texture; }
|
|
||||||
|
|
||||||
inline const RenderTexture *getPressedUnfocusTexture(void) const
|
virtual inline bool isPressed() const { return _pressed; }
|
||||||
{ return _pressed_unfocus_tx; }
|
|
||||||
void setPressedUnfocusTexture(RenderTexture *texture)
|
|
||||||
{ _pressed_unfocus_tx = texture; }
|
|
||||||
|
|
||||||
void setTexture(RenderTexture *texture);
|
virtual void press(unsigned int mouse_button);
|
||||||
void setUnfocusTexture(RenderTexture *texture);
|
virtual void release(unsigned int mouse_button);
|
||||||
|
|
||||||
inline bool isPressed(void) const { return _pressed; }
|
virtual void buttonPressHandler(const XButtonEvent &e);
|
||||||
void press(unsigned int mouse_button);
|
virtual void buttonReleaseHandler(const XButtonEvent &e);
|
||||||
void release(unsigned int mouse_button);
|
|
||||||
|
|
||||||
void buttonPressHandler(const XButtonEvent &e);
|
virtual void styleChanged(const RenderStyle &style);
|
||||||
void buttonReleaseHandler(const XButtonEvent &e);
|
|
||||||
|
|
||||||
virtual void setStyle(RenderStyle *style);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _default;
|
||||||
bool _pressed;
|
bool _pressed;
|
||||||
unsigned int _mouse_button;
|
unsigned int _mouse_button;
|
||||||
|
|
||||||
RenderTexture *_pressed_focus_tx;
|
|
||||||
RenderTexture *_pressed_unfocus_tx;
|
|
||||||
|
|
||||||
RenderTexture *_unpr_focus_tx;
|
|
||||||
RenderTexture *_unpr_unfocus_tx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
|
148
otk/label.cc
148
otk/label.cc
|
@ -5,100 +5,138 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "label.hh"
|
#include "label.hh"
|
||||||
|
#include "display.hh"
|
||||||
|
#include "rendercontrol.hh"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
Label::Label(Widget *parent)
|
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()
|
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::fitString(const std::string &str)
|
void Label::setVerticalJustify(RenderStyle::Justify j)
|
||||||
{
|
{
|
||||||
const Font *ft = style()->labelFont();
|
_justify_vert = j;
|
||||||
fitSize(ft->measureString(str), ft->height());
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Label::fitSize(int w, int h)
|
void Label::setText(const ustring &text)
|
||||||
{
|
{
|
||||||
unsigned int sidemargin = _bevel_width * 2;
|
bool utf = text.utf8();
|
||||||
resize(w + sidemargin * 2, h + _bevel_width * 2);
|
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::update()
|
void Label::setFont(const Font *f)
|
||||||
{
|
{
|
||||||
if (_dirty) {
|
_font = f;
|
||||||
int w = _rect.width(), h = _rect.height();
|
calcDefaultSizes();
|
||||||
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);
|
|
||||||
}
|
|
||||||
Widget::update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Label::calcDefaultSizes()
|
||||||
void Label::renderForeground(void)
|
|
||||||
{
|
{
|
||||||
Widget::renderForeground();
|
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;
|
||||||
|
}
|
||||||
|
setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4,
|
||||||
|
_parsedtext.size() * _font->height() + borderWidth() * 2 +
|
||||||
|
bevel() * 2));
|
||||||
|
}
|
||||||
|
|
||||||
const Font *ft = style()->labelFont();
|
void Label::styleChanged(const RenderStyle &style)
|
||||||
unsigned int sidemargin = _bevel_width * 2;
|
{
|
||||||
|
_texture = style.labelFocusBackground();
|
||||||
|
_forecolor = style.textFocusColor();
|
||||||
|
_font = style.labelFont();
|
||||||
|
Widget::styleChanged(style);
|
||||||
|
calcDefaultSizes();
|
||||||
|
}
|
||||||
|
|
||||||
ustring t = _text; // the actual text to draw
|
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
|
int x = sidemargin; // x coord for the text
|
||||||
|
|
||||||
// find a string that will fit inside the area for text
|
// find a string that will fit inside the area for text
|
||||||
int max_length = width() - sidemargin * 2;
|
ustring::size_type text_len = t.size();
|
||||||
if (max_length <= 0) {
|
unsigned int length;
|
||||||
t = ""; // can't fit anything
|
|
||||||
} else {
|
|
||||||
size_t text_len = t.size();
|
|
||||||
int length;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
t.resize(text_len);
|
t.resize(text_len);
|
||||||
length = ft->measureString(t);
|
length = _font->measureString(t);
|
||||||
} while (length > max_length && text_len-- > 0);
|
} while (length > w && text_len-- > 0);
|
||||||
|
|
||||||
|
if (text_len <= 0) continue; // won't fit anything
|
||||||
|
|
||||||
// justify the text
|
// justify the text
|
||||||
switch (style()->labelTextJustify()) {
|
switch (_justify_horz) {
|
||||||
case RenderStyle::RightJustify:
|
case RenderStyle::RightBottomJustify:
|
||||||
x += max_length - length;
|
x += w - length;
|
||||||
break;
|
break;
|
||||||
case RenderStyle::CenterJustify:
|
case RenderStyle::CenterJustify:
|
||||||
x += (max_length - length) / 2;
|
x += (w - length) / 2;
|
||||||
break;
|
break;
|
||||||
case RenderStyle::LeftJustify:
|
case RenderStyle::LeftTopJustify:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
control->drawString(surface, *_font, x, y, *_forecolor, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display->renderControl(_screen)->
|
|
||||||
drawString(*_surface, *ft, x, _bevel_width, *style()->textUnfocusColor(), t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
37
otk/label.hh
37
otk/label.hh
|
@ -3,33 +3,54 @@
|
||||||
#define __label_hh
|
#define __label_hh
|
||||||
|
|
||||||
#include "widget.hh"
|
#include "widget.hh"
|
||||||
|
#include "ustring.hh"
|
||||||
|
#include "renderstyle.hh"
|
||||||
|
#include "font.hh"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
class Label : public Widget {
|
class Label : public Widget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Label(Widget *parent);
|
Label(Widget *parent);
|
||||||
~Label();
|
virtual ~Label();
|
||||||
|
|
||||||
inline const ustring& getText(void) const { return _text; }
|
inline const ustring& getText(void) const { return _text; }
|
||||||
void setText(const ustring &text) { _text = text; _dirty = true; }
|
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);
|
virtual void calcDefaultSizes();
|
||||||
void fitSize(int w, int h);
|
|
||||||
|
|
||||||
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:
|
private:
|
||||||
//! Text to be displayed in the label
|
//! Text to be displayed in the label
|
||||||
ustring _text;
|
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
|
//! The actual text being shown, may be a subset of _text
|
||||||
ustring _drawtext;
|
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
|
//! The drawing offset for the text
|
||||||
int _drawx;
|
int _drawx;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include "eventdispatcher.hh"
|
#include "eventdispatcher.hh"
|
||||||
#include "eventhandler.hh"
|
#include "eventhandler.hh"
|
||||||
#include "widget.hh"
|
#include "widget.hh"
|
||||||
#include "focuswidget.hh"
|
|
||||||
#include "focuslabel.hh"
|
|
||||||
#include "appwidget.hh"
|
#include "appwidget.hh"
|
||||||
#include "application.hh"
|
#include "application.hh"
|
||||||
#include "assassin.hh"
|
#include "assassin.hh"
|
||||||
|
@ -17,8 +15,8 @@
|
||||||
#include "rendercolor.hh"
|
#include "rendercolor.hh"
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "font.hh"
|
#include "font.hh"
|
||||||
//#include "gccache.hh"
|
|
||||||
#include "rendercontrol.hh"
|
#include "rendercontrol.hh"
|
||||||
|
#include "size.hh"
|
||||||
#include "point.hh"
|
#include "point.hh"
|
||||||
#include "property.hh"
|
#include "property.hh"
|
||||||
#include "rect.hh"
|
#include "rect.hh"
|
||||||
|
|
|
@ -5,75 +5,30 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "application.hh"
|
#include "application.hh"
|
||||||
#include "focuswidget.hh"
|
|
||||||
#include "appwidget.hh"
|
#include "appwidget.hh"
|
||||||
|
#include "label.hh"
|
||||||
#include "button.hh"
|
#include "button.hh"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
otk::Application app(argc, argv);
|
otk::Application app(argc, argv);
|
||||||
|
|
||||||
otk::AppWidget foo(&app);
|
otk::AppWidget foo(&app, otk::Widget::Vertical, 3);
|
||||||
|
otk::Label lab(&foo);
|
||||||
|
otk::Label lab2(&foo);
|
||||||
|
otk::Button but(&foo);
|
||||||
|
otk::Button but2(&foo);
|
||||||
|
|
||||||
foo.resize(600, 500);
|
foo.resize(otk::Size(100, 150));
|
||||||
foo.setTexture(app.getStyle()->titlebarFocusBackground());
|
|
||||||
// foo.setUnfocusTexture(app.getStyle()->titlebarUnfocusBackground());
|
|
||||||
|
|
||||||
foo.setBevelWidth(2);
|
lab.setText("Hi, I'm a sexy\nlabel!!!");
|
||||||
foo.setDirection(otk::Widget::Horizontal);
|
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);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
|
|
||||||
rbutt1.setText("this is fucking tight");
|
|
||||||
rbutt2.setText("heh, WOOP");
|
|
||||||
|
|
||||||
// will recursively unfocus its children
|
|
||||||
//foo.unfocus();
|
|
||||||
|
|
||||||
foo.show();
|
foo.show();
|
||||||
|
|
||||||
|
|
32
otk/point.hh
32
otk/point.hh
|
@ -2,40 +2,22 @@
|
||||||
#ifndef __point_hh
|
#ifndef __point_hh
|
||||||
#define __point_hh
|
#define __point_hh
|
||||||
|
|
||||||
/*! @file point.hh
|
|
||||||
@brief The Point class contains an x/y pair
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
//! The Point class is an x/y coordinate or size pair
|
|
||||||
class Point {
|
class Point {
|
||||||
private:
|
int _x, _y;
|
||||||
//! The x value
|
|
||||||
int _x;
|
|
||||||
//! The y value
|
|
||||||
int _y;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructs a new Point with 0,0 values
|
|
||||||
Point() : _x(0), _y(0) {}
|
Point() : _x(0), _y(0) {}
|
||||||
//! Constructs a new Point with given values
|
|
||||||
Point(int x, int y) : _x(x), _y(y) {}
|
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
|
inline int x() const { return _x; }
|
||||||
void setX(int x) { _x = x; }
|
inline int y() const { return _y; }
|
||||||
//! Returns the x value
|
|
||||||
int x() const { return _x; }
|
|
||||||
|
|
||||||
//! Changes the y value to the new value specified
|
bool operator==(const Point &o) const { return _x == o._x && _y == o._y; }
|
||||||
void setY(int y) { _y = y; }
|
bool operator!=(const Point &o) const { return _x != o._x || _y != o._y; }
|
||||||
//! Returns the y value
|
|
||||||
int y() const { return _y; }
|
|
||||||
|
|
||||||
//! Changes the x and y values
|
|
||||||
void setPoint(int x, int y) { _x = x; _y = y; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __point_hh */
|
#endif // __point_hh
|
||||||
|
|
151
otk/rect.cc
151
otk/rect.cc
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
257
otk/rect.hh
257
otk/rect.hh
|
@ -2,255 +2,38 @@
|
||||||
#ifndef __rect_hh
|
#ifndef __rect_hh
|
||||||
#define __rect_hh
|
#define __rect_hh
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "point.hh"
|
#include "point.hh"
|
||||||
#include <vector>
|
#include "size.hh"
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
//! The Rect class defines a rectangle in the plane.
|
|
||||||
class Rect {
|
class Rect {
|
||||||
|
Point _p;
|
||||||
|
Size _s;
|
||||||
public:
|
public:
|
||||||
//! Constructs an invalid Rect
|
Rect() : _p(), _s() {}
|
||||||
inline Rect(void) : _x1(0), _y1(0), _x2(0), _y2(0) { }
|
Rect(const Point &p, const Size &s) : _p(p), _s(s) {}
|
||||||
//! Constructs a Rect
|
Rect(const Rect &r) : _p(r._p), _s(r._s) {}
|
||||||
/*!
|
Rect(int x, int y, unsigned int w, unsigned int h)
|
||||||
@param x The x component of the point defining the top left corner of the
|
: _p(x, y), _s(w, h) {}
|
||||||
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 x() const { return _p.x(); }
|
||||||
inline int left(void) const { return _x1; }
|
inline int y() const { return _p.y(); }
|
||||||
//! Returns the top coordinate of the Rect. Identical to Rect::y.
|
inline unsigned int width() const { return _s.width(); }
|
||||||
inline int top(void) const { return _y1; }
|
inline unsigned int height() const { return _s.height(); }
|
||||||
//! 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 left() const { return _p.x(); }
|
||||||
inline int x(void) const { return _x1; }
|
inline int top() const { return _p.y(); }
|
||||||
//! The y component of the point defining the top left corner of the Rect
|
inline int right() const { return _p.x() + _s.width() - 1; }
|
||||||
inline int y(void) const { return _y1; }
|
inline int bottom() const { return _p.y() + _s.height() - 1; }
|
||||||
//! 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.
|
inline const Point& position() const { return _p; }
|
||||||
/*!
|
inline const Size& size() const { return _s; }
|
||||||
@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
|
bool operator==(const Rect &o) const { return _p == o._p && _s == o._s; }
|
||||||
inline int width(void) const { return _x2 - _x1 + 1; }
|
bool operator!=(const Rect &o) const { return _p != o._p || _s != o._s; }
|
||||||
//! 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! A list for Rect objects
|
|
||||||
typedef std::vector<Rect> RectList;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __rect_hh
|
#endif // __rect_hh
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "pseudorendercontrol.hh"
|
#include "pseudorendercontrol.hh"
|
||||||
#include "rendertexture.hh"
|
#include "rendertexture.hh"
|
||||||
#include "rendercolor.hh"
|
#include "rendercolor.hh"
|
||||||
|
#include "renderstyle.hh"
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "screeninfo.hh"
|
#include "screeninfo.hh"
|
||||||
#include "surface.hh"
|
#include "surface.hh"
|
||||||
|
@ -50,15 +51,11 @@ RenderControl::RenderControl(int screen)
|
||||||
: _screen(screen)
|
: _screen(screen)
|
||||||
{
|
{
|
||||||
printf("Initializing RenderControl\n");
|
printf("Initializing RenderControl\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderControl::~RenderControl()
|
RenderControl::~RenderControl()
|
||||||
{
|
{
|
||||||
printf("Destroying RenderControl\n");
|
printf("Destroying RenderControl\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderControl::drawRoot(const RenderColor &color) const
|
void RenderControl::drawRoot(const RenderColor &color) const
|
||||||
|
@ -120,7 +117,7 @@ void RenderControl::drawSolidBackground(Surface& sf,
|
||||||
|
|
||||||
sf.setPixmap(texture.color());
|
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;
|
int left = 0, top = 0, right = width - 1, bottom = height - 1;
|
||||||
|
|
||||||
if (texture.interlaced())
|
if (texture.interlaced())
|
||||||
|
|
|
@ -8,8 +8,49 @@
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "screeninfo.hh"
|
#include "screeninfo.hh"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace otk {
|
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)
|
RenderStyle::RenderStyle(int screen, const std::string &stylefile)
|
||||||
: _screen(screen),
|
: _screen(screen),
|
||||||
_file(stylefile)
|
_file(stylefile)
|
||||||
|
@ -175,7 +216,7 @@ RenderStyle::RenderStyle(int screen, const std::string &stylefile)
|
||||||
0x0);
|
0x0);
|
||||||
|
|
||||||
_label_font = new Font(_screen, "Arial,Sans-9:bold", true, 1, 0x40);
|
_label_font = new Font(_screen, "Arial,Sans-9:bold", true, 1, 0x40);
|
||||||
_label_justify = RightJustify;
|
_label_justify = RightBottomJustify;
|
||||||
|
|
||||||
_max_mask = new PixmapMask();
|
_max_mask = new PixmapMask();
|
||||||
_max_mask->w = _max_mask->h = 8;
|
_max_mask->w = _max_mask->h = 8;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "font.hh"
|
#include "font.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
|
@ -16,11 +17,27 @@ struct PixmapMask {
|
||||||
PixmapMask() { mask = None; w = h = 0; }
|
PixmapMask() { mask = None; w = h = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class RenderStyle {
|
class RenderStyle;
|
||||||
|
|
||||||
|
class StyleNotify {
|
||||||
public:
|
public:
|
||||||
enum TextJustify {
|
//! Called when the style is changed on the same screen as the handler.
|
||||||
LeftJustify,
|
virtual void styleChanged(const RenderStyle &) {}
|
||||||
RightJustify,
|
};
|
||||||
|
|
||||||
|
class RenderStyle {
|
||||||
|
static RenderStyle **_styles;
|
||||||
|
static std::list<StyleNotify*> *_notifies;
|
||||||
|
public:
|
||||||
|
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
|
CenterJustify
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +78,7 @@ private:
|
||||||
RenderTexture *_grip_unfocus;
|
RenderTexture *_grip_unfocus;
|
||||||
|
|
||||||
Font *_label_font;
|
Font *_label_font;
|
||||||
TextJustify _label_justify;
|
Justify _label_justify;
|
||||||
|
|
||||||
PixmapMask *_max_mask;
|
PixmapMask *_max_mask;
|
||||||
PixmapMask *_icon_mask;
|
PixmapMask *_icon_mask;
|
||||||
|
@ -120,7 +137,7 @@ public:
|
||||||
inline RenderTexture *gripUnfocusBackground() const { return _grip_unfocus; }
|
inline RenderTexture *gripUnfocusBackground() const { return _grip_unfocus; }
|
||||||
|
|
||||||
inline Font *labelFont() const { return _label_font; }
|
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 *maximizeMask() const { return _max_mask; }
|
||||||
inline PixmapMask *iconifyMask() const { return _icon_mask; }
|
inline PixmapMask *iconifyMask() const { return _icon_mask; }
|
||||||
|
|
|
@ -22,7 +22,7 @@ ScreenInfo::ScreenInfo(unsigned int num) {
|
||||||
|
|
||||||
_root_window = RootWindow(**display, _screen);
|
_root_window = RootWindow(**display, _screen);
|
||||||
|
|
||||||
_rect.setSize(WidthOfScreen(ScreenOfDisplay(**display,
|
_size = Size(WidthOfScreen(ScreenOfDisplay(**display,
|
||||||
_screen)),
|
_screen)),
|
||||||
HeightOfScreen(ScreenOfDisplay(**display,
|
HeightOfScreen(ScreenOfDisplay(**display,
|
||||||
_screen)));
|
_screen)));
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#ifndef __screeninfo_hh
|
#ifndef __screeninfo_hh
|
||||||
#define __screeninfo_hh
|
#define __screeninfo_hh
|
||||||
|
|
||||||
|
#include "size.hh"
|
||||||
#include "rect.hh"
|
#include "rect.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -9,6 +10,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
|
@ -21,9 +23,9 @@ private:
|
||||||
int _depth;
|
int _depth;
|
||||||
unsigned int _screen;
|
unsigned int _screen;
|
||||||
std::string _display_string;
|
std::string _display_string;
|
||||||
Rect _rect;
|
Size _size;
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
RectList _xinerama_areas;
|
std::vector<Rect> _xinerama_areas;
|
||||||
bool _xinerama_active;
|
bool _xinerama_active;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -35,12 +37,11 @@ public:
|
||||||
inline Colormap colormap() const { return _colormap; }
|
inline Colormap colormap() const { return _colormap; }
|
||||||
inline int depth() const { return _depth; }
|
inline int depth() const { return _depth; }
|
||||||
inline unsigned int screen() const { return _screen; }
|
inline unsigned int screen() const { return _screen; }
|
||||||
inline const Rect& rect() const { return _rect; }
|
inline const Size& size() const { return _size; }
|
||||||
inline unsigned int width() const { return _rect.width(); }
|
|
||||||
inline unsigned int height() const { return _rect.height(); }
|
|
||||||
inline const std::string& displayString() const { return _display_string; }
|
inline const std::string& displayString() const { return _display_string; }
|
||||||
#ifdef XINERAMA
|
#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; }
|
inline bool isXineramaActive() const { return _xinerama_active; }
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern "C" {
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
Surface::Surface(int screen, const Point &size)
|
Surface::Surface(int screen, const Size &size)
|
||||||
: _screen(screen),
|
: _screen(screen),
|
||||||
_size(size),
|
_size(size),
|
||||||
_pixmap(None),
|
_pixmap(None),
|
||||||
|
@ -34,19 +34,19 @@ void Surface::setPixmap(const RenderColor &color)
|
||||||
createObjects();
|
createObjects();
|
||||||
|
|
||||||
XFillRectangle(**display, _pixmap, color.gc(), 0, 0,
|
XFillRectangle(**display, _pixmap, color.gc(), 0, 0,
|
||||||
_size.x(), _size.y());
|
_size.width(), _size.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surface::setPixmap(XImage *image)
|
void Surface::setPixmap(XImage *image)
|
||||||
{
|
{
|
||||||
assert(image->width == _size.x());
|
assert((unsigned)image->width == _size.width());
|
||||||
assert(image->height == _size.y());
|
assert((unsigned)image->height == _size.height());
|
||||||
|
|
||||||
if (_pixmap == None)
|
if (_pixmap == None)
|
||||||
createObjects();
|
createObjects();
|
||||||
|
|
||||||
XPutImage(**display, _pixmap, DefaultGC(**display, _screen),
|
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()
|
void Surface::createObjects()
|
||||||
|
@ -56,7 +56,7 @@ void Surface::createObjects()
|
||||||
const ScreenInfo *info = display->screenInfo(_screen);
|
const ScreenInfo *info = display->screenInfo(_screen);
|
||||||
|
|
||||||
_pixmap = XCreatePixmap(**display, info->rootWindow(),
|
_pixmap = XCreatePixmap(**display, info->rootWindow(),
|
||||||
_size.x(), _size.y(), info->depth());
|
_size.width(), _size.height(), info->depth());
|
||||||
assert(_pixmap != None);
|
assert(_pixmap != None);
|
||||||
|
|
||||||
_xftdraw = XftDrawCreate(**display, _pixmap,
|
_xftdraw = XftDrawCreate(**display, _pixmap,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#ifndef __surface_hh
|
#ifndef __surface_hh
|
||||||
#define __surface_hh
|
#define __surface_hh
|
||||||
|
|
||||||
#include "point.hh"
|
#include "size.hh"
|
||||||
#include "truerendercontrol.hh"
|
#include "truerendercontrol.hh"
|
||||||
#include "pseudorendercontrol.hh"
|
#include "pseudorendercontrol.hh"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class RenderColor;
|
||||||
|
|
||||||
class Surface {
|
class Surface {
|
||||||
int _screen;
|
int _screen;
|
||||||
Point _size;
|
Size _size;
|
||||||
Pixmap _pixmap;
|
Pixmap _pixmap;
|
||||||
XftDraw *_xftdraw;
|
XftDraw *_xftdraw;
|
||||||
|
|
||||||
|
@ -31,14 +31,12 @@ protected:
|
||||||
void setPixmap(const RenderColor &color);
|
void setPixmap(const RenderColor &color);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Surface(int screen, const Point &size);
|
Surface(int screen, const Size &size);
|
||||||
virtual ~Surface();
|
virtual ~Surface();
|
||||||
|
|
||||||
inline int screen(void) const { return _screen; }
|
inline int screen(void) const { return _screen; }
|
||||||
|
|
||||||
virtual const Point& size() const { return _size; }
|
virtual const Size& size() const { return _size; }
|
||||||
virtual int width() const { return _size.x(); }
|
|
||||||
virtual int height() const { return _size.y(); }
|
|
||||||
|
|
||||||
virtual Pixmap pixmap() const { return _pixmap; }
|
virtual Pixmap pixmap() const { return _pixmap; }
|
||||||
|
|
||||||
|
|
|
@ -59,13 +59,14 @@ void TrueRenderControl::drawGradientBackground(
|
||||||
Surface &sf, const RenderTexture &texture) const
|
Surface &sf, const RenderTexture &texture) const
|
||||||
{
|
{
|
||||||
unsigned int r,g,b;
|
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);
|
const ScreenInfo *info = display->screenInfo(_screen);
|
||||||
XImage *im = XCreateImage(**display, info->visual(), info->depth(),
|
XImage *im = XCreateImage(**display, info->visual(), info->depth(),
|
||||||
ZPixmap, 0, NULL, w, h, 32, 0);
|
ZPixmap, 0, NULL, w, h, 32, 0);
|
||||||
im->byte_order = endian;
|
im->byte_order = endian;
|
||||||
pixel32 *data = new pixel32[sf.height()*sf.width()];
|
pixel32 *data = new pixel32[h*w];
|
||||||
pixel32 current;
|
pixel32 current;
|
||||||
|
|
||||||
switch (texture.gradient()) {
|
switch (texture.gradient()) {
|
||||||
|
@ -101,6 +102,7 @@ void TrueRenderControl::drawGradientBackground(
|
||||||
|
|
||||||
if (texture.relief() != RenderTexture::Flat) {
|
if (texture.relief() != RenderTexture::Flat) {
|
||||||
if (texture.bevel() == RenderTexture::Bevel1) {
|
if (texture.bevel() == RenderTexture::Bevel1) {
|
||||||
|
if (w >= 1 && h >= 1) {
|
||||||
for (off = 1, x = 1; x < w - 1; ++x, off++)
|
for (off = 1, x = 1; x < w - 1; ++x, off++)
|
||||||
highlight(data + off,
|
highlight(data + off,
|
||||||
data + off + (h-1) * w,
|
data + off + (h-1) * w,
|
||||||
|
@ -110,8 +112,10 @@ void TrueRenderControl::drawGradientBackground(
|
||||||
data + off * w + w - 1,
|
data + off * w + w - 1,
|
||||||
texture.relief()==RenderTexture::Raised);
|
texture.relief()==RenderTexture::Raised);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (texture.bevel() == RenderTexture::Bevel2) {
|
if (texture.bevel() == RenderTexture::Bevel2) {
|
||||||
|
if (w >= 2 && h >= 2) {
|
||||||
for (off = 2, x = 2; x < w - 2; ++x, off++)
|
for (off = 2, x = 2; x < w - 2; ++x, off++)
|
||||||
highlight(data + off + w,
|
highlight(data + off + w,
|
||||||
data + off + (h-2) * w,
|
data + off + (h-2) * w,
|
||||||
|
@ -122,6 +126,7 @@ void TrueRenderControl::drawGradientBackground(
|
||||||
texture.relief()==RenderTexture::Raised);
|
texture.relief()==RenderTexture::Raised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reduceDepth(im, data);
|
reduceDepth(im, data);
|
||||||
|
|
||||||
|
@ -141,24 +146,25 @@ void TrueRenderControl::verticalGradient(Surface &sf,
|
||||||
pixel32 current;
|
pixel32 current;
|
||||||
float dr, dg, db;
|
float dr, dg, db;
|
||||||
unsigned int r,g,b;
|
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)(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)(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)(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);
|
r = texture.color().red() + (int)(dr * y);
|
||||||
g = texture.color().green() + (int)(dg * y);
|
g = texture.color().green() + (int)(dg * y);
|
||||||
b = texture.color().blue() + (int)(db * y);
|
b = texture.color().blue() + (int)(db * y);
|
||||||
current = (r << default_red_shift)
|
current = (r << default_red_shift)
|
||||||
+ (g << default_green_shift)
|
+ (g << default_green_shift)
|
||||||
+ (b << default_blue_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;
|
*data = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,21 +176,21 @@ void TrueRenderControl::diagonalGradient(Surface &sf,
|
||||||
pixel32 current;
|
pixel32 current;
|
||||||
float drx, dgx, dbx, dry, dgy, dby;
|
float drx, dgx, dbx, dry, dgy, dby;
|
||||||
unsigned int r,g,b;
|
unsigned int r,g,b;
|
||||||
|
unsigned int w = sf.size().width(), h = sf.size().height();
|
||||||
|
|
||||||
|
for (unsigned int y = 0; y < h; ++y) {
|
||||||
for (int y = 0; y < sf.height(); ++y) {
|
|
||||||
drx = (float)(texture.secondary_color().red() - texture.color().red());
|
drx = (float)(texture.secondary_color().red() - texture.color().red());
|
||||||
dry = drx/(float)sf.height();
|
dry = drx/(float)h;
|
||||||
drx/= (float)sf.width();
|
drx/= (float)w;
|
||||||
|
|
||||||
dgx = (float)(texture.secondary_color().green() - texture.color().green());
|
dgx = (float)(texture.secondary_color().green() - texture.color().green());
|
||||||
dgy = dgx/(float)sf.height();
|
dgy = dgx/(float)h;
|
||||||
dgx/= (float)sf.width();
|
dgx/= (float)w;
|
||||||
|
|
||||||
dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
|
dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
|
||||||
dby = dbx/(float)sf.height();
|
dby = dbx/(float)h;
|
||||||
dbx/= (float)sf.width();
|
dbx/= (float)w;
|
||||||
for (int x = 0; x < sf.width(); ++x, ++data) {
|
for (unsigned int x = 0; x < w; ++x, ++data) {
|
||||||
r = texture.color().red() + ((int)(drx * x) + (int)(dry * y))/2;
|
r = texture.color().red() + ((int)(drx * x) + (int)(dry * y))/2;
|
||||||
g = texture.color().green() + ((int)(dgx * x) + (int)(dgy * y))/2;
|
g = texture.color().green() + ((int)(dgx * x) + (int)(dgy * y))/2;
|
||||||
b = texture.color().blue() + ((int)(dbx * x) + (int)(dby * y))/2;
|
b = texture.color().blue() + ((int)(dbx * x) + (int)(dby * y))/2;
|
||||||
|
@ -203,20 +209,21 @@ void TrueRenderControl::crossDiagonalGradient(Surface &sf,
|
||||||
pixel32 current;
|
pixel32 current;
|
||||||
float drx, dgx, dbx, dry, dgy, dby;
|
float drx, dgx, dbx, dry, dgy, dby;
|
||||||
unsigned int r,g,b;
|
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());
|
drx = (float)(texture.secondary_color().red() - texture.color().red());
|
||||||
dry = drx/(float)sf.height();
|
dry = drx/(float)h;
|
||||||
drx/= (float)sf.width();
|
drx/= (float)w;
|
||||||
|
|
||||||
dgx = (float)(texture.secondary_color().green() - texture.color().green());
|
dgx = (float)(texture.secondary_color().green() - texture.color().green());
|
||||||
dgy = dgx/(float)sf.height();
|
dgy = dgx/(float)h;
|
||||||
dgx/= (float)sf.width();
|
dgx/= (float)w;
|
||||||
|
|
||||||
dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
|
dbx = (float)(texture.secondary_color().blue() - texture.color().blue());
|
||||||
dby = dbx/(float)sf.height();
|
dby = dbx/(float)h;
|
||||||
dbx/= (float)sf.width();
|
dbx/= (float)w;
|
||||||
for (int x = sf.width(); x > 0; --x, ++data) {
|
for (int x = w; x > 0; --x, ++data) {
|
||||||
r = texture.color().red() + ((int)(drx * (x-1)) + (int)(dry * y))/2;
|
r = texture.color().red() + ((int)(drx * (x-1)) + (int)(dry * y))/2;
|
||||||
g = texture.color().green() + ((int)(dgx * (x-1)) + (int)(dgy * 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;
|
b = texture.color().blue() + ((int)(dbx * (x-1)) + (int)(dby * y))/2;
|
||||||
|
|
875
otk/widget.cc
875
otk/widget.cc
|
@ -1,110 +1,102 @@
|
||||||
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#include "config.h"
|
||||||
# include "../config.h"
|
|
||||||
#endif // HAVE_CONFIG_H
|
|
||||||
|
|
||||||
#include "widget.hh"
|
#include "widget.hh"
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "assassin.hh"
|
#include "surface.hh"
|
||||||
|
#include "rendertexture.hh"
|
||||||
|
#include "rendercolor.hh"
|
||||||
|
#include "eventdispatcher.hh"
|
||||||
#include "screeninfo.hh"
|
#include "screeninfo.hh"
|
||||||
#include "focuslabel.hh"
|
|
||||||
|
#include <climits>
|
||||||
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
Widget::Widget(Widget *parent, Direction direction)
|
Widget::Widget(int screen, EventDispatcher *ed, Direction direction, int bevel,
|
||||||
: EventHandler(),
|
bool overrideredir)
|
||||||
_dirty(false), _focused(false),
|
: _texture(0),
|
||||||
_parent(parent), _style(parent->style()), _direction(direction),
|
_screen(screen),
|
||||||
_cursor(parent->cursor()), _bevel_width(parent->bevelWidth()),
|
_parent(0),
|
||||||
_ignore_config(0),
|
_window(0),
|
||||||
_visible(false), _grabbed_mouse(false),
|
_surface(0),
|
||||||
_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),
|
|
||||||
_event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
_event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||||
ExposureMask | StructureNotifyMask),
|
ExposureMask | StructureNotifyMask),
|
||||||
_surface(0),
|
_alignment(RenderStyle::CenterJustify),
|
||||||
_event_dispatcher(parent->eventDispatcher())
|
_direction(direction),
|
||||||
|
_max_size(UINT_MAX, UINT_MAX),
|
||||||
|
_visible(false),
|
||||||
|
_bordercolor(0),
|
||||||
|
_borderwidth(0),
|
||||||
|
_bevel(bevel),
|
||||||
|
_dirty(true),
|
||||||
|
_dispatcher(ed),
|
||||||
|
_ignore_config(0)
|
||||||
{
|
{
|
||||||
assert(parent);
|
createWindow(overrideredir);
|
||||||
parent->addChild(this);
|
_dispatcher->registerHandler(_window, this);
|
||||||
create();
|
|
||||||
_event_dispatcher->registerHandler(_window, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Widget(EventDispatcher *event_dispatcher, RenderStyle *style,
|
Widget::Widget(Widget *parent, Direction direction, int bevel)
|
||||||
Direction direction, Cursor cursor, int bevel_width,
|
: _texture(0),
|
||||||
bool override_redirect)
|
_screen(parent->_screen),
|
||||||
: EventHandler(),
|
_parent(parent),
|
||||||
_dirty(false),_focused(false),
|
_window(0),
|
||||||
_parent(0), _style(style), _direction(direction), _cursor(cursor),
|
_surface(0),
|
||||||
_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 |
|
_event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||||
ExposureMask | StructureNotifyMask),
|
ExposureMask | StructureNotifyMask),
|
||||||
_surface(0),
|
_alignment(RenderStyle::CenterJustify),
|
||||||
_event_dispatcher(event_dispatcher)
|
_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(parent);
|
||||||
assert(style);
|
createWindow(false);
|
||||||
create(override_redirect);
|
parent->addChild(this);
|
||||||
_event_dispatcher->registerHandler(_window, this);
|
parent->layout();
|
||||||
|
_dispatcher->registerHandler(_window, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::~Widget()
|
Widget::~Widget()
|
||||||
{
|
{
|
||||||
if (_visible)
|
assert(_children.empty()); // this would be bad. theyd have a hanging _parent
|
||||||
hide();
|
|
||||||
|
|
||||||
if (_surface)
|
if (_surface) delete _surface;
|
||||||
delete _surface;
|
if (_parent) _parent->removeChild(this);
|
||||||
|
|
||||||
_event_dispatcher->clearHandler(_window);
|
|
||||||
|
|
||||||
std::for_each(_children.begin(), _children.end(), PointerAssassin());
|
|
||||||
|
|
||||||
if (_parent)
|
|
||||||
_parent->removeChild(this);
|
|
||||||
|
|
||||||
|
_dispatcher->clearHandler(_window);
|
||||||
XDestroyWindow(**display, _window);
|
XDestroyWindow(**display, _window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::create(bool override_redirect)
|
void Widget::show(bool children)
|
||||||
{
|
{
|
||||||
const ScreenInfo *scr_info = display->screenInfo(_screen);
|
if (children) {
|
||||||
Window p_window = _parent ? _parent->window() : scr_info->rootWindow();
|
std::list<Widget*>::iterator it , end = _children.end();
|
||||||
|
for (it = _children.begin(); it != end; ++it)
|
||||||
_rect.setRect(0, 0, 1, 1); // just some initial values
|
(*it)->show(true);
|
||||||
|
}
|
||||||
XSetWindowAttributes attrib_create;
|
if (!_visible) {
|
||||||
unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
|
_visible = true;
|
||||||
|
XMapWindow(**display, _window);
|
||||||
attrib_create.background_pixmap = None;
|
update();
|
||||||
attrib_create.colormap = scr_info->colormap();
|
}
|
||||||
attrib_create.event_mask = _event_mask;
|
|
||||||
|
|
||||||
if (override_redirect) {
|
|
||||||
create_mask |= CWOverrideRedirect;
|
|
||||||
attrib_create.override_redirect = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cursor) {
|
void Widget::hide()
|
||||||
create_mask |= CWCursor;
|
{
|
||||||
attrib_create.cursor = _cursor;
|
if (_visible) {
|
||||||
|
_visible = false;
|
||||||
|
XUnmapWindow(**display, _window);
|
||||||
|
if (_parent) _parent->layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
_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::setEventMask(long e)
|
void Widget::setEventMask(long e)
|
||||||
|
@ -113,411 +105,382 @@ void Widget::setEventMask(long e)
|
||||||
_event_mask = 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)
|
|
||||||
{
|
|
||||||
_rect.setPos(x, y);
|
|
||||||
XMoveWindow(**display, _window, x, y);
|
|
||||||
_ignore_config++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::resize(const Point &to)
|
|
||||||
{
|
|
||||||
resize(to.x(), to.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::resize(int w, int h)
|
|
||||||
{
|
|
||||||
assert(w > 0 && h > 0);
|
|
||||||
_fixed_width = _fixed_height = true;
|
|
||||||
setGeometry(_rect.x(), _rect.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setGeometry(int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
_rect = Rect(x, y, width, height);
|
|
||||||
_dirty = true;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::show(bool recursive)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::hide(bool recursive)
|
|
||||||
{
|
|
||||||
if (! _visible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (recursive) {
|
|
||||||
WidgetList::iterator it = _children.begin(), end = _children.end();
|
|
||||||
for (; it != end; ++it)
|
|
||||||
(*it)->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
XUnmapWindow(**display, _window);
|
|
||||||
_visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::focus(void)
|
|
||||||
{
|
|
||||||
_focused = true;
|
|
||||||
|
|
||||||
Widget::WidgetList::iterator it = _children.begin(),
|
|
||||||
end = _children.end();
|
|
||||||
for (; it != end; ++it)
|
|
||||||
(*it)->focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::unfocus(void)
|
|
||||||
{
|
|
||||||
_focused = false;
|
|
||||||
|
|
||||||
Widget::WidgetList::iterator it = _children.begin(),
|
|
||||||
end = _children.end();
|
|
||||||
for (; it != end; ++it)
|
|
||||||
(*it)->unfocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::ungrabMouse(void)
|
|
||||||
{
|
|
||||||
if (! _grabbed_mouse)
|
|
||||||
return;
|
|
||||||
|
|
||||||
XUngrabPointer(**display, CurrentTime);
|
|
||||||
_grabbed_mouse = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Widget::grabKeyboard(void)
|
|
||||||
{
|
|
||||||
Status ret = XGrabKeyboard(**display, _window, True,
|
|
||||||
GrabModeSync, GrabModeAsync, CurrentTime);
|
|
||||||
_grabbed_keyboard = (ret == GrabSuccess);
|
|
||||||
return _grabbed_keyboard;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::ungrabKeyboard(void)
|
|
||||||
{
|
|
||||||
if (! _grabbed_keyboard)
|
|
||||||
return;
|
|
||||||
|
|
||||||
XUngrabKeyboard(**display, CurrentTime);
|
|
||||||
_grabbed_keyboard = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::render(void)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::adjust(void)
|
|
||||||
{
|
|
||||||
if (_direction == Horizontal)
|
|
||||||
adjustHorz();
|
|
||||||
else
|
|
||||||
adjustVert();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::adjustHorz(void)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget *prev_widget = 0;
|
|
||||||
|
|
||||||
for (it = _children.begin(); it != end; ++it) {
|
|
||||||
tmp = *it;
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
prev_widget = tmp;
|
|
||||||
}
|
|
||||||
internalResize(width, tallest + _bevel_width * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::adjustVert(void)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
prev_widget = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
internalResize(widest + _bevel_width * 2, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::update()
|
void Widget::update()
|
||||||
{
|
{
|
||||||
WidgetList::iterator it = _children.begin(), end = _children.end();
|
_dirty = true;
|
||||||
for (; it != end; ++it)
|
if (parent())
|
||||||
(*it)->update();
|
parent()->layout(); // relay-out us and our siblings
|
||||||
|
else {
|
||||||
if (_dirty) {
|
|
||||||
adjust();
|
|
||||||
render();
|
render();
|
||||||
XClearWindow(**display, _window);
|
layout();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::moveresize(const Rect &r)
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::internal_moveresize(int x, int y, unsigned w, unsigned int h)
|
||||||
|
{
|
||||||
|
assert(w > 0);
|
||||||
|
assert(h > 0);
|
||||||
|
assert(_borderwidth >= 0);
|
||||||
|
_dirty = true;
|
||||||
|
XMoveResizeWindow(**display, _window, x, y,
|
||||||
|
w - _borderwidth * 2,
|
||||||
|
h - _borderwidth * 2);
|
||||||
|
_ignore_config++;
|
||||||
|
|
||||||
|
_area = Rect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setAlignment(RenderStyle::Justify a)
|
||||||
|
{
|
||||||
|
_alignment = a;
|
||||||
|
layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::createWindow(bool overrideredir)
|
||||||
|
{
|
||||||
|
const ScreenInfo *info = display->screenInfo(_screen);
|
||||||
|
XSetWindowAttributes attrib;
|
||||||
|
unsigned long mask = CWEventMask | CWBorderPixel;
|
||||||
|
|
||||||
|
attrib.event_mask = _event_mask;
|
||||||
|
attrib.border_pixel = (_bordercolor ?
|
||||||
|
_bordercolor->pixel():
|
||||||
|
BlackPixel(**display, _screen));
|
||||||
|
|
||||||
|
if (overrideredir) {
|
||||||
|
mask |= CWOverrideRedirect;
|
||||||
|
attrib.override_redirect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_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
|
||||||
|
|
||||||
|
_borderwidth = w;
|
||||||
|
XSetWindowBorderWidth(**display, _window, _borderwidth);
|
||||||
|
|
||||||
|
calcDefaultSizes();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setMinSize(const Size &s)
|
||||||
|
{
|
||||||
|
_min_size = s;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setMaxSize(const Size &s)
|
||||||
|
{
|
||||||
|
_max_size = s;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setBorderColor(const RenderColor *c)
|
||||||
|
{
|
||||||
|
_bordercolor = c;
|
||||||
|
XSetWindowBorder(**otk::display, _window,
|
||||||
|
c ? c->pixel() : BlackPixel(**otk::display, _screen));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setBevel(int b)
|
||||||
|
{
|
||||||
|
_bevel = b;
|
||||||
|
calcDefaultSizes();
|
||||||
|
layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::layout()
|
||||||
|
{
|
||||||
|
if (_direction == Horizontal)
|
||||||
|
layoutHorz();
|
||||||
|
else
|
||||||
|
layoutVert();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::layoutHorz()
|
||||||
|
{
|
||||||
|
std::list<Widget*>::iterator it, end;
|
||||||
|
|
||||||
|
// 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 (visible.empty()) return;
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::layoutVert()
|
||||||
|
{
|
||||||
|
std::list<Widget*>::iterator it, end;
|
||||||
|
|
||||||
|
// 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 (visible.empty()) return;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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::render()
|
||||||
|
{
|
||||||
|
if (!_texture || !_dirty) return;
|
||||||
|
if ((unsigned)_borderwidth * 2 > _area.width() ||
|
||||||
|
(unsigned)_borderwidth * 2 > _area.height())
|
||||||
|
return; // no surface to draw on
|
||||||
|
|
||||||
|
Surface *s = new Surface(_screen, Size(_area.width() - _borderwidth * 2,
|
||||||
|
_area.height() - _borderwidth * 2));
|
||||||
|
display->renderControl(_screen)->drawBackground(*s, *_texture);
|
||||||
|
|
||||||
|
renderForeground(*s); // for inherited types to render onto the _surface
|
||||||
|
|
||||||
|
XSetWindowBackgroundPixmap(**display, _window, s->pixmap());
|
||||||
|
XClearWindow(**display, _window);
|
||||||
|
|
||||||
|
// delete the old surface *after* its pixmap isn't in use anymore
|
||||||
|
if (_surface) delete _surface;
|
||||||
|
|
||||||
|
_surface = s;
|
||||||
|
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::internalResize(int w, int h)
|
void Widget::renderChildren()
|
||||||
{
|
{
|
||||||
assert(w > 0 && h > 0);
|
std::list<Widget*>::iterator it, end = _children.end();
|
||||||
|
|
||||||
bool fw = _fixed_width, fh = _fixed_height;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::addChild(Widget *child, bool front)
|
|
||||||
{
|
|
||||||
assert(child);
|
|
||||||
if (front)
|
|
||||||
_children.push_front(child);
|
|
||||||
else
|
|
||||||
_children.push_back(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::removeChild(Widget *child)
|
|
||||||
{
|
|
||||||
assert(child);
|
|
||||||
WidgetList::iterator it, end = _children.end();
|
|
||||||
for (it = _children.begin(); it != end; ++it) {
|
|
||||||
if ((*it) == child)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it != _children.end())
|
|
||||||
_children.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setStyle(RenderStyle *style)
|
|
||||||
{
|
|
||||||
assert(style);
|
|
||||||
_style = style;
|
|
||||||
_dirty = true;
|
|
||||||
|
|
||||||
WidgetList::iterator it, end = _children.end();
|
|
||||||
for (it = _children.begin(); it != end; ++it)
|
for (it = _children.begin(); it != end; ++it)
|
||||||
(*it)->setStyle(style);
|
(*it)->render();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Widget::setEventDispatcher(EventDispatcher *disp)
|
|
||||||
{
|
|
||||||
if (_event_dispatcher)
|
|
||||||
_event_dispatcher->clearHandler(_window);
|
|
||||||
_event_dispatcher = disp;
|
|
||||||
_event_dispatcher->registerHandler(_window, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::exposeHandler(const XExposeEvent &e)
|
void Widget::exposeHandler(const XExposeEvent &e)
|
||||||
{
|
{
|
||||||
EventHandler::exposeHandler(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)
|
void Widget::configureHandler(const XConfigureEvent &e)
|
||||||
{
|
{
|
||||||
EventHandler::configureHandler(e);
|
|
||||||
|
|
||||||
if (_ignore_config) {
|
if (_ignore_config) {
|
||||||
_ignore_config--;
|
_ignore_config--;
|
||||||
} else {
|
} else {
|
||||||
int width = e.width;
|
|
||||||
int height = e.height;
|
|
||||||
|
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
while (XCheckTypedWindowEvent(**display, _window, ConfigureNotify, &ev)) {
|
ev.xconfigure.width = e.width;
|
||||||
width = ev.xconfigure.width;
|
ev.xconfigure.height = e.height;
|
||||||
height = ev.xconfigure.height;
|
while (XCheckTypedWindowEvent(**display, window(), ConfigureNotify, &ev));
|
||||||
}
|
|
||||||
|
|
||||||
if (!(width == _rect.width() && height == _rect.height())) {
|
if (!((unsigned)ev.xconfigure.width == area().width() &&
|
||||||
_dirty = true;
|
(unsigned)ev.xconfigure.height == area().height())) {
|
||||||
_rect.setSize(width, height);
|
_area = Rect(_area.position(), Size(e.width, e.height));
|
||||||
}
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
233
otk/widget.hh
233
otk/widget.hh
|
@ -2,179 +2,136 @@
|
||||||
#ifndef __widget_hh
|
#ifndef __widget_hh
|
||||||
#define __widget_hh
|
#define __widget_hh
|
||||||
|
|
||||||
|
#include "eventhandler.hh"
|
||||||
#include "rect.hh"
|
#include "rect.hh"
|
||||||
#include "point.hh"
|
|
||||||
#include "rendertexture.hh"
|
|
||||||
#include "renderstyle.hh"
|
#include "renderstyle.hh"
|
||||||
#include "eventdispatcher.hh"
|
|
||||||
#include "display.hh"
|
|
||||||
#include "surface.hh"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <assert.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
class Widget : public EventHandler {
|
class Surface;
|
||||||
|
class RenderTexture;
|
||||||
|
class RenderColor;
|
||||||
|
class EventDispatcher;
|
||||||
|
|
||||||
|
class Widget : public EventHandler, public StyleNotify {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Direction { Horizontal, Vertical };
|
enum Direction { Horizontal, Vertical };
|
||||||
|
|
||||||
typedef std::list<Widget *> WidgetList;
|
Widget(int screen, EventDispatcher *ed, Direction direction = Horizontal,
|
||||||
|
int bevel = 3, bool overrideredir = false);
|
||||||
Widget(Widget *parent, Direction = Horizontal);
|
Widget(Widget *parent, Direction direction = Horizontal, int bevel = 3);
|
||||||
Widget(EventDispatcher *event_dispatcher, RenderStyle *style,
|
|
||||||
Direction direction = Horizontal, Cursor cursor = 0,
|
|
||||||
int bevel_width = 1, bool override_redirect = false);
|
|
||||||
|
|
||||||
virtual ~Widget();
|
virtual ~Widget();
|
||||||
|
|
||||||
|
inline int screen() const { return _screen; }
|
||||||
|
inline Window window() const { return _window; }
|
||||||
|
inline Widget *parent() const { return _parent; }
|
||||||
|
inline Direction direction() const { return _direction; }
|
||||||
|
|
||||||
|
inline RenderStyle::Justify alignment() const { return _alignment; }
|
||||||
|
void setAlignment(RenderStyle::Justify a);
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
virtual void refresh() { _dirty = true; render(); }
|
||||||
|
|
||||||
void exposeHandler(const XExposeEvent &e);
|
virtual void setBevel(int b);
|
||||||
void configureHandler(const XConfigureEvent &e);
|
inline int bevel() const { return _bevel; }
|
||||||
|
|
||||||
inline Window window(void) const { return _window; }
|
void move(const Point &p)
|
||||||
inline const Widget *parent(void) const { return _parent; }
|
{ moveresize(Rect(p, _area.size())); }
|
||||||
inline const WidgetList &children(void) const { return _children; }
|
void resize(const Size &s)
|
||||||
inline unsigned int screen(void) const { return _screen; }
|
{ moveresize(Rect(_area.position(), s)); }
|
||||||
inline const Rect &rect(void) const { return _rect; }
|
/*!
|
||||||
|
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);
|
||||||
|
|
||||||
void move(const Point &to);
|
inline const RenderColor *borderColor() const { return _bordercolor; }
|
||||||
void move(int x, int y);
|
virtual void setBorderColor(const RenderColor *c);
|
||||||
|
|
||||||
virtual void setWidth(int);
|
inline int borderWidth() const { return _borderwidth; }
|
||||||
virtual void setHeight(int);
|
virtual void setBorderWidth(int w);
|
||||||
|
|
||||||
virtual int width() const { return _rect.width(); }
|
const std::list<Widget*>& children() const { return _children; }
|
||||||
virtual int height() const { return _rect.height(); }
|
|
||||||
|
|
||||||
virtual void resize(const Point &to);
|
virtual void exposeHandler(const XExposeEvent &e);
|
||||||
virtual void resize(int x, int y);
|
virtual void configureHandler(const XConfigureEvent &e);
|
||||||
|
virtual void styleChanged(const RenderStyle &) {calcDefaultSizes();update();}
|
||||||
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 const RenderColor *borderColor(void) const { return _bcolor; }
|
|
||||||
virtual void setBorderColor(const RenderColor *color) {
|
|
||||||
assert(color); _bcolor = color;
|
|
||||||
XSetWindowBorder(**display, _window, color->pixel());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int borderWidth(void) const { return _bwidth; }
|
|
||||||
void setBorderWidth(int width) {
|
|
||||||
_bwidth = width;
|
|
||||||
XSetWindowBorderWidth(**display, _window, width);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void addChild(Widget *child, bool front = false);
|
|
||||||
virtual void removeChild(Widget *child);
|
|
||||||
|
|
||||||
inline bool isStretchableHorz(void) const { return _stretchable_horz; }
|
|
||||||
void setStretchableHorz(bool s_horz = true) { _stretchable_horz = s_horz; }
|
|
||||||
|
|
||||||
inline bool isStretchableVert(void) const { return _stretchable_vert; }
|
|
||||||
void setStretchableVert(bool s_vert = true) { _stretchable_vert = s_vert; }
|
|
||||||
|
|
||||||
inline Cursor cursor(void) const { return _cursor; }
|
|
||||||
void setCursor(Cursor cursor) {
|
|
||||||
_cursor = cursor;
|
|
||||||
XDefineCursor(**display, _window, _cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int bevelWidth(void) const { return _bevel_width; }
|
|
||||||
void setBevelWidth(int bevel_width)
|
|
||||||
{ assert(bevel_width > 0); _bevel_width = bevel_width; }
|
|
||||||
|
|
||||||
inline Direction direction(void) const { return _direction; }
|
|
||||||
void setDirection(Direction dir) { _direction = dir; }
|
|
||||||
|
|
||||||
inline RenderStyle *style(void) const { return _style; }
|
|
||||||
virtual void setStyle(RenderStyle *style);
|
|
||||||
|
|
||||||
inline long eventMask(void) const { return _event_mask; }
|
|
||||||
void setEventMask(long e);
|
|
||||||
|
|
||||||
inline EventDispatcher *eventDispatcher(void)
|
|
||||||
{ return _event_dispatcher; }
|
|
||||||
void setEventDispatcher(EventDispatcher *disp);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void addChild(Widget *w) { assert(w); _children.push_back(w); }
|
||||||
|
virtual void removeChild(Widget *w) { assert(w); _children.remove(w); }
|
||||||
|
|
||||||
bool _dirty;
|
//! Find the default min/max sizes for the widget. Useful after the in-use
|
||||||
bool _focused;
|
//! style has changed.
|
||||||
|
virtual void calcDefaultSizes() {};
|
||||||
|
|
||||||
virtual void adjust(void);
|
virtual void setMinSize(const Size &s);
|
||||||
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;
|
//! Arrange the widget's children
|
||||||
|
virtual void layout();
|
||||||
|
virtual void layoutHorz();
|
||||||
|
virtual void layoutVert();
|
||||||
|
virtual void render();
|
||||||
|
virtual void renderForeground(Surface&) {};
|
||||||
|
virtual void renderChildren();
|
||||||
|
|
||||||
|
void createWindow(bool overrideredir);
|
||||||
|
|
||||||
|
RenderTexture *_texture;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void internal_moveresize(int x, int y, unsigned w, unsigned int h);
|
||||||
|
|
||||||
|
int _screen;
|
||||||
Widget *_parent;
|
Widget *_parent;
|
||||||
WidgetList _children;
|
Window _window;
|
||||||
|
Surface *_surface;
|
||||||
|
long _event_mask;
|
||||||
|
|
||||||
RenderStyle *_style;
|
RenderStyle::Justify _alignment;
|
||||||
Direction _direction;
|
Direction _direction;
|
||||||
Cursor _cursor;
|
Rect _area;
|
||||||
int _bevel_width;
|
//! This size is the size *inside* the border, so they won't match the
|
||||||
int _ignore_config;
|
//! 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;
|
bool _visible;
|
||||||
|
|
||||||
bool _grabbed_mouse;
|
const RenderColor *_bordercolor;
|
||||||
bool _grabbed_keyboard;
|
int _borderwidth;
|
||||||
|
int _bevel;
|
||||||
|
bool _dirty;
|
||||||
|
|
||||||
bool _stretchable_vert;
|
std::list<Widget*> _children;
|
||||||
bool _stretchable_horz;
|
|
||||||
|
|
||||||
RenderTexture *_texture;
|
EventDispatcher *_dispatcher;
|
||||||
Pixmap _bg_pixmap;
|
|
||||||
unsigned int _bg_pixel;
|
|
||||||
|
|
||||||
const RenderColor *_bcolor;
|
int _ignore_config;
|
||||||
unsigned int _bwidth;
|
|
||||||
|
|
||||||
Rect _rect;
|
|
||||||
unsigned int _screen;
|
|
||||||
|
|
||||||
bool _fixed_width;
|
|
||||||
bool _fixed_height;
|
|
||||||
|
|
||||||
long _event_mask;
|
|
||||||
|
|
||||||
Surface *_surface;
|
|
||||||
|
|
||||||
EventDispatcher *_event_dispatcher;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue