summaryrefslogtreecommitdiff
path: root/otk/widget.cc
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-03-21 18:42:39 +0000
committerDana Jansens <danakj@orodu.net>2003-03-21 18:42:39 +0000
commita52a6d96d701c993896f276e4198003317632aaf (patch)
treebe2f51e6a433d1fdf9a7c8248b343cb3f6297212 /otk/widget.cc
parenta36c7543d4eedaa9e10bfd9f4d9b81279b1bb7e6 (diff)
rm the old code including the .pys and the c++ shit
Diffstat (limited to 'otk/widget.cc')
-rw-r--r--otk/widget.cc547
1 files changed, 0 insertions, 547 deletions
diff --git a/otk/widget.cc b/otk/widget.cc
deleted file mode 100644
index 1a0c7d9e..00000000
--- a/otk/widget.cc
+++ /dev/null
@@ -1,547 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "config.h"
-#include "widget.hh"
-#include "display.hh"
-#include "surface.hh"
-#include "rendertexture.hh"
-#include "rendercolor.hh"
-#include "eventdispatcher.hh"
-#include "screeninfo.hh"
-
-#include <climits>
-#include <cassert>
-#include <algorithm>
-
-namespace otk {
-
-Widget::Widget(int screen, EventDispatcher *ed, Direction direction, int bevel,
- bool overrideredir)
- : _texture(0),
- _screen(screen),
- _parent(0),
- _window(0),
- _surface(0),
- _event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
- ExposureMask | StructureNotifyMask),
- _alignment(RenderStyle::CenterJustify),
- _direction(direction),
- _max_size(INT_MAX, INT_MAX),
- _visible(false),
- _bordercolor(0),
- _borderwidth(0),
- _bevel(bevel),
- _dirty(true),
- _dispatcher(ed),
- _ignore_config(0)
-{
- createWindow(overrideredir);
- _dispatcher->registerHandler(_window, this);
-}
-
-Widget::Widget(Widget *parent, Direction direction, int bevel)
- : _texture(0),
- _screen(parent->_screen),
- _parent(parent),
- _window(0),
- _surface(0),
- _event_mask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
- ExposureMask | StructureNotifyMask),
- _alignment(RenderStyle::CenterJustify),
- _direction(direction),
- _max_size(INT_MAX, INT_MAX),
- _visible(false),
- _bordercolor(0),
- _borderwidth(0),
- _bevel(bevel),
- _dirty(true),
- _dispatcher(parent->_dispatcher),
- _ignore_config(0)
-{
- assert(parent);
- createWindow(false);
- parent->addChild(this);
- if (parent->visible()) parent->layout();
- _dispatcher->registerHandler(_window, this);
- styleChanged(*RenderStyle::style(_screen));
-}
-
-Widget::~Widget()
-{
- assert(_children.empty()); // this would be bad. theyd have a hanging _parent
-
- if (_surface) delete _surface;
- if (_parent) _parent->removeChild(this);
-
- _dispatcher->clearHandler(_window);
- XDestroyWindow(**display, _window);
-}
-
-void Widget::show(bool children)
-{
- if (children) {
- std::list<Widget*>::iterator it , end = _children.end();
- for (it = _children.begin(); it != end; ++it) {
- (*it)->show(true);
- }
- }
- if (!_visible) {
- if (_parent) _parent->calcDefaultSizes();
- else resize(_area.size()); // constrain sizes
- _visible = true;
- XMapWindow(**display, _window);
- update();
- }
-}
-
-void Widget::hide()
-{
- if (_visible) {
- _visible = false;
- XUnmapWindow(**display, _window);
- if (_parent) {
- _parent->calcDefaultSizes();
- _parent->layout();
- }
- }
-}
-
-void Widget::setEventMask(long e)
-{
- XSelectInput(**display, _window, e);
- _event_mask = e;
-}
-
-void Widget::update()
-{
- if (!_visible) return;
- _dirty = true;
- if (_parent) {
- _parent->calcDefaultSizes();
- _parent->layout(); // relay-out us and our siblings
- } else {
- render();
- layout();
- }
-}
-
-void Widget::moveresize(const Rect &r)
-{
- int w, h;
- w = std::max(std::min(r.width(), maxSize().width()), minSize().width());
- h = std::max(std::min(r.height(), maxSize().height()), minSize().height());
-
- bool sizechange = !(w == area().width() && h == area().height());
-
- if (r.x() == area().x() && r.y() == area().y() && !sizechange)
- return; // no change, don't cause a big layout chain to occur!
-
- internal_moveresize(r.x(), r.y(), w, h);
-
- if (sizechange)
- update();
-}
-
-void Widget::internal_moveresize(int x, int y, int w, int h)
-{
- assert(w > 0);
- assert(h > 0);
- assert(_borderwidth >= 0);
- _dirty = true;
- if (!(x == _area.x() && y == _area.y())) {
- if (!(w == _area.width() && h == _area.height()))
- XMoveResizeWindow(**display, _window, x, y,
- w - _borderwidth * 2,
- h - _borderwidth * 2);
- else
- XMoveWindow(**display, _window, x, y);
- } else
- XResizeWindow(**display, _window, 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::calcDefaultSizes()
-{
- std::list<Widget*>::const_iterator it, end = _children.end();
- int min_biggest = 0, max_biggest = 0;
- int min_sum = _bevel + _borderwidth * 2;
- int max_sum = _bevel + _borderwidth * 2;
- bool fullmax = false;
-
- for (it = _children.begin(); it != end; ++it) {
- const otk::Size &min = (*it)->minSize();
- const otk::Size &max = (*it)->maxSize();
- if (_direction == Horizontal) {
- if (min.height() > min_biggest) min_biggest = min.height();
- if (max.height() > max_biggest) max_biggest = max.height();
- min_sum += _bevel + min.width();
- if (max.width() == INT_MAX)
- fullmax = true;
- else if (!fullmax)
- max_sum += _bevel + max.width();
- } else {
- if (min.width() > min_biggest) min_biggest = min.width();
- if (max.width() > max_biggest) max_biggest = max.width();
- min_sum += _bevel + min.height();
- if (max.height() == INT_MAX)
- fullmax = true;
- else if (!fullmax)
- max_sum += _bevel + max.height();
- }
- }
- if (_direction == Horizontal) {
- _min_size = otk::Size(min_sum + (_bevel + _borderwidth) * 2,
- min_biggest + (_bevel + _borderwidth) * 2);
- _max_size = otk::Size((fullmax ? INT_MAX :
- max_sum + (_bevel + _borderwidth) * 2),
- max_biggest);
- } else {
- _min_size = otk::Size(min_biggest + (_bevel + _borderwidth) * 2,
- min_sum + (_bevel + _borderwidth) * 2);
- _max_size = otk::Size(max_biggest, (fullmax ? INT_MAX : max_sum +
- (_bevel + _borderwidth) * 2));
- }
- update();
-}
-
-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 (_children.empty() || !_visible) return;
- 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;
- for (it = _children.begin(), end = _children.end(); it != end; ++it)
- if ((*it)->visible())
- visible.push_back(*it);
-
- if (visible.empty()) return;
-
- int x, y, w, h; // working area
- x = y = _bevel;
- w = _area.width() - _borderwidth * 2 - _bevel * 2;
- h = _area.height() - _borderwidth * 2 - _bevel * 2;
- if (w < 0 || h < 0) return; // not worth laying anything out!
-
- int free = w - (visible.size() - 1) * _bevel;
- if (free < 0) free = 0;
- int each;
-
- std::list<Widget*> adjustable;
-
- // find the 'free' space, and how many children will be using it
- for (it = visible.begin(), end = visible.end(); it != end; ++it) {
- free -= (*it)->minSize().width();
- if (free < 0) free = 0;
- if ((*it)->maxSize().width() - (*it)->minSize().width() > 0)
- adjustable.push_back(*it);
- }
- // 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;
- 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) {
- 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;
- 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;
- for (it = _children.begin(), end = _children.end(); it != end; ++it)
- if ((*it)->visible())
- visible.push_back(*it);
-
- if (visible.empty()) return;
-
- int x, y, w, h; // working area
- x = y = _bevel;
- w = _area.width() - _borderwidth * 2 - _bevel * 2;
- h = _area.height() - _borderwidth * 2 - _bevel * 2;
- if (w < 0 || h < 0) return; // not worth laying anything out!
-
- int free = h - (visible.size() - 1) * _bevel;
- if (free < 0) free = 0;
- int each;
-
- std::list<Widget*> adjustable;
-
- // find the 'free' space, and how many children will be using it
- for (it = visible.begin(), end = visible.end(); it != end; ++it) {
- free -= (*it)->minSize().height();
- if (free < 0) free = 0;
- if ((*it)->maxSize().height() - (*it)->minSize().height() > 0)
- adjustable.push_back(*it);
- }
- // 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;
- 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) {
- 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;
- 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 (!_dirty) return;
- if (!_texture) {
- // set a solid color as the default background
- XSetWindowBackground(**display, _window,
- RenderStyle::style(_screen)->
- titlebarUnfocusBackground()->color().pixel());
- return;
- }
- if (_borderwidth * 2 > _area.width() ||
- _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;
-
- s->freePixelData(); // done rendering with this surface
- _surface = s;
-
- _dirty = false;
-}
-
-void Widget::renderChildren()
-{
- std::list<Widget*>::iterator it, end = _children.end();
- for (it = _children.begin(); it != end; ++it)
- (*it)->render();
-}
-
-void Widget::styleChanged(const RenderStyle &)
-{
- refresh();
-}
-
-void Widget::exposeHandler(const XExposeEvent &e)
-{
- EventHandler::exposeHandler(e);
- XClearArea(**display, _window, e.x, e.y, e.width, e.height, false);
-}
-
-void Widget::configureHandler(const XConfigureEvent &e)
-{
- if (_ignore_config) {
- _ignore_config--;
- } else {
- // only interested in these for top level windows
- if (_parent) return;
-
- XEvent ev;
- ev.xconfigure.width = e.width;
- ev.xconfigure.height = e.height;
- while (XCheckTypedWindowEvent(**display, window(), ConfigureNotify, &ev));
-
- if (!(ev.xconfigure.width == area().width() &&
- ev.xconfigure.height == area().height())) {
- _area = Rect(_area.position(), Size(e.width, e.height));
- update();
- }
- }
-}
-
-}