From: Angus Leeming Date: Wed, 28 Apr 2004 17:22:05 +0000 (+0000) Subject: A layout engine for XForms. X-Git-Tag: 1.6.10~15268 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=b03580df175b7f6956c3ed4759a187989dfca195;p=features.git A layout engine for XForms. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8704 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/po/POTFILES.in b/po/POTFILES.in index 6e837e3f78..2f914c2342 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -187,8 +187,6 @@ src/output_plaintext.C src/paragraph.C src/rowpainter.C src/support/globbing.C -src/support/path_defines.C -src/tex2lyx/lengthcommon.C src/text.C src/text2.C src/text3.C diff --git a/src/BufferView.C b/src/BufferView.C index ec90ecea57..2763929f1d 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -65,9 +65,8 @@ using std::vector; extern BufferList bufferlist; -BufferView::BufferView(LyXView * owner, int xpos, int ypos, - int width, int height) - : pimpl_(new Pimpl(*this, owner, xpos, ypos, width, height)) +BufferView::BufferView(LyXView * owner, int width, int height) + : pimpl_(new Pimpl(*this, owner, width, height)) {} diff --git a/src/BufferView.h b/src/BufferView.h index 11df875780..8bbb970012 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -54,7 +54,7 @@ public: * Create a view with the given owner main window, * of the given dimensions. */ - BufferView(LyXView * owner, int x, int y, int w, int h); + BufferView(LyXView * owner, int w, int h); ~BufferView(); diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index f9adcc0cf2..c1c9968bfb 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -115,13 +115,13 @@ boost::signals::connection lostcon; BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner, - int xpos, int ypos, int width, int height) + int width, int height) : bv_(&bv), owner_(owner), buffer_(0), cursor_timeout(400), using_xterm_cursor(false), cursor_(bv) { xsel_cache_.set = false; - workarea_.reset(WorkAreaFactory::create(*owner_, xpos, ypos, width, height)); + workarea_.reset(WorkAreaFactory::create(*owner_, width, height)); screen_.reset(LyXScreenFactory::create(workarea())); // Setup the signals diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index d98925866c..6c6766af2b 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -46,8 +46,7 @@ class FuncStatus; /// struct BufferView::Pimpl : public boost::signals::trackable { /// - Pimpl(BufferView & bv, LyXView * owner, - int xpos, int ypos, int width, int height); + Pimpl(BufferView & bv, LyXView * owner, int width, int height); /// Painter & painter() const; /// return the screen for this bview diff --git a/src/ChangeLog b/src/ChangeLog index eed92477a0..a6dddf70b8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2004-04-28 Angus Leeming + + * BufferView.[Ch] (c-tor): + * BufferView_pimpl.[Ch] (c-tor): no longer receives x,y position. + No longer passes these data to the WorkArea generator. + 2004-04-28 Angus Leeming * BufferView_pimpl.C (c-tor): pass LyXView & to WorkArea generator. diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index ea71af020a..623e6d5d5c 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,8 @@ +2004-04-28 Angus Leeming + + * WorkAreaFactory.h (create): passed a LyXView &. + No longer passed x, y data. + 2004-04-27 Angus Leeming * Dialogs.h: add myself as author. diff --git a/src/frontends/WorkAreaFactory.h b/src/frontends/WorkAreaFactory.h index 12d8d76ae9..ca679bf6ef 100644 --- a/src/frontends/WorkAreaFactory.h +++ b/src/frontends/WorkAreaFactory.h @@ -20,7 +20,7 @@ namespace WorkAreaFactory { * Make a work area. Used because we want to generate * a toolkit-specific instance. */ - WorkArea * create(LyXView & owner, int x, int y, int w, int h); + WorkArea * create(LyXView & owner, int w, int h); } #endif // WORKAREA_FACTORY_H diff --git a/src/frontends/gtk/ChangeLog b/src/frontends/gtk/ChangeLog index 69113690cb..10ca09105e 100644 --- a/src/frontends/gtk/ChangeLog +++ b/src/frontends/gtk/ChangeLog @@ -1,3 +1,9 @@ +2004-04-28 Angus Leeming + + * WorkAreaFactory.C (create): No longer passed x, y data. + + * GView.[Ch] (c-tor): no longer passes x, y data to BufferView c-tor. + 2004-04-28 Angus Leeming * WorkAreaFactory.C (create): pass a LyXView & to GWorkArea c-tor. diff --git a/src/frontends/gtk/GView.C b/src/frontends/gtk/GView.C index b9b22248a1..fa1cac9932 100644 --- a/src/frontends/gtk/GView.C +++ b/src/frontends/gtk/GView.C @@ -83,7 +83,7 @@ GView::GView() menubar_.reset(new GMenubar(this, menubackend)); toolbar_.reset(new GToolbar(this, 0, 0)); toolbar_->init(); - bufferview_.reset(new BufferView(this, 0, 0, 300, 300)); + bufferview_.reset(new BufferView(this, 300, 300)); minibuffer_.reset(new GMiniBuffer(this, *controlcommand_)); focus_command_buffer.connect( diff --git a/src/frontends/gtk/WorkAreaFactory.C b/src/frontends/gtk/WorkAreaFactory.C index 7d8dcc18e3..e1c74cf827 100644 --- a/src/frontends/gtk/WorkAreaFactory.C +++ b/src/frontends/gtk/WorkAreaFactory.C @@ -19,7 +19,7 @@ namespace WorkAreaFactory { -WorkArea * create(LyXView & owner, int /*x*/, int /*y*/, int w, int h) +WorkArea * create(LyXView & owner, int w, int h) { return new GWorkArea(owner, w, h); } diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index 0b5055eb70..79f853b120 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,11 @@ +2004-04-28 Angus Leeming + + * WorkAreaFactory.C (create): No longer passed x, y data. + + * QWorkArea.[Ch] (c-tor): No longer receives x, y data. + + * QtView.[Ch] (c-tor): no longer passes x, y data to BufferView c-tor. + 2004-04-28 Angus Leeming * WorkAreaFactory.C (create): pass a LyXView & to QWorkArea c-tor. diff --git a/src/frontends/qt2/QWorkArea.C b/src/frontends/qt2/QWorkArea.C index 4426ca1f32..5e105e1d44 100644 --- a/src/frontends/qt2/QWorkArea.C +++ b/src/frontends/qt2/QWorkArea.C @@ -39,7 +39,7 @@ namespace { QWorkArea const * wa_ptr = 0; } -QWorkArea::QWorkArea(LyXView &, int, int, int, int) +QWorkArea::QWorkArea(LyXView &, int, int) : WorkArea(), QWidget(qApp->mainWidget()), painter_(*this) { scrollbar_ = new QScrollBar(QScrollBar::Vertical, this); diff --git a/src/frontends/qt2/QWorkArea.h b/src/frontends/qt2/QWorkArea.h index 3f241c20ba..092ef03a7f 100644 --- a/src/frontends/qt2/QWorkArea.h +++ b/src/frontends/qt2/QWorkArea.h @@ -35,7 +35,7 @@ class QWorkArea : public WorkArea, public QWidget { public: friend class QContentPane; - QWorkArea(LyXView & owner, int x, int y, int w, int h); + QWorkArea(LyXView & owner, int w, int h); virtual ~QWorkArea(); /// return this widget's painter diff --git a/src/frontends/qt2/QtView.C b/src/frontends/qt2/QtView.C index 6eb8197ea4..1f81096c30 100644 --- a/src/frontends/qt2/QtView.C +++ b/src/frontends/qt2/QtView.C @@ -49,7 +49,7 @@ QtView::QtView(unsigned int width, unsigned int height) qApp->setMainWidget(this); - bufferview_.reset(new BufferView(this, 0, 0, width, height)); + bufferview_.reset(new BufferView(this, width, height)); menubar_.reset(new QLMenubar(this, menubackend)); toolbar_.reset(new QLToolbar(this)); diff --git a/src/frontends/qt2/WorkAreaFactory.C b/src/frontends/qt2/WorkAreaFactory.C index 477e5eae53..3277a944cf 100644 --- a/src/frontends/qt2/WorkAreaFactory.C +++ b/src/frontends/qt2/WorkAreaFactory.C @@ -15,9 +15,9 @@ namespace WorkAreaFactory { -WorkArea * create(LyXView & owner, int x, int y, int w, int h) +WorkArea * create(LyXView & owner, int w, int h) { - return new QWorkArea(owner, x, y, w, h); + return new QWorkArea(owner, w, h); } } // namespace WorkAreaFactory diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index 80771c5d13..44070db863 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,18 @@ +2004-04-28 Angus Leeming + + * LayoutEngine.[Ch]: a layout engine for xforms, drawing heavily + on GTK+ code for inspiration. + + * Makefile.am: add new files. + + * WorkAreaFactory.C (create): no longer pass x,y data to XWorkArea. + + * XFormsMenubar.[Ch]: + * XFormsToolbar.[Ch]: + * XFormsView.[Ch]: + * XMiniBuffer.[Ch]: + * XWorkArea.[Ch]: adjustments to use the new layout engine. + 2004-04-28 Angus Leeming * WorkAreaFactory.C (create): pass a LyXView & to QWorkArea c-tor. diff --git a/src/frontends/xforms/LayoutEngine.C b/src/frontends/xforms/LayoutEngine.C new file mode 100644 index 0000000000..1d1d61e5c9 --- /dev/null +++ b/src/frontends/xforms/LayoutEngine.C @@ -0,0 +1,468 @@ +// -*- C++ -*- +/** + * \file LayoutEngine.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + * + * A generic layout engine. + * + * Draws heavily on the GTK+ files gtkbox.[ch], gtkhbox.[ch], + * for both inspiration and implementation, + * and from which this notice is taken: + * + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "LayoutEngine.h" +#include "lyx_forms.h" +#include + + +namespace lyx { +namespace frontend { + + +bool BoxList::empty() const +{ + return data_.empty(); +} + + +BoxList::size_type BoxList::size() const +{ + return data_.size(); +} + + +void BoxList::clear() +{ + data_.clear(); +} + + +Box & BoxList::push_back(Box const & box) +{ + data_.push_back(box); + return data_.back(); +} + + +BoxList::iterator BoxList::begin() +{ + return data_.begin(); +} + + +BoxList::iterator BoxList::end() +{ + return data_.end(); +} + + +BoxList::const_iterator BoxList::begin() const +{ + return data_.begin(); +} + + +BoxList::const_iterator BoxList::end() const +{ + return data_.end(); +} + + +BoxList::iterator BoxList::erase(iterator where) +{ + return data_.erase(where); +} + + +BoxList::iterator BoxList::erase(iterator begin, iterator end) +{ + return data_.erase(begin, end); +} + + +Box::Orientation Box::default_orientation_ = Box::Vertical; +Box::Packing Box::default_packing_ = Box::Shrink; + + +Box::Box(dimension_t min_w, dimension_t min_h) + : visible_(false), + min_w_(min_w), + min_h_(min_h), + w_(min_w), + h_(min_h), + x_(0), + y_(0), + orientation_(default_orientation_), + packing_(default_packing_), + prefered_visibility_(Visible) +{} + + +void Box::setMinimumDimensions(dimension_t min_w, dimension_t min_h) +{ + min_w_ = min_w; + min_h_ = min_h; +} + + +Box::Orientation Box::orientation() const +{ + return orientation_; +} + + +void Box::set(Orientation o) +{ + orientation_ = o; +} + + +Box::Orientation Box::defaultOrientation() +{ + return default_orientation_; +} + + +void Box::setDefault(Orientation o) +{ + default_orientation_ = o; +} + + +Box::Packing Box::packing() const +{ + return packing_; +} + + +void Box::set(Packing p) +{ + packing_ = p; +} + + +Box::Packing Box::defaultPacking() +{ + return default_packing_; +} + + +void Box::setDefault(Packing p) +{ + default_packing_ = p; +} + + +bool Box::expandable() const +{ + if (!visible_) + return false; + + if (packing_ == Expand) + return true; + + BoxList::const_iterator it = children_.begin(); + BoxList::const_iterator const end = children_.end(); + for (; it != end; ++it) { + if (it->visible() && it->packing() == Expand) + return true; + } + + return false; +} + + +Box::PreferedVisibility Box::preferedVisibility() const +{ + return prefered_visibility_; +} + + +void Box::set(PreferedVisibility pv) +{ + prefered_visibility_ = pv; + if (pv == Invisible) + hide(); +} + + +bool Box::visible() const +{ + return visible_; +} + + +void Box::show() +{ + if (prefered_visibility_ == Invisible) + return; + + visible_ = true; + + BoxList::iterator it = children_.begin(); + BoxList::iterator const end = children_.end(); + for (; it != end; ++it) + it->show(); +} + + +void Box::hide() +{ + visible_ = false; + + BoxList::iterator it = children_.begin(); + BoxList::iterator const end = children_.end(); + for (; it != end; ++it) + it->hide(); +} + + +BoxList & Box::children() +{ + return children_; +} + + +BoxList const & Box::children() const +{ + return children_; +} + + +Box::dimension_t Box::width() const +{ + return w_; +} + + +Box::dimension_t Box::height() const +{ + return h_; +} + + +Box::dimension_t Box::xorigin() const +{ + return x_; +} + + +Box::dimension_t Box::yorigin() const +{ + return y_; +} + + +void Box::updateMetrics() +{ + shrinkMetrics(); + expandMetrics(x_, y_, w_, h_); +} + + +void Box::shrinkMetrics() +{ + dimension_t width = 0; + dimension_t height = 0; + + BoxList::iterator it = children_.begin(); + BoxList::iterator const end = children_.end(); + for (; it != end; ++it) { + if (!it->visible()) + continue; + + it->shrinkMetrics(); + dimension_t child_width = it->width(); + dimension_t child_height = it->height(); + + if (orientation_ == Horizontal) { + width += child_width; + height = std::max(height, child_height); + } else { + width = std::max(width, child_width); + height += child_height; + } + } + + w_ = visible_ ? std::max(min_w_, width) : 0; + h_ = visible_ ? std::max(min_h_, height) : 0; +} + + +void Box::expandMetrics(dimension_t x_in, dimension_t y_in, + dimension_t w_avail, dimension_t h_avail) +{ + x_ = x_in; + y_ = y_in; + w_ = w_avail; + h_ = h_avail; + + if (orientation_ == Vertical) + expandVbox(x_in, y_in, w_avail, h_avail); + else + expandHbox(x_in, y_in, w_avail, h_avail); +} + + +void Box::expandHbox(dimension_t x_in, dimension_t y_in, + dimension_t w_avail, dimension_t h_avail) +{ + int nvisible_children = 0; + int nexpanded_children = 0; + dimension_t w_fixed = 0; + + BoxList::const_iterator cit = children_.begin(); + BoxList::const_iterator const cend = children_.end(); + for (; cit != cend; ++cit) { + if (cit->visible()) { + nvisible_children += 1; + if (cit->expandable()) + nexpanded_children += 1; + else + w_fixed += cit->width(); + } + } + + if (nvisible_children == 0) + return; + + dimension_t width = 0; + dimension_t extra = 0; + if (nexpanded_children > 0) { + width = w_avail - w_fixed; + extra = width / nexpanded_children; + } + + dimension_t x_child = x_in; + dimension_t y_child = y_in; + dimension_t h_child = h_avail; + + BoxList::iterator it = children_.begin(); + BoxList::iterator const end = children_.end(); + for (; it != end; ++it) { + if (!it->visible()) + continue; + + dimension_t w_child = it->width(); + if (it->expandable()) { + if (nexpanded_children == 1) + w_child = std::max(w_child, width); + else + w_child = std::max(w_child, extra); + + nexpanded_children -= 1; + width -= w_child; + } + + it->expandMetrics(x_child, y_child, w_child, h_child); + x_child += w_child; + } +} + + +void Box::expandVbox(dimension_t x_in, dimension_t y_in, + dimension_t w_avail, dimension_t h_avail) +{ + int nvisible_children = 0; + int nexpanded_children = 0; + dimension_t h_fixed = 0; + + BoxList::const_iterator cit = children_.begin(); + BoxList::const_iterator const cend = children_.end(); + for (; cit != cend; ++cit) { + if (cit->visible()) { + nvisible_children += 1; + if (cit->expandable()) + nexpanded_children += 1; + else + h_fixed += cit->height(); + } + } + + if (nvisible_children == 0) + return; + + dimension_t height = 0; + dimension_t extra = 0; + if (nexpanded_children > 0) { + height = h_avail - h_fixed; + extra = height / nexpanded_children; + } + + dimension_t x_child = x_in; + dimension_t y_child = y_in; + dimension_t w_child = w_avail; + + BoxList::iterator it = children_.begin(); + BoxList::iterator const end = children_.end(); + for (; it != end; ++it) { + if (!it->visible()) + continue; + + dimension_t h_child = it->height(); + if (it->expandable()) { + if (nexpanded_children == 1) + h_child = std::max(h_child, height); + else + h_child = std::max(h_child, extra); + nexpanded_children -= 1; + height -= h_child; + } + + it->expandMetrics(x_child, y_child, w_child, h_child); + y_child += h_child; + } +} + + +Box & WidgetMap::add(FL_OBJECT * ob, BoxList & container, + dimension_t min_w, dimension_t min_h) +{ + Box & box = container.push_back(Box(min_w, min_h)); + widgets_[ob] = &box; + return box; +} + + +void WidgetMap::updateMetrics() const +{ + DataMap::const_iterator it = widgets_.begin(); + DataMap::const_iterator const end = widgets_.end(); + for (; it != end; ++it) { + FL_OBJECT * ob = it->first; + Box & box = *it->second; + fl_set_object_geometry(ob, + box.xorigin(), box.yorigin(), + box.width(), box.height()); + } +} + + +Box & embed(FL_OBJECT * ob, BoxList & container, WidgetMap & widgets, int bw) +{ + container.push_back(Box(0, bw)); + Box & middle = container.push_back(Box(0, 0)); + middle.set(Box::Horizontal); + container.push_back(Box(0, bw)); + + middle.children().push_back(Box(bw, 0)); + Box & center = widgets.add(ob, middle.children(), 0, 0); + middle.children().push_back(Box(bw, 0)); + + return center; +} + +} // namespace frontend +} // namespace lyx diff --git a/src/frontends/xforms/LayoutEngine.h b/src/frontends/xforms/LayoutEngine.h new file mode 100644 index 0000000000..c15379eda5 --- /dev/null +++ b/src/frontends/xforms/LayoutEngine.h @@ -0,0 +1,189 @@ +// -*- C++ -*- +/** + * \file LayoutEngine.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + * + * A generic layout engine that draws heavily on GTK+. + */ + +#ifndef LAYOUT_ENGINE_H +#define LAYOUT_ENGINE_H + +#include "forms_fwd.h" +#include +#include + +namespace lyx { +namespace frontend { + +class Box; + +class BoxList { +public: + typedef std::list Container; + typedef Container::size_type size_type; + typedef Container::iterator iterator; + typedef Container::const_iterator const_iterator; + + bool empty() const; + size_type size() const; + + void clear(); + Box & push_back(Box const &); + + iterator begin(); + iterator end(); + + const_iterator begin() const; + const_iterator end() const; + + iterator erase(iterator where); + iterator erase(iterator begin, iterator end); + +private: + Container data_; +}; + + +class Box { +public: + typedef unsigned int dimension_t; + + /** \param min_w the minimum allowed width of the box. + * \param min_h the minimum allowed height of the box. + */ + Box(dimension_t min_w, dimension_t min_h); + + void setMinimumDimensions(dimension_t min_w, dimension_t min_h); + + /** \name Child Orientation + * The enum prescribes whether children are aligned + * horizontally or vertically. + */ + //@{ + enum Orientation { + Vertical, + Horizontal + }; + + Orientation orientation() const; + void set(Orientation); + + /// Initially set to Vertical + static Orientation defaultOrientation(); + static void setDefault(Orientation); + //@} + + /** \name Packing + * Do the children receive extra space when the parent grows? + */ + //@{ + enum Packing { + Shrink, + Expand + }; + + Packing packing() const; + void set(Packing); + + /// Initially set to Shrink + static Packing defaultPacking(); + static void setDefault(Packing); + + /** returns true if this Box or any of its children have + * packing() == Expand. + */ + bool expandable() const; + //@} + + /** \name Prefered Visibility + * If the parent container is visible, should this Box be + * visible or not? + */ + //@{ + enum PreferedVisibility { + Visible, + Invisible + }; + + PreferedVisibility preferedVisibility() const; + /// If \pv == Invisible, also calls hide(). + void set(PreferedVisibility pv); + //@} + + /** \name Actual Visibility + */ + //@{ + bool visible() const; + /// Does nothing if preferedVisibility() == Invisible. + void show(); + /// Always hides. + void hide(); + //@} + + BoxList & children(); + BoxList const & children() const; + + dimension_t width() const; + dimension_t height() const; + dimension_t xorigin() const; + dimension_t yorigin() const; + + void updateMetrics(); + +private: + void shrinkMetrics(); + void expandMetrics(dimension_t x, dimension_t y, + dimension_t w, dimension_t h); + void expandHbox(dimension_t x, dimension_t y, + dimension_t w, dimension_t h); + void expandVbox(dimension_t x, dimension_t y, + dimension_t w, dimension_t h); + + static Orientation default_orientation_; + static Packing default_packing_; + + BoxList children_; + bool visible_; + dimension_t min_w_; + dimension_t min_h_; + dimension_t w_; + dimension_t h_; + dimension_t x_; + dimension_t y_; + Orientation orientation_; + Packing packing_; + PreferedVisibility prefered_visibility_; +}; + + +class WidgetMap { +public: + typedef Box::dimension_t dimension_t; + + /// \returns the just-added Box. + Box & add(FL_OBJECT * widget, BoxList & container, + dimension_t min_w, dimension_t min_h); + void updateMetrics() const; + +private: + typedef std::map DataMap; + DataMap widgets_; +}; + + +/** Embed \c ob in \c container inside a border of width \c bw. + * Thereafter, hand control of its metrics to \c widgets. + * \returns the Box containing \c ob. + */ +Box & embed(FL_OBJECT * ob, BoxList & container, WidgetMap & widgets, int bw); + +} // namespace frontend +} // namespace lyx + +#endif // NOT LAYOUT_ENGINE_H diff --git a/src/frontends/xforms/Makefile.am b/src/frontends/xforms/Makefile.am index 3375547096..ec7b0ffc86 100644 --- a/src/frontends/xforms/Makefile.am +++ b/src/frontends/xforms/Makefile.am @@ -149,6 +149,8 @@ libxforms_la_SOURCES = \ FormVSpace.h \ FormWrap.C \ FormWrap.h \ + LayoutEngine.C \ + LayoutEngine.h \ LyXKeySymFactory.C \ LyXScreenFactory.C \ XFormsMenubar.C \ diff --git a/src/frontends/xforms/WorkAreaFactory.C b/src/frontends/xforms/WorkAreaFactory.C index 49513a13ad..8158ee0191 100644 --- a/src/frontends/xforms/WorkAreaFactory.C +++ b/src/frontends/xforms/WorkAreaFactory.C @@ -16,9 +16,9 @@ namespace WorkAreaFactory { -WorkArea * create(LyXView & owner, int x, int y, int w, int h) +WorkArea * create(LyXView & owner, int w, int h) { - return new XWorkArea(owner, x, y, w, h); + return new XWorkArea(owner, w, h); } } diff --git a/src/frontends/xforms/XFormsMenubar.C b/src/frontends/xforms/XFormsMenubar.C index e8a3c0f421..a52ffe6c88 100644 --- a/src/frontends/xforms/XFormsMenubar.C +++ b/src/frontends/xforms/XFormsMenubar.C @@ -23,8 +23,13 @@ #include "support/lstrings.h" #include "support/tostr.h" +#include + #include "lyx_forms.h" +using lyx::frontend::Box; +using lyx::frontend::BoxList; + using lyx::support::lowercase; using lyx::support::subst; @@ -82,8 +87,14 @@ extern "C" { XFormsMenubar::XFormsMenubar(LyXView * view, MenuBackend const & mb) - : owner_(static_cast(view)), menubackend_(&mb) + : owner_(static_cast(view)), + menubackend_(&mb), + menubar_(0) { + using lyx::frontend::WidgetMap; + owner_->metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics, + &widgets_)); + makeMenubar(menubackend_->getMenubar()); } @@ -94,16 +105,27 @@ XFormsMenubar::~XFormsMenubar() void XFormsMenubar::makeMenubar(Menu const & menu) { - FL_FORM * form = owner_->getForm(); - int moffset = 0; + // Draw a frame around the whole. + BoxList & boxlist = owner_->getBox(XFormsView::Top).children(); - // Create menu frame if there is non yet. - FL_OBJECT * frame = fl_add_frame(FL_UP_FRAME, 0, 0, - form->w, mheight, ""); + FL_OBJECT * frame = fl_add_frame(FL_UP_FRAME, 0, 0, 0, 0, ""); fl_set_object_resize(frame, FL_RESIZE_ALL); - fl_set_object_gravity(frame, NorthWestGravity, - NorthEastGravity); + fl_set_object_gravity(frame, NorthWestGravity, NorthEastGravity); + + menubar_ = &widgets_.add(frame, boxlist, 0, mheight); + + // The menubar contains three vertically-aligned Boxes, + // the center one of which is to contain the buttons, + // aligned horizontally. + // The other two provide some visual padding. + menubar_->children().push_back(Box(0, yloc)); + Box & menubar_center = menubar_->children().push_back(Box(0,0)); + menubar_center.set(Box::Horizontal); + menubar_->children().push_back(Box(0, yloc)); + BoxList & menubar_buttons = menubar_center.children(); + + // Add the buttons. Menu::const_iterator i = menu.begin(); Menu::const_iterator end = menu.end(); for (; i != end; ++i) { @@ -117,11 +139,12 @@ void XFormsMenubar::makeMenubar(Menu const & menu) string const label = i->label(); string const shortcut = '#' + i->shortcut(); int const width = string_width(label); - obj = fl_add_button(FL_MENU_BUTTON, - air + moffset, yloc, - width + mbadd, - mbheight, - label.c_str()); + + obj = fl_add_button(FL_MENU_BUTTON, 0, 0, 0, 0, label.c_str()); + + menubar_buttons.push_back(Box(air, 0)); + widgets_.add(obj, menubar_buttons, width + mbadd, mbheight); + fl_set_object_boxtype(obj, FL_FLAT_BOX); fl_set_object_color(obj, FL_MCOL, FL_MCOL); fl_set_object_lsize(obj, MENU_LABEL_SIZE); @@ -129,7 +152,6 @@ void XFormsMenubar::makeMenubar(Menu const & menu) fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity); - moffset += obj->w + air; fl_set_object_shortcut(obj, shortcut.c_str(), 1); fl_set_object_callback(obj, C_XFormsMenubar_MenuCallback, 1); @@ -138,7 +160,6 @@ void XFormsMenubar::makeMenubar(Menu const & menu) buttonlist_.push_back(iteminfo); obj->u_vdata = iteminfo.get(); } - } diff --git a/src/frontends/xforms/XFormsMenubar.h b/src/frontends/xforms/XFormsMenubar.h index d43061d71b..ded13fb862 100644 --- a/src/frontends/xforms/XFormsMenubar.h +++ b/src/frontends/xforms/XFormsMenubar.h @@ -15,6 +15,8 @@ #include "funcrequest.h" #include "frontends/Menubar.h" +#include "LayoutEngine.h" + #include #include "forms_fwd.h" @@ -67,6 +69,10 @@ private: /// MenuBackend const * menubackend_; /// + lyx::frontend::Box * menubar_; + /// + lyx::frontend::WidgetMap widgets_; + /// struct ItemInfo { /// ItemInfo(XFormsMenubar * p, MenuItem const * i, diff --git a/src/frontends/xforms/XFormsToolbar.C b/src/frontends/xforms/XFormsToolbar.C index d288cd7b97..69f8e07eb3 100644 --- a/src/frontends/xforms/XFormsToolbar.C +++ b/src/frontends/xforms/XFormsToolbar.C @@ -30,6 +30,11 @@ #include "lyx_forms.h" #include "combox.h" +#include + +using lyx::frontend::Box; +using lyx::frontend::BoxList; + using std::distance; using std::endl; using std::string; @@ -90,10 +95,17 @@ XFormsToolbar::toolbarItem::operator=(toolbarItem const & ti) -XFormsToolbar::XFormsToolbar(LyXView * o, int x, int y) - : owner_(static_cast(o)), combox_(0), xpos(x), ypos(y) +XFormsToolbar::XFormsToolbar(LyXView * o) + : toolbar_(0), + toolbar_buttons_(0), + owner_(static_cast(o)), + combox_(0) { tooltip_ = new Tooltips; + + using lyx::frontend::WidgetMap; + owner_->metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics, + &widgets_)); } @@ -278,6 +290,23 @@ void XFormsToolbar::add(ToolbarBackend::Toolbar const & tb) if (!toollist_.empty()) return; + // The toolbar contains three vertically-aligned Boxes, + // the center one of which is to contain the buttons, + // aligned horizontally. + // The other two provide some visual padding. + BoxList & boxlist = owner_->getBox(XFormsView::Top).children(); + toolbar_ = &boxlist.push_back(Box(0,0)); + + int const padding = 2 + abs(fl_get_border_width()); + toolbar_->children().push_back(Box(0, padding)); + + Box & toolbar_center = toolbar_->children().push_back(Box(0,0)); + toolbar_center.set(Box::Horizontal); + toolbar_buttons_ = &toolbar_center.children(); + + toolbar_->children().push_back(Box(0, padding)); + + // Add the buttons themselves. funcs.clear(); ToolbarBackend::item_iterator it = tb.items.begin(); @@ -294,18 +323,21 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip) switch (func.action) { case ToolbarBackend::SEPARATOR: - xpos += sepspace; + toolbar_buttons_->push_back(Box(sepspace, 0)); break; case ToolbarBackend::MINIBUFFER: // Not implemented break; case ToolbarBackend::LAYOUTS: - xpos += standardspacing; + toolbar_buttons_->push_back(Box(standardspacing, 0)); if (combox_) break; combox_ = fl_add_combox(FL_DROPLIST_COMBOX, - xpos, ypos, 135, height, ""); + 0, 0, 135, height, ""); + + widgets_.add(combox_, *toolbar_buttons_, 135, height); + fl_set_combox_browser_height(combox_, 400); fl_set_object_boxtype(combox_, FL_DOWN_BOX); fl_set_object_color(combox_, FL_MCOL, FL_MCOL); @@ -314,17 +346,17 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip) combox_->u_vdata = this; fl_set_object_callback(combox_, C_layoutSelectedCB, 0); - xpos += 135; break; default: { FL_OBJECT * obj; - xpos += standardspacing; + toolbar_buttons_->push_back(Box(standardspacing, 0)); item.icon = obj = fl_add_pixmapbutton(FL_NORMAL_BUTTON, - xpos, ypos, - buttonwidth, - height, ""); + 0, 0, 0, 0, ""); + + widgets_.add(obj, *toolbar_buttons_, buttonwidth, height); + fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthWestGravity, @@ -343,14 +375,6 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip) string const xpm = toolbarbackend.getIcon(func); fl_set_pixmapbutton_file(obj, xpm.c_str()); - - // we must remember to update the positions - xpos += buttonwidth; - // ypos is constant - /* Here will come a check to see if the new - * pos is within the bounds of the main frame, - * and perhaps wrap the toolbar if not. - */ break; } } diff --git a/src/frontends/xforms/XFormsToolbar.h b/src/frontends/xforms/XFormsToolbar.h index f74fde1b15..6183bab2bf 100644 --- a/src/frontends/xforms/XFormsToolbar.h +++ b/src/frontends/xforms/XFormsToolbar.h @@ -16,6 +16,8 @@ #include #include "forms_fwd.h" +#include "LayoutEngine.h" + #include "frontends/Toolbar.h" #include "ToolbarBackend.h" @@ -27,7 +29,7 @@ class Tooltips; class XFormsToolbar : public Toolbar { public: /// create an empty toolbar - XFormsToolbar(LyXView * o, int x, int y); + XFormsToolbar(LyXView * o); /// ~XFormsToolbar(); @@ -73,6 +75,13 @@ public: FL_OBJECT * icon; }; + /// + lyx::frontend::Box * toolbar_; + /// + lyx::frontend::BoxList * toolbar_buttons_; + /// + lyx::frontend::WidgetMap widgets_; + typedef std::vector Funcs; Funcs funcs; @@ -87,10 +96,6 @@ public: Tooltips * tooltip_; /// layout combo FL_OBJECT * combox_; - /// x position of end of toolbar - int xpos; - /// y position of end of toolbar - int ypos; }; #endif diff --git a/src/frontends/xforms/XFormsView.C b/src/frontends/xforms/XFormsView.C index e0b7208c16..f3d92b503e 100644 --- a/src/frontends/xforms/XFormsView.C +++ b/src/frontends/xforms/XFormsView.C @@ -27,6 +27,8 @@ #include +using lyx::frontend::Box; + using lyx::support::LibFileSearch; using std::abs; @@ -48,13 +50,80 @@ int C_XFormsView_atCloseMainFormCB(FL_FORM * form, void * p) } +void print_metrics(std::ostream & os, std::string const & name, Box const & box) +{ + os << name << " metrics:" + << "\tx = " << box.xorigin() + << "\ty = " << box.yorigin() + << "\tw = " << box.width() + << "\th = " << box.height() << '\n'; +} + + XFormsView::XFormsView(int width, int height) : LyXView(), + window_(Box(width, height)), icon_pixmap_(0), icon_mask_(0) { - create_form_form_main(width, height); - fl_set_form_atclose(getForm(), C_XFormsView_atCloseMainFormCB, 0); + int const air = 2; + + // Logical layout of the boxes making up the LyX window. + Box & top = window_.children().push_back(Box(0,0)); + Box & middle = window_.children().push_back(Box(0,0)); + middle.set(Box::Horizontal); + Box & bottom = window_.children().push_back(Box(0,0)); + + Box & left = middle.children().push_back(Box(air,0)); + Box & center = middle.children().push_back(Box(0,0)); + center.set(Box::Expand); + Box & right = middle.children().push_back(Box(air,0)); + + // Define accessors to the various boxes. + box_map_[Top] = ⊤ + box_map_[Bottom] = ⊥ + box_map_[Left] = &left; + box_map_[Center] = ¢er; + box_map_[Right] = &right; + + // Define the XForms components making up the window. + // Each uses the layout engine defined above to control its + // dimensions. + form_ = fl_bgn_form(FL_NO_BOX, width, height); + form_->u_vdata = this; + fl_set_form_atclose(form_, C_XFormsView_atCloseMainFormCB, 0); + + FL_OBJECT * obj = fl_add_box(FL_FLAT_BOX, 0, 0, width, height, ""); + fl_set_object_color(obj, FL_MCOL, FL_MCOL); + + menubar_.reset(new XFormsMenubar(this, menubackend)); + + toolbar_.reset(new XFormsToolbar(this)); + toolbar_->init(); + + bufferview_.reset(new BufferView(this, width, height)); + minibuffer_.reset(new XMiniBuffer(*this, *controlcommand_)); + + // Assign an icon to the main form. + string const iconname = LibFileSearch("images", "lyx", "xpm"); + if (!iconname.empty()) { + unsigned int w, h; + icon_pixmap_ = fl_read_pixmapfile(fl_root, + iconname.c_str(), + &w, + &h, + &icon_mask_, + 0, + 0, + 0); + fl_set_form_icon(form_, icon_pixmap_, icon_mask_); + } + + fl_end_form(); + // Update the layout so that all widgets fit. + window_.show(); + updateMetrics(); + view_state_con = view_state_changed.connect(boost::bind(&XFormsView::show_view_state, this)); focus_con = @@ -78,6 +147,14 @@ XFormsView::~XFormsView() } +Box & XFormsView::getBox(Position pos) const +{ + std::map::const_iterator it = box_map_.find(pos); + BOOST_ASSERT(it != box_map_.end()); + return *it->second; +} + + /// Redraw the main form. void XFormsView::redraw() { @@ -121,58 +198,16 @@ void XFormsView::show(int x, int y, string const & title) } -void XFormsView::create_form_form_main(int width, int height) - /* to make this work as it should, .lyxrc should have been - * read first; OR maybe this one should be made dynamic. - * Hmmmm. Lgb. - * We will probably not have lyxrc before the main form is - * initialized, because error messages from lyxrc parsing - * are presented (and rightly so) in GUI popups. Asger. - */ +void XFormsView::updateMetrics() { - // the main form - form_ = fl_bgn_form(FL_NO_BOX, width, height); - getForm()->u_vdata = this; - FL_OBJECT * obj = fl_add_box(FL_FLAT_BOX, 0, 0, width, height, ""); - fl_set_object_color(obj, FL_MCOL, FL_MCOL); - - // Parameters for the appearance of the main form - int const air = 2; - int const bw = abs(fl_get_border_width()); - - menubar_.reset(new XFormsMenubar(this, menubackend)); - - toolbar_.reset(new XFormsToolbar(this, air, 30 + air + bw)); - toolbar_->init(); - - int const ywork = 60 + 2 * air + bw; - int const workheight = height - ywork - (25 + 2 * air); - - bufferview_.reset(new BufferView(this, air, ywork, - width - 3 * air, workheight)); - - minibuffer_.reset(new XMiniBuffer(*controlcommand_, - air, height - (25 + air), width - (2 * air), 25)); + window_.updateMetrics(); - // assign an icon to main form - string const iconname = LibFileSearch("images", "lyx", "xpm"); - if (!iconname.empty()) { - unsigned int w, h; - icon_pixmap_ = fl_read_pixmapfile(fl_root, - iconname.c_str(), - &w, - &h, - &icon_mask_, - 0, - 0, - 0); - fl_set_form_icon(getForm(), icon_pixmap_, icon_mask_); - } - - // set min size - fl_set_form_minsize(getForm(), 50, 50); + FL_FORM * form = getForm(); + fl_set_form_size(form, window_.width(), window_.height()); - fl_end_form(); + // Emit a signal so that all daughter widgets are layed-out + // correctly. + metricsUpdated(); } diff --git a/src/frontends/xforms/XFormsView.h b/src/frontends/xforms/XFormsView.h index d0647277f8..ba67f8e38b 100644 --- a/src/frontends/xforms/XFormsView.h +++ b/src/frontends/xforms/XFormsView.h @@ -12,12 +12,16 @@ #ifndef LyXView_H #define LyXView_H - +#include "LayoutEngine.h" #include "forms_fwd.h" #include "frontends/LyXView.h" #include // for Pixmap +#include + +#include + class XMiniBuffer; /** @@ -27,11 +31,22 @@ class XMiniBuffer; */ class XFormsView : public LyXView { public: + enum Position { + Top, + Bottom, + Left, + Right, + Center + }; + /// create a main window of the given dimensions XFormsView(int w, int h); ~XFormsView(); + /// Accessor to the appropriate layout Box. + lyx::frontend::Box & getBox(Position pos) const; + /** * show - display the top-level window * @param xpos requested x position (or 0) @@ -56,6 +71,8 @@ public: /// clear back to normal status message virtual void clearMessage(); + boost::signal0 metricsUpdated; + private: /** * setWindowTitle - set title of window @@ -67,8 +84,14 @@ private: /// update the minibuffer state message void show_view_state(); - /// makes the main form. - void create_form_form_main(int width, int height); + /// + void updateMetrics(); + /// The top-most box of the layout engine containing all other boxes. + lyx::frontend::Box window_; + + // Accessors to the various Boxes. + std::map box_map_; + /// the minibuffer boost::scoped_ptr minibuffer_; /// diff --git a/src/frontends/xforms/XMiniBuffer.C b/src/frontends/xforms/XMiniBuffer.C index aa0216888b..40854a4b1f 100644 --- a/src/frontends/xforms/XMiniBuffer.C +++ b/src/frontends/xforms/XMiniBuffer.C @@ -12,6 +12,7 @@ #include #include "XMiniBuffer.h" +#include "XFormsView.h" #include "freebrowser.h" #include "xforms_helpers.h" @@ -24,6 +25,9 @@ #include +using lyx::frontend::Box; +using lyx::frontend::BoxList; +using lyx::frontend::WidgetMap; using std::vector; using std::string; @@ -32,22 +36,34 @@ using std::string; namespace { /// This creates the input widget for the minibuffer -FL_OBJECT * create_input_box(void * parent, int type, - FL_Coord, FL_Coord, FL_Coord, FL_Coord); +FL_OBJECT * create_input_box(void * parent, int type); FL_FREEBROWSER * create_freebrowser(void * parent); } // namespace anon -XMiniBuffer::XMiniBuffer(ControlCommandBuffer & control, - FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w) +XMiniBuffer::XMiniBuffer(XFormsView & owner, + ControlCommandBuffer & control) : controller_(control), info_shown_(false) { - input_ = create_input_box(this, FL_NORMAL_INPUT, x, y, h, w); + input_ = create_input_box(this, FL_NORMAL_INPUT); freebrowser_.reset(create_freebrowser(this), fl_free_freebrowser); + // The minibuffer is 25 pixels high and is embedded inside a + // 2 pixel deep frame. + int const air = 2; + + BoxList & boxlist = owner.getBox(XFormsView::Bottom).children(); + minibuffer_ = &boxlist.push_back(Box(0,0)); + Box & center = embed(input_, minibuffer_->children(), widgets_, air); + center.set(Box::Expand); + center.setMinimumDimensions(0, 25); + + owner.metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics, + &widgets_)); + info_timer_.reset(new Timeout(1500)); idle_timer_.reset(new Timeout(6000)); info_con = info_timer_->timeout.connect(boost::bind(&XMiniBuffer::info_timeout, this)); @@ -315,10 +331,9 @@ void C_freebrowserCB(FL_FREEBROWSER * fb, int action) } -FL_OBJECT * create_input_box(void * parent, int type, - FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h) +FL_OBJECT * create_input_box(void * parent, int type) { - FL_OBJECT * obj = fl_add_input(type, x, y, w, h, ""); + FL_OBJECT * obj = fl_add_input(type, 0, 0, 0, 0, ""); fl_set_object_boxtype(obj, FL_DOWN_BOX); fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, SouthWestGravity, SouthEastGravity); diff --git a/src/frontends/xforms/XMiniBuffer.h b/src/frontends/xforms/XMiniBuffer.h index 9ed98d50d2..afea4343c8 100644 --- a/src/frontends/xforms/XMiniBuffer.h +++ b/src/frontends/xforms/XMiniBuffer.h @@ -16,6 +16,8 @@ #include "lyx_forms.h" +#include "LayoutEngine.h" + #include #include #include @@ -23,6 +25,7 @@ struct fl_freebrowser_; typedef fl_freebrowser_ FL_FREEBROWSER; +class XFormsView; class ControlCommandBuffer; class Timeout; @@ -30,8 +33,7 @@ class Timeout; class XMiniBuffer { public: /// - XMiniBuffer(ControlCommandBuffer & control, - FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w); + XMiniBuffer(XFormsView & owner, ControlCommandBuffer & control); /// ~XMiniBuffer(); @@ -102,6 +104,10 @@ private: /// are we showing an informational temporary message ? bool info_shown_; + /// + lyx::frontend::Box * minibuffer_; + /// + lyx::frontend::WidgetMap widgets_; }; #endif // XMINIBUFFER_H diff --git a/src/frontends/xforms/XWorkArea.C b/src/frontends/xforms/XWorkArea.C index 444e532111..4d9893b49c 100644 --- a/src/frontends/xforms/XWorkArea.C +++ b/src/frontends/xforms/XWorkArea.C @@ -12,12 +12,19 @@ #include #include "XWorkArea.h" +#include "XFormsView.h" #include "debug.h" #include "XLyXKeySym.h" #include "funcrequest.h" #include "Timeout.h" +#include + +using lyx::frontend::Box; +using lyx::frontend::BoxList; +using lyx::frontend::WidgetMap; + using std::abs; using std::dec; using std::endl; @@ -96,25 +103,21 @@ int C_event_cb(FL_FORM * form, void * xev) } // namespace anon -XWorkArea::XWorkArea(LyXView & owner, int x, int y, int w, int h) +XWorkArea::XWorkArea(LyXView & owner, int w, int h) : workareapixmap(0), painter_(*this) { - if (lyxerr.debugging(Debug::WORKAREA)) { - lyxerr << "\tbackground box: +" - << x << '+' << y << ' ' - << w - 15 << 'x' << h << endl; - } - fl_freeze_all_forms(); FL_OBJECT * obj; + FL_OBJECT * frame; - obj = fl_add_box(FL_BORDER_BOX, x, y, w - 15, h, ""); + // A frame around the work area. + frame = obj = fl_add_box(FL_BORDER_BOX, 0, 0, w, h, ""); fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity); - scrollbar = obj = fl_add_scrollbar(FL_VERT_SCROLLBAR, - x + w - 15, y, 17, h, ""); + // The scrollbar. + scrollbar = obj = fl_add_scrollbar(FL_VERT_SCROLLBAR, 0, 0, w, h, ""); fl_set_object_boxtype(obj, FL_UP_BOX); fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity); @@ -124,24 +127,8 @@ XWorkArea::XWorkArea(LyXView & owner, int x, int y, int w, int h) fl_set_scrollbar_value(scrollbar, 0.0); fl_set_scrollbar_size(scrollbar, scrollbar->h); - int const bw = int(abs(fl_get_border_width())); - - // Create the workarea pixmap - // FIXME remove redraw(w - 15 - 2 * bw, h - 2 * bw); - - if (lyxerr.debugging(Debug::WORKAREA)) - lyxerr << "\tfree object: +" - << x + bw << '+' << y + bw << ' ' - << w - 15 - 2 * bw << 'x' - << h - 2 * bw << endl; - - // We add this object as late as possible to avoid problems - // with drawing. - // FIXME: like ?? - work_area = obj = fl_add_free(FL_ALL_FREE, - x + bw, y + bw, - w - 15 - 2 * bw, - h - 2 * bw, "", + // The work area itself + work_area = obj = fl_add_free(FL_ALL_FREE, 0, 0, w, h, "", C_work_area_handler); obj->wantkey = FL_KEY_ALL; obj->u_vdata = this; @@ -150,6 +137,26 @@ XWorkArea::XWorkArea(LyXView & owner, int x, int y, int w, int h) fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity); + // Hand control of the layout of these widgets to the + // Layout Engine. + XFormsView & xview = dynamic_cast(owner); + BoxList & boxlist = xview.getBox(XFormsView::Center).children(); + + wa_box_ = &boxlist.push_back(Box(0,0)); + wa_box_->set(Box::Horizontal); + + Box & frame_box = widgets_.add(frame, wa_box_->children(), 0, 0); + frame_box.set(Box::Expand); + + int const bw = int(abs(fl_get_border_width())); + Box & wa_box = embed(work_area, frame_box.children(), widgets_, bw); + wa_box.set(Box::Expand); + + widgets_.add(scrollbar, wa_box_->children(), 17, 0); + + xview.metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics, + &widgets_)); + /// X selection hook - xforms gets it wrong fl_current_form->u_vdata = this; fl_register_raw_callback(fl_current_form, FL_ALL_EVENT, C_event_cb); diff --git a/src/frontends/xforms/XWorkArea.h b/src/frontends/xforms/XWorkArea.h index 9afc1ba5c7..22d6274da4 100644 --- a/src/frontends/xforms/XWorkArea.h +++ b/src/frontends/xforms/XWorkArea.h @@ -16,6 +16,8 @@ #include "frontends/WorkArea.h" #include "XPainter.h" +#include "LayoutEngine.h" + #include "lyx_forms.h" class LyXView; @@ -24,7 +26,7 @@ class LyXView; class XWorkArea : public WorkArea { public: /// - XWorkArea(LyXView & owner, int xpos, int ypos, int width, int height); + XWorkArea(LyXView & owner, int width, int height); /// ~XWorkArea(); /// @@ -80,6 +82,10 @@ private: bool screen_cleared; /// the current document's height (for scrollbar) int doc_height_; + /// + lyx::frontend::Box * wa_box_; + /// + lyx::frontend::WidgetMap widgets_; }; #endif // XWORKAREA_H