X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Fwidget.cc;h=eccbb5212392079238fb5894610ec5fa4a8a6d2a;hb=22b5d6458e3001a7bd930bf3491bf7fcd26ac3ce;hp=25d5043d2ee81adb5cfd833c7015d42b5edaebdf;hpb=74cfb1b4c115cdb4e05aa823b09d2b5ea9d0d690;p=chaz%2Fopenbox diff --git a/otk/widget.cc b/otk/widget.cc index 25d5043d..eccbb521 100644 --- a/otk/widget.cc +++ b/otk/widget.cc @@ -63,6 +63,7 @@ Widget::Widget(Widget *parent, Direction direction, int bevel) parent->addChild(this); if (parent->visible()) parent->layout(); _dispatcher->registerHandler(_window, this); + styleChanged(*RenderStyle::style(_screen)); } Widget::~Widget() @@ -86,6 +87,10 @@ void Widget::show(bool children) } if (!_visible) { _visible = true; + if (_parent) _parent->calcDefaultSizes(); + else { + resize(_min_size); + } XMapWindow(**display, _window); update(); } @@ -96,7 +101,10 @@ void Widget::hide() if (_visible) { _visible = false; XUnmapWindow(**display, _window); - if (_parent) _parent->layout(); + if (_parent) { + _parent->calcDefaultSizes(); + _parent->layout(); + } } } @@ -110,9 +118,10 @@ void Widget::update() { if (!_visible) return; _dirty = true; - if (parent()) - parent()->layout(); // relay-out us and our siblings - else { + if (_parent) { + _parent->calcDefaultSizes(); + _parent->layout(); // relay-out us and our siblings + } else { render(); layout(); } @@ -121,8 +130,8 @@ void Widget::update() void Widget::moveresize(const Rect &r) { 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()); + w = std::max(std::min(r.width(), maxSize().width()), minSize().width()); + h = std::max(std::min(r.height(), maxSize().height()), minSize().height()); if (r.x() == area().x() && r.y() == area().y() && w == area().width() && h == area().height()) { @@ -140,9 +149,15 @@ void Widget::internal_moveresize(int x, int y, int w, int h) assert(h > 0); assert(_borderwidth >= 0); _dirty = true; - XMoveResizeWindow(**display, _window, x, y, - w - _borderwidth * 2, - h - _borderwidth * 2); + 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); @@ -185,6 +200,48 @@ void Widget::createWindow(bool overrideredir) ++_ignore_config; } +void Widget::calcDefaultSizes() +{ + std::list::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, 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, 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); @@ -427,7 +484,14 @@ void Widget::layoutVert() void Widget::render() { - if (!_texture || !_dirty) return; + 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 @@ -456,6 +520,11 @@ void Widget::renderChildren() (*it)->render(); } +void Widget::styleChanged(const RenderStyle &) +{ + refresh(); +} + void Widget::exposeHandler(const XExposeEvent &e) { EventHandler::exposeHandler(e);