widegt using new render system
This commit is contained in:
parent
0ba441fe8f
commit
d8d9b42777
17 changed files with 229 additions and 224 deletions
|
@ -22,11 +22,12 @@ Button::~Button()
|
|||
void Button::setStyle(Style *style)
|
||||
{
|
||||
FocusLabel::setStyle(style);
|
||||
|
||||
setTexture(style->getButtonFocus());
|
||||
setUnfocusTexture(style->getButtonUnfocus());
|
||||
_pressed_focus_tx = style->getButtonPressedFocus();
|
||||
_pressed_unfocus_tx = style->getButtonPressedUnfocus();
|
||||
|
||||
// XXX: do this again
|
||||
//setTexture(style->getButtonFocus());
|
||||
//setUnfocusTexture(style->getButtonUnfocus());
|
||||
//_pressed_focus_tx = style->getButtonPressedFocus();
|
||||
//_pressed_unfocus_tx = style->getButtonPressedUnfocus();
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,13 +52,13 @@ void Button::release(unsigned int mouse_button)
|
|||
_pressed = false;
|
||||
}
|
||||
|
||||
void Button::setTexture(Texture *texture)
|
||||
void Button::setTexture(RenderTexture *texture)
|
||||
{
|
||||
FocusWidget::setTexture(texture);
|
||||
_unpr_focus_tx = texture;
|
||||
}
|
||||
|
||||
void Button::setUnfocusTexture(Texture *texture)
|
||||
void Button::setUnfocusTexture(RenderTexture *texture)
|
||||
{
|
||||
FocusWidget::setUnfocusTexture(texture);
|
||||
_unpr_unfocus_tx = texture;
|
||||
|
|
|
@ -13,18 +13,18 @@ public:
|
|||
Button(Widget *parent);
|
||||
~Button();
|
||||
|
||||
inline const Texture *getPressedFocusTexture(void) const
|
||||
inline const RenderTexture *getPressedFocusTexture(void) const
|
||||
{ return _pressed_focus_tx; }
|
||||
void setPressedFocusTexture(Texture *texture)
|
||||
void setPressedFocusTexture(RenderTexture *texture)
|
||||
{ _pressed_focus_tx = texture; }
|
||||
|
||||
inline const Texture *getPressedUnfocusTexture(void) const
|
||||
inline const RenderTexture *getPressedUnfocusTexture(void) const
|
||||
{ return _pressed_unfocus_tx; }
|
||||
void setPressedUnfocusTexture(Texture *texture)
|
||||
void setPressedUnfocusTexture(RenderTexture *texture)
|
||||
{ _pressed_unfocus_tx = texture; }
|
||||
|
||||
void setTexture(Texture *texture);
|
||||
void setUnfocusTexture(Texture *texture);
|
||||
void setTexture(RenderTexture *texture);
|
||||
void setUnfocusTexture(RenderTexture *texture);
|
||||
|
||||
inline bool isPressed(void) const { return _pressed; }
|
||||
void press(unsigned int mouse_button);
|
||||
|
@ -40,11 +40,11 @@ private:
|
|||
bool _pressed;
|
||||
unsigned int _mouse_button;
|
||||
|
||||
Texture *_pressed_focus_tx;
|
||||
Texture *_pressed_unfocus_tx;
|
||||
RenderTexture *_pressed_focus_tx;
|
||||
RenderTexture *_pressed_unfocus_tx;
|
||||
|
||||
Texture *_unpr_focus_tx;
|
||||
Texture *_unpr_unfocus_tx;
|
||||
RenderTexture *_unpr_focus_tx;
|
||||
RenderTexture *_unpr_unfocus_tx;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,55 +23,51 @@ FocusLabel::~FocusLabel()
|
|||
void FocusLabel::setStyle(Style *style)
|
||||
{
|
||||
FocusWidget::setStyle(style);
|
||||
|
||||
setTexture(style->getLabelFocus());
|
||||
setUnfocusTexture(style->getLabelUnfocus());
|
||||
|
||||
// XXX: do this again
|
||||
//setTexture(style->getLabelFocus());
|
||||
//setUnfocusTexture(style->getLabelUnfocus());
|
||||
}
|
||||
|
||||
|
||||
void FocusLabel::update(void)
|
||||
void FocusLabel::renderForeground(void)
|
||||
{
|
||||
if (_dirty) {
|
||||
const Font *ft = style()->getFont();
|
||||
Color *text_color = (isFocused() ? style()->getTextFocus()
|
||||
: style()->getTextUnfocus());
|
||||
unsigned int sidemargin = style()->getBevelWidth() * 2;
|
||||
const Font *ft = style()->getFont();
|
||||
Color *text_color = (isFocused() ? style()->getTextFocus()
|
||||
: style()->getTextUnfocus());
|
||||
unsigned int sidemargin = style()->getBevelWidth() * 2;
|
||||
|
||||
ustring t = _text; // the actual text to draw
|
||||
int x = sidemargin; // x coord for the text
|
||||
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;
|
||||
// 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);
|
||||
do {
|
||||
t.resize(text_len);
|
||||
length = ft->measureString(t);
|
||||
} while (length > max_length && text_len-- > 0);
|
||||
|
||||
// justify the text
|
||||
switch (style()->textJustify()) {
|
||||
case Style::RightJustify:
|
||||
x += max_length - length;
|
||||
break;
|
||||
case Style::CenterJustify:
|
||||
x += (max_length - length) / 2;
|
||||
break;
|
||||
case Style::LeftJustify:
|
||||
break;
|
||||
}
|
||||
// justify the text
|
||||
switch (style()->textJustify()) {
|
||||
case Style::RightJustify:
|
||||
x += max_length - length;
|
||||
break;
|
||||
case Style::CenterJustify:
|
||||
x += (max_length - length) / 2;
|
||||
break;
|
||||
case Style::LeftJustify:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FocusWidget::update();
|
||||
|
||||
display->renderControl(_screen)->
|
||||
drawString(this, *ft, x, 0, *text_color, t);
|
||||
} else
|
||||
FocusWidget::update();
|
||||
display->renderControl(_screen)->
|
||||
drawString(_surface, *ft, x, 0, *text_color, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
inline const ustring &getText(void) const { return _text; }
|
||||
void setText(const ustring &text) { _text = text; _dirty = true; }
|
||||
|
||||
void update(void);
|
||||
void renderForeground(void);
|
||||
|
||||
virtual void setStyle(Style *style);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ void FocusWidget::unfocus(void)
|
|||
update();
|
||||
}
|
||||
|
||||
void FocusWidget::setTexture(Texture *texture)
|
||||
void FocusWidget::setTexture(RenderTexture *texture)
|
||||
{
|
||||
Widget::setTexture(texture);
|
||||
_focus_texture = texture;
|
||||
|
|
|
@ -17,12 +17,12 @@ public:
|
|||
virtual void focus(void);
|
||||
virtual void unfocus(void);
|
||||
|
||||
virtual void setTexture(Texture *texture);
|
||||
virtual void setTexture(RenderTexture *texture);
|
||||
virtual void setBorderColor(const Color *color);
|
||||
|
||||
inline void setUnfocusTexture(Texture *texture)
|
||||
inline void setUnfocusTexture(RenderTexture *texture)
|
||||
{ _unfocus_texture = texture; }
|
||||
inline Texture *getUnfocusTexture(void) const
|
||||
inline RenderTexture *getUnfocusTexture(void) const
|
||||
{ return _unfocus_texture; }
|
||||
|
||||
inline void setUnfocusBorderColor(const Color *color)
|
||||
|
@ -35,8 +35,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
Texture *_unfocus_texture;
|
||||
Texture *_focus_texture;
|
||||
RenderTexture *_unfocus_texture;
|
||||
RenderTexture *_focus_texture;
|
||||
|
||||
const Color *_unfocus_bcolor;
|
||||
const Color *_focus_bcolor;
|
||||
|
|
66
otk/label.cc
66
otk/label.cc
|
@ -21,51 +21,47 @@ void Label::setStyle(Style *style)
|
|||
{
|
||||
Widget::setStyle(style);
|
||||
|
||||
setTexture(style->getLabelUnfocus());
|
||||
// XXX: do this again
|
||||
//setTexture(style->getLabelUnfocus());
|
||||
}
|
||||
|
||||
|
||||
void Label::update(void)
|
||||
void Label::renderForeground(void)
|
||||
{
|
||||
if (_dirty) {
|
||||
const Font *ft = style()->getFont();
|
||||
unsigned int sidemargin = style()->getBevelWidth() * 2;
|
||||
const Font *ft = style()->getFont();
|
||||
unsigned int sidemargin = style()->getBevelWidth() * 2;
|
||||
|
||||
ustring t = _text; // the actual text to draw
|
||||
int x = sidemargin; // x coord for the text
|
||||
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;
|
||||
// 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);
|
||||
do {
|
||||
t.resize(text_len);
|
||||
length = ft->measureString(t);
|
||||
} while (length > max_length && text_len-- > 0);
|
||||
|
||||
// justify the text
|
||||
switch (style()->textJustify()) {
|
||||
case Style::RightJustify:
|
||||
x += max_length - length;
|
||||
break;
|
||||
case Style::CenterJustify:
|
||||
x += (max_length - length) / 2;
|
||||
break;
|
||||
case Style::LeftJustify:
|
||||
break;
|
||||
}
|
||||
// justify the text
|
||||
switch (style()->textJustify()) {
|
||||
case Style::RightJustify:
|
||||
x += max_length - length;
|
||||
break;
|
||||
case Style::CenterJustify:
|
||||
x += (max_length - length) / 2;
|
||||
break;
|
||||
case Style::LeftJustify:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Widget::update();
|
||||
|
||||
display->renderControl(_screen)->
|
||||
drawString(this, *ft, x, 0, *style()->getTextUnfocus(), t);
|
||||
} else
|
||||
Widget::update();
|
||||
display->renderControl(_screen)->
|
||||
drawString(_surface, *ft, x, 0, *style()->getTextUnfocus(), t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,13 +16,17 @@ public:
|
|||
inline const ustring &getText(void) const { return _text; }
|
||||
void setText(const ustring &text) { _text = text; _dirty = true; }
|
||||
|
||||
void update(void);
|
||||
virtual void renderForeground(void);
|
||||
|
||||
virtual void setStyle(Style *style);
|
||||
|
||||
private:
|
||||
//! Text displayed in the label
|
||||
//! Text to be displayed in the label
|
||||
ustring _text;
|
||||
//! The actual text being shown, may be a subset of _text
|
||||
ustring _drawtext;
|
||||
//! The drawing offset for the text
|
||||
int _drawx;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -60,13 +60,12 @@ RenderControl::~RenderControl()
|
|||
|
||||
}
|
||||
|
||||
void RenderControl::drawString(Surface *sf, const Font &font, int x, int y,
|
||||
void RenderControl::drawString(Surface& sf, const Font &font, int x, int y,
|
||||
const Color &color, const ustring &string) const
|
||||
{
|
||||
assert(sf);
|
||||
assert(sf->_screen == _screen);
|
||||
XftDraw *d = sf->_xftdraw;
|
||||
assert(d);
|
||||
assert(sf._screen == _screen);
|
||||
XftDraw *d = sf._xftdraw;
|
||||
assert(d); // this means that the background hasn't been rendered yet!
|
||||
|
||||
if (font._shadow) {
|
||||
XftColor c;
|
||||
|
|
|
@ -69,11 +69,11 @@ public:
|
|||
static RenderControl *getRenderControl(int screen);
|
||||
|
||||
//! Draws a string onto a Surface
|
||||
virtual void drawString(Surface *sf, const Font &font, int x, int y,
|
||||
virtual void drawString(Surface& sf, const Font &font, int x, int y,
|
||||
const Color &color, const ustring &string) const;
|
||||
|
||||
//! Draws a background onto a Surface, as specified by a RenderTexture
|
||||
virtual void drawBackground(Surface *sf,
|
||||
virtual void drawBackground(Surface &sf,
|
||||
const RenderTexture &texture) const = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,20 +12,14 @@ int main(int argc, char **argv)
|
|||
otk::Application app(argc, argv);
|
||||
otk::AppWidget foo(&app);
|
||||
foo.resize(600, 500);
|
||||
|
||||
otk::RenderTexture tex;
|
||||
foo.setTexture(&tex);
|
||||
|
||||
foo.show();
|
||||
|
||||
otk::RenderControl *rc = otk::RenderControl::getRenderControl(0);
|
||||
|
||||
otk::RenderTexture tex;
|
||||
|
||||
rc->drawBackground(&foo, tex);
|
||||
XSetWindowBackgroundPixmap(**otk::display, foo.window(), foo.pixmap());
|
||||
XClearWindow(**otk::display, foo.window());
|
||||
|
||||
app.run();
|
||||
|
||||
delete rc;
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "surface.hh"
|
||||
#include "display.hh"
|
||||
#include "screeninfo.hh"
|
||||
#include "gccache.hh"
|
||||
|
||||
extern "C" {
|
||||
#include <X11/Xutil.h>
|
||||
|
@ -14,22 +15,12 @@ extern "C" {
|
|||
|
||||
namespace otk {
|
||||
|
||||
Surface::Surface(int screen)
|
||||
: _screen(screen),
|
||||
_size(1, 1),
|
||||
_pm(None),
|
||||
_xftdraw(0)
|
||||
{
|
||||
createObjects();
|
||||
}
|
||||
|
||||
Surface::Surface(int screen, const Point &size)
|
||||
: _screen(screen),
|
||||
_size(size),
|
||||
_pm(None),
|
||||
_pixmap(None),
|
||||
_xftdraw(0)
|
||||
{
|
||||
createObjects();
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
|
@ -37,36 +28,53 @@ Surface::~Surface()
|
|||
destroyObjects();
|
||||
}
|
||||
|
||||
void Surface::setPixmap(const Color &color)
|
||||
{
|
||||
if (_pixmap == None)
|
||||
createObjects();
|
||||
|
||||
Pen p(color);
|
||||
XFillRectangle(**display, _pixmap, p.gc(), 0, 0,
|
||||
_size.x(), _size.y());
|
||||
}
|
||||
|
||||
void Surface::setPixmap(XImage *image)
|
||||
{
|
||||
printf("SET PIXMAP\n");
|
||||
assert(image->width == _size.x());
|
||||
assert(image->height == _size.y());
|
||||
|
||||
if (_pixmap == None)
|
||||
createObjects();
|
||||
|
||||
XPutImage(**display, _pixmap, DefaultGC(**display, _screen),
|
||||
image, 0, 0, 0, 0, _size.x(), _size.y());
|
||||
}
|
||||
|
||||
void Surface::createObjects()
|
||||
{
|
||||
assert(_pm == None); assert(!_xftdraw);
|
||||
assert(_pixmap == None); assert(!_xftdraw);
|
||||
|
||||
const ScreenInfo *info = display->screenInfo(_screen);
|
||||
|
||||
_pm = XCreatePixmap(**display, info->rootWindow(), _size.x(), _size.y(),
|
||||
info->depth());
|
||||
|
||||
_xftdraw = XftDrawCreate(**display, _pm, info->visual(), info->colormap());
|
||||
_pixmap = XCreatePixmap(**display, info->rootWindow(),
|
||||
_size.x(), _size.y(), info->depth());
|
||||
|
||||
_xftdraw = XftDrawCreate(**display, _pixmap,
|
||||
info->visual(), info->colormap());
|
||||
}
|
||||
|
||||
void Surface::destroyObjects()
|
||||
{
|
||||
assert(_pm != None); assert(_xftdraw);
|
||||
if (_xftdraw) {
|
||||
XftDrawDestroy(_xftdraw);
|
||||
_xftdraw = 0;
|
||||
}
|
||||
|
||||
XftDrawDestroy(_xftdraw);
|
||||
_xftdraw = 0;
|
||||
|
||||
XFreePixmap(**display, _pm);
|
||||
_pm = None;
|
||||
}
|
||||
|
||||
void Surface::setSize(int w, int h)
|
||||
{
|
||||
if (w == _size.x() && h == _size.y()) return; // no change
|
||||
|
||||
_size.setPoint(w, h);
|
||||
destroyObjects();
|
||||
createObjects();
|
||||
if (_pixmap != None) {
|
||||
XFreePixmap(**display, _pixmap);
|
||||
_pixmap = None;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,26 +18,27 @@ class ScreenInfo;
|
|||
class Surface {
|
||||
int _screen;
|
||||
Point _size;
|
||||
Pixmap _pm;
|
||||
Pixmap _pixmap;
|
||||
XftDraw *_xftdraw;
|
||||
|
||||
protected:
|
||||
void createObjects();
|
||||
void destroyObjects();
|
||||
|
||||
void setPixmap(XImage *image);
|
||||
void setPixmap(const Color &color);
|
||||
|
||||
protected:
|
||||
Surface(int screen);
|
||||
Surface(int screen, const Point &size);
|
||||
|
||||
virtual void setSize(int w, int h);
|
||||
|
||||
public:
|
||||
Surface(int screen, const Point &size);
|
||||
virtual ~Surface();
|
||||
|
||||
inline int screen(void) const { return _screen; }
|
||||
|
||||
virtual const Point& size() const { return _size; }
|
||||
virtual int width() const { return _size.x(); }
|
||||
virtual int height() const { return _size.y(); }
|
||||
virtual Pixmap pixmap() const { return _pm; } // TEMP
|
||||
|
||||
virtual Pixmap pixmap() const { return _pixmap; }
|
||||
|
||||
// The RenderControl classes use the internal objects in this class to render
|
||||
// to it. Noone else needs them tho, so they are private.
|
||||
|
|
|
@ -98,16 +98,19 @@ static inline void renderPixel(XImage *im, unsigned char *dp,
|
|||
}
|
||||
}
|
||||
|
||||
void TrueRenderControl::drawBackground(Surface *sf,
|
||||
void TrueRenderControl::drawBackground(Surface& sf,
|
||||
const RenderTexture &texture) const
|
||||
{
|
||||
assert(sf);
|
||||
|
||||
int w = sf->width(), h = sf->height();
|
||||
XImage *im = sf->_im;
|
||||
Pixmap pm = sf->_pm;
|
||||
assert(im); assert(pm != None);
|
||||
(void)texture;
|
||||
|
||||
assert(sf._screen == _screen);
|
||||
|
||||
int w = sf.width(), h = sf.height();
|
||||
|
||||
const ScreenInfo *info = display->screenInfo(_screen);
|
||||
XImage *im = XCreateImage(**display, info->visual(), info->depth(),
|
||||
ZPixmap, 0, NULL, w, h, 32, 0);
|
||||
|
||||
unsigned char *data = new unsigned char[im->bytes_per_line * h];
|
||||
unsigned char *dp = data;
|
||||
unsigned int bytes_per_pixel = im->bits_per_pixel/8;
|
||||
|
@ -123,9 +126,10 @@ void TrueRenderControl::drawBackground(Surface *sf,
|
|||
renderPixel(im, dp, (255*x/w) >> _blue_shift << _blue_offset);
|
||||
|
||||
im->data = (char*) data;
|
||||
|
||||
XPutImage(**display, pm, DefaultGC(**display, _screen),
|
||||
sf->_im, 0, 0, 0, 0, w, h);
|
||||
}
|
||||
|
||||
sf.setPixmap(im);
|
||||
|
||||
delete [] im->data;
|
||||
im->data = NULL;
|
||||
XDestroyImage(im);}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
TrueRenderControl(int screen);
|
||||
virtual ~TrueRenderControl();
|
||||
|
||||
virtual void drawBackground(Surface *sf, const RenderTexture &texture) const;
|
||||
virtual void drawBackground(Surface& sf, const RenderTexture &texture) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
namespace otk {
|
||||
|
||||
Widget::Widget(Widget *parent, Direction direction)
|
||||
: Surface(parent->screen()),
|
||||
EventHandler(),
|
||||
: EventHandler(),
|
||||
_dirty(false), _focused(false),
|
||||
_parent(parent), _style(parent->style()), _direction(direction),
|
||||
_cursor(parent->cursor()), _bevel_width(parent->bevelWidth()),
|
||||
|
@ -24,8 +23,9 @@ Widget::Widget(Widget *parent, Direction direction)
|
|||
_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), _pos(0,0), _screen(parent->screen()),
|
||||
_bcolor(0), _bwidth(0), _rect(0, 0, 1, 1), _screen(parent->screen()),
|
||||
_fixed_width(false), _fixed_height(false),
|
||||
_surface(parent->screen(), _rect.size()),
|
||||
_event_dispatcher(parent->eventDispatcher())
|
||||
{
|
||||
assert(parent);
|
||||
|
@ -38,15 +38,15 @@ Widget::Widget(Widget *parent, Direction direction)
|
|||
Widget::Widget(EventDispatcher *event_dispatcher, Style *style,
|
||||
Direction direction, Cursor cursor, int bevel_width,
|
||||
bool override_redirect)
|
||||
: Surface(style->getScreen()),
|
||||
EventHandler(),
|
||||
: EventHandler(),
|
||||
_dirty(false),_focused(false),
|
||||
_parent(0), _style(style), _direction(direction), _cursor(cursor),
|
||||
_bevel_width(bevel_width), _ignore_config(0), _visible(false),
|
||||
_grabbed_mouse(false), _grabbed_keyboard(false),
|
||||
_stretchable_vert(false), _stretchable_horz(false), _texture(0),
|
||||
_bg_pixmap(0), _bg_pixel(0), _bcolor(0), _bwidth(0), _pos(0,0),
|
||||
_bg_pixmap(0), _bg_pixel(0), _bcolor(0), _bwidth(0), _rect(0, 0, 1, 1),
|
||||
_screen(style->getScreen()), _fixed_width(false), _fixed_height(false),
|
||||
_surface(style->getScreen(), _rect.size()),
|
||||
_event_dispatcher(event_dispatcher)
|
||||
{
|
||||
assert(event_dispatcher);
|
||||
|
@ -76,6 +76,8 @@ void Widget::create(bool override_redirect)
|
|||
const ScreenInfo *scr_info = display->screenInfo(_screen);
|
||||
Window p_window = _parent ? _parent->window() : scr_info->rootWindow();
|
||||
|
||||
_rect.setRect(0, 0, 1, 1); // just some initial values
|
||||
|
||||
XSetWindowAttributes attrib_create;
|
||||
unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
|
||||
|
||||
|
@ -94,8 +96,8 @@ void Widget::create(bool override_redirect)
|
|||
attrib_create.cursor = _cursor;
|
||||
}
|
||||
|
||||
_window = XCreateWindow(**display, p_window, _pos.x(),
|
||||
_pos.y(), width(), height(), 0,
|
||||
_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++;
|
||||
|
@ -105,14 +107,14 @@ void Widget::setWidth(int w)
|
|||
{
|
||||
assert(w > 0);
|
||||
_fixed_width = true;
|
||||
setGeometry(_pos.x(), _pos.y(), w, height());
|
||||
setGeometry(_rect.x(), _rect.y(), w, _rect.height());
|
||||
}
|
||||
|
||||
void Widget::setHeight(int h)
|
||||
{
|
||||
assert(h > 0);
|
||||
_fixed_height = true;
|
||||
setGeometry(_pos.x(), _pos.y(), _pos.x(), h);
|
||||
setGeometry(_rect.x(), _rect.y(), _rect.width(), h);
|
||||
}
|
||||
|
||||
void Widget::move(const Point &to)
|
||||
|
@ -122,7 +124,7 @@ void Widget::move(const Point &to)
|
|||
|
||||
void Widget::move(int x, int y)
|
||||
{
|
||||
_pos.setPoint(x, y);
|
||||
_rect.setPos(x, y);
|
||||
XMoveWindow(**display, _window, x, y);
|
||||
_ignore_config++;
|
||||
}
|
||||
|
@ -136,7 +138,7 @@ void Widget::resize(int w, int h)
|
|||
{
|
||||
assert(w > 0 && h > 0);
|
||||
_fixed_width = _fixed_height = true;
|
||||
setGeometry(_pos.x(), _pos.y(), w, h);
|
||||
setGeometry(_rect.x(), _rect.y(), w, h);
|
||||
}
|
||||
|
||||
void Widget::setGeometry(const Rect &new_geom)
|
||||
|
@ -151,8 +153,7 @@ void Widget::setGeometry(const Point &topleft, int width, int height)
|
|||
|
||||
void Widget::setGeometry(int x, int y, int width, int height)
|
||||
{
|
||||
_pos.setPoint(x, y);
|
||||
setSize(width, height);
|
||||
_rect = Rect(x, y, width, height);
|
||||
_dirty = true;
|
||||
|
||||
// don't use an XMoveResizeWindow here, because it doesn't seem to move
|
||||
|
@ -258,19 +259,14 @@ void Widget::ungrabKeyboard(void)
|
|||
void Widget::render(void)
|
||||
{
|
||||
if (!_texture) return;
|
||||
printf("RENDER\n");
|
||||
|
||||
_bg_pixmap = _texture->render(width(), height(), _bg_pixmap);
|
||||
_surface = Surface(_screen, _rect.size());
|
||||
display->renderControl(_screen)->drawBackground(_surface, *_texture);
|
||||
|
||||
if (_bg_pixmap) {
|
||||
XSetWindowBackgroundPixmap(**display, _window, _bg_pixmap);
|
||||
_bg_pixel = None;
|
||||
} else {
|
||||
unsigned int pix = _texture->color().pixel();
|
||||
if (pix != _bg_pixel) {
|
||||
_bg_pixel = pix;
|
||||
XSetWindowBackground(**display, _window, pix);
|
||||
}
|
||||
}
|
||||
renderForeground();
|
||||
|
||||
XSetWindowBackgroundPixmap(**display, _window, _surface.pixmap());
|
||||
}
|
||||
|
||||
void Widget::adjust(void)
|
||||
|
@ -296,22 +292,22 @@ void Widget::adjustHorz(void)
|
|||
for (it = _children.begin(); it != end; ++it) {
|
||||
tmp = *it;
|
||||
if (tmp->isStretchableVert())
|
||||
tmp->setHeight(height() > _bevel_width * 2 ?
|
||||
height() - _bevel_width * 2 : _bevel_width);
|
||||
tmp->setHeight(_rect.height() > _bevel_width * 2 ?
|
||||
_rect.height() - _bevel_width * 2 : _bevel_width);
|
||||
if (tmp->isStretchableHorz())
|
||||
stretchable.push_back(tmp);
|
||||
else
|
||||
width += tmp->width() + _bevel_width;
|
||||
width += tmp->_rect.width() + _bevel_width;
|
||||
|
||||
if (tmp->height() > tallest)
|
||||
tallest = tmp->height();
|
||||
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 = Surface::width() - width / stretchable.size();
|
||||
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
|
||||
|
@ -325,10 +321,10 @@ void Widget::adjustHorz(void)
|
|||
int x, y;
|
||||
|
||||
if (prev_widget)
|
||||
x = prev_widget->_pos.x() + prev_widget->width() + _bevel_width;
|
||||
x = prev_widget->_rect.x() + prev_widget->_rect.width() + _bevel_width;
|
||||
else
|
||||
x = _pos.x() + _bevel_width;
|
||||
y = (tallest - tmp->height()) / 2 + _bevel_width;
|
||||
x = _rect.x() + _bevel_width;
|
||||
y = (tallest - tmp->_rect.height()) / 2 + _bevel_width;
|
||||
|
||||
tmp->move(x, y);
|
||||
|
||||
|
@ -353,22 +349,22 @@ void Widget::adjustVert(void)
|
|||
for (it = _children.begin(); it != end; ++it) {
|
||||
tmp = *it;
|
||||
if (tmp->isStretchableHorz())
|
||||
tmp->setWidth(width() > _bevel_width * 2 ?
|
||||
width() - _bevel_width * 2 : _bevel_width);
|
||||
tmp->setWidth(_rect.width() > _bevel_width * 2 ?
|
||||
_rect.width() - _bevel_width * 2 : _bevel_width);
|
||||
if (tmp->isStretchableVert())
|
||||
stretchable.push_back(tmp);
|
||||
else
|
||||
height += tmp->height() + _bevel_width;
|
||||
height += tmp->_rect.height() + _bevel_width;
|
||||
|
||||
if (tmp->width() > widest)
|
||||
widest = tmp->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 = Surface::height() - height / stretchable.size();
|
||||
int str_height = _rect.height() - height / stretchable.size();
|
||||
|
||||
for (; str_it != str_end; ++str_it)
|
||||
(*str_it)->setHeight(str_height > _bevel_width ?
|
||||
|
@ -382,10 +378,10 @@ void Widget::adjustVert(void)
|
|||
int x, y;
|
||||
|
||||
if (prev_widget)
|
||||
y = prev_widget->_pos.y() + prev_widget->height() + _bevel_width;
|
||||
y = prev_widget->_rect.y() + prev_widget->_rect.height() + _bevel_width;
|
||||
else
|
||||
y = _pos.y() + _bevel_width;
|
||||
x = (widest - tmp->width()) / 2 + _bevel_width;
|
||||
y = _rect.y() + _bevel_width;
|
||||
x = (widest - tmp->_rect.width()) / 2 + _bevel_width;
|
||||
|
||||
tmp->move(x, y);
|
||||
|
||||
|
@ -417,9 +413,9 @@ void Widget::internalResize(int w, int h)
|
|||
if (! _fixed_width && ! _fixed_height)
|
||||
resize(w, h);
|
||||
else if (! _fixed_width)
|
||||
resize(w, height());
|
||||
resize(w, _rect.height());
|
||||
else if (! _fixed_height)
|
||||
resize(width(), h);
|
||||
resize(_rect.width(), h);
|
||||
}
|
||||
|
||||
void Widget::addChild(Widget *child, bool front)
|
||||
|
@ -477,10 +473,9 @@ void Widget::configureHandler(const XConfigureEvent &e)
|
|||
if (_ignore_config) {
|
||||
_ignore_config--;
|
||||
} else {
|
||||
if (!(e.width == width() && e.height == height())) {
|
||||
if (!(e.width == _rect.width() && e.height == _rect.height())) {
|
||||
_dirty = true;
|
||||
_pos.setPoint(e.x, e.y);
|
||||
setSize(e.width, e.height);
|
||||
_rect.setSize(e.width, e.height);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
#ifndef __widget_hh
|
||||
#define __widget_hh
|
||||
|
||||
#include "surface.hh"
|
||||
#include "rect.hh"
|
||||
#include "point.hh"
|
||||
#include "texture.hh"
|
||||
#include "rendertexture.hh"
|
||||
#include "style.hh"
|
||||
#include "eventdispatcher.hh"
|
||||
#include "display.hh"
|
||||
#include "surface.hh"
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
|
@ -19,7 +19,7 @@ extern "C" {
|
|||
|
||||
namespace otk {
|
||||
|
||||
class Widget : public Surface, public EventHandler {
|
||||
class Widget : public EventHandler {
|
||||
|
||||
public:
|
||||
|
||||
|
@ -42,7 +42,8 @@ public:
|
|||
inline Window window(void) const { return _window; }
|
||||
inline const Widget *parent(void) const { return _parent; }
|
||||
inline const WidgetList &children(void) const { return _children; }
|
||||
inline Rect rect(void) const { return Rect(_pos, size()); }
|
||||
inline unsigned int screen(void) const { return _screen; }
|
||||
inline const Rect &rect(void) const { return _rect; }
|
||||
|
||||
void move(const Point &to);
|
||||
void move(int x, int y);
|
||||
|
@ -50,6 +51,9 @@ public:
|
|||
virtual void setWidth(int);
|
||||
virtual void setHeight(int);
|
||||
|
||||
virtual int width() const { return _rect.width(); }
|
||||
virtual int height() const { return _rect.height(); }
|
||||
|
||||
virtual void resize(const Point &to);
|
||||
virtual void resize(int x, int y);
|
||||
|
||||
|
@ -73,8 +77,8 @@ public:
|
|||
bool grabKeyboard(void);
|
||||
void ungrabKeyboard(void);
|
||||
|
||||
inline Texture *texture(void) const { return _texture; }
|
||||
virtual void setTexture(Texture *texture)
|
||||
inline RenderTexture *texture(void) const { return _texture; }
|
||||
virtual void setTexture(RenderTexture *texture)
|
||||
{ _texture = texture; _dirty = true; }
|
||||
|
||||
inline const Color *borderColor(void) const { return _bcolor; }
|
||||
|
@ -129,6 +133,7 @@ protected:
|
|||
virtual void adjustVert(void);
|
||||
virtual void internalResize(int width, int height);
|
||||
virtual void render(void);
|
||||
virtual void renderForeground(void) {} // for overriding
|
||||
|
||||
Window _window;
|
||||
|
||||
|
@ -149,19 +154,21 @@ protected:
|
|||
bool _stretchable_vert;
|
||||
bool _stretchable_horz;
|
||||
|
||||
Texture *_texture;
|
||||
RenderTexture *_texture;
|
||||
Pixmap _bg_pixmap;
|
||||
unsigned int _bg_pixel;
|
||||
|
||||
const Color *_bcolor;
|
||||
unsigned int _bwidth;
|
||||
|
||||
Point _pos;
|
||||
Rect _rect;
|
||||
unsigned int _screen;
|
||||
|
||||
bool _fixed_width;
|
||||
bool _fixed_height;
|
||||
|
||||
Surface _surface;
|
||||
|
||||
EventDispatcher *_event_dispatcher;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue