]> git.lyx.org Git - features.git/commitdiff
A layout engine for XForms.
authorAngus Leeming <leeming@lyx.org>
Wed, 28 Apr 2004 17:22:05 +0000 (17:22 +0000)
committerAngus Leeming <leeming@lyx.org>
Wed, 28 Apr 2004 17:22:05 +0000 (17:22 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8704 a592a061-630c-0410-9148-cb99ea01b6c8

31 files changed:
po/POTFILES.in
src/BufferView.C
src/BufferView.h
src/BufferView_pimpl.C
src/BufferView_pimpl.h
src/ChangeLog
src/frontends/ChangeLog
src/frontends/WorkAreaFactory.h
src/frontends/gtk/ChangeLog
src/frontends/gtk/GView.C
src/frontends/gtk/WorkAreaFactory.C
src/frontends/qt2/ChangeLog
src/frontends/qt2/QWorkArea.C
src/frontends/qt2/QWorkArea.h
src/frontends/qt2/QtView.C
src/frontends/qt2/WorkAreaFactory.C
src/frontends/xforms/ChangeLog
src/frontends/xforms/LayoutEngine.C [new file with mode: 0644]
src/frontends/xforms/LayoutEngine.h [new file with mode: 0644]
src/frontends/xforms/Makefile.am
src/frontends/xforms/WorkAreaFactory.C
src/frontends/xforms/XFormsMenubar.C
src/frontends/xforms/XFormsMenubar.h
src/frontends/xforms/XFormsToolbar.C
src/frontends/xforms/XFormsToolbar.h
src/frontends/xforms/XFormsView.C
src/frontends/xforms/XFormsView.h
src/frontends/xforms/XMiniBuffer.C
src/frontends/xforms/XMiniBuffer.h
src/frontends/xforms/XWorkArea.C
src/frontends/xforms/XWorkArea.h

index 6e837e3f78155471cb3a275faec8505e360fc537..2f914c23428f517e53f79bc0435fb690db33cc4a 100644 (file)
@@ -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
index ec90ecea575a018f0da435ea800917e15617d1b9..2763929f1df1590b46da90b6493902f0d460a69b 100644 (file)
@@ -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))
 {}
 
 
index 11df87578044eec883dd320634af0a0eead21e9a..8bbb970012343f1a28060d73350fe90b8d75d746 100644 (file)
@@ -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();
 
index f9adcc0cf26672bc67f1e181e3539f19d8bbaa7d..c1c9968bfb608a4c31a2bb5d250ff5fcec52dfa4 100644 (file)
@@ -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
index d98925866c443819e2cf567a3f3ba0053491e733..6c6766af2b110bc82d012edca9fbc9bc06b67a29 100644 (file)
@@ -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
index eed92477a0be036542e5198cda07371abfcf03d3..a6dddf70b80b066ddec3a2b730c4a3d71f916e63 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-28  Angus Leeming  <leeming@lyx.org>
+
+       * 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  <leeming@lyx.org>
 
        * BufferView_pimpl.C (c-tor): pass LyXView & to WorkArea generator.
index ea71af020a18f5b2165196ec812a97e7edd3dddd..623e6d5d5cbb0ee39312aace1b79762116bb20e3 100644 (file)
@@ -1,3 +1,8 @@
+2004-04-28  Angus Leeming  <leeming@lyx.org>
+
+       * WorkAreaFactory.h (create): passed a LyXView &.
+       No longer passed x, y data.
+
 2004-04-27  Angus Leeming  <leeming@lyx.org>
 
        * Dialogs.h: add myself as author.
index 12d8d76ae9e7355e7045f8764dea6217e6042424..ca679bf6ef6f4cc902a10c18986dbe87de56de73 100644 (file)
@@ -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
index 69113690cba4580f3f067a47fe52438a9f8246ac..10ca09105ef5c66056efdd41662db8712ff3ea37 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-28  Angus Leeming  <leeming@lyx.org>
+
+       * 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  <leeming@lyx.org>
 
        * WorkAreaFactory.C (create): pass a LyXView & to GWorkArea c-tor.
index b9b22248a147fb20f2fd568f8b375df80869387a..fa1cac9932b483a9fbc2f168b9bbcd9f847c1c45 100644 (file)
@@ -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(
index 7d8dcc18e3a1b3c7bc9b52d9f64619eaf7dcf881..e1c74cf8274d46730ff05eb88daaec1fc37cde07 100644 (file)
@@ -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);
 }
index 0b5055eb707b66ba432d37c7d5833c51b6d0be02..79f853b120ff89fbc2706d83169615687cf4c9eb 100644 (file)
@@ -1,3 +1,11 @@
+2004-04-28  Angus Leeming  <leeming@lyx.org>
+
+       * 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  <leeming@lyx.org>
 
        * WorkAreaFactory.C (create): pass a LyXView & to QWorkArea c-tor.
index 4426ca1f32fbb5c9ef2f4c5431aa026ef9d3de3f..5e105e1d44c6a119d29c0b214a1a025fc94f032b 100644 (file)
@@ -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);
index 3f241c20ba1bc808173b865cb8c08f962fce3ff7..092ef03a7f9d401cecb22383d7443dd9aeb251d6 100644 (file)
@@ -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
index 6eb8197ea40d16e2c4d4d5003c47322218916478..1f81096c305a6d061905b9e1ec7d618a259c1c78 100644 (file)
@@ -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));
index 477e5eae53cd1fcf79cb8aee815ccb1d5c42b454..3277a944cf4f4dadd578569aba245161bea35789 100644 (file)
@@ -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
index 80771c5d13899a0bc11efff62deb2101abbd1f46..44070db863017a7a11f7beda16ac80f3a27cd699 100644 (file)
@@ -1,3 +1,18 @@
+2004-04-28  Angus Leeming  <leeming@lyx.org>
+
+       * 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  <leeming@lyx.org>
 
        * 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 (file)
index 0000000..1d1d61e
--- /dev/null
@@ -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 <boost/assert.hpp>
+
+
+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 (file)
index 0000000..c15379e
--- /dev/null
@@ -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 <list>
+#include <map>
+
+namespace lyx {
+namespace frontend {
+
+class Box;
+
+class BoxList {
+public:
+       typedef std::list<Box> 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<FL_OBJECT *, Box *> 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
index 337554709692c37f5850c9b830e4ab4b59303020..ec7b0ffc86f76d8670e918753b206814e3b0ef54 100644 (file)
@@ -149,6 +149,8 @@ libxforms_la_SOURCES = \
        FormVSpace.h \
        FormWrap.C \
        FormWrap.h \
+       LayoutEngine.C \
+       LayoutEngine.h \
        LyXKeySymFactory.C \
        LyXScreenFactory.C \
        XFormsMenubar.C \
index 49513a13ad94a7f60e05f4d7b12b033899177fc8..8158ee0191a708853ad4864bbea387ee52635227 100644 (file)
@@ -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);
 }
 
 }
index e8a3c0f4216fbb4a1e0471e8b8b58e854a4937ba..a52ffe6c88938c08bf92e127aa1fa0b9681b070b 100644 (file)
 #include "support/lstrings.h"
 #include "support/tostr.h"
 
+#include <boost/bind.hpp>
+
 #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<XFormsView*>(view)), menubackend_(&mb)
+       : owner_(static_cast<XFormsView*>(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();
        }
-
 }
 
 
index d43061d71bfced7b0b686b9d5c051cf0773b043c..ded13fb8622c3f6611bb8a358e19b202bfe3c286 100644 (file)
@@ -15,6 +15,8 @@
 #include "funcrequest.h"
 #include "frontends/Menubar.h"
 
+#include "LayoutEngine.h"
+
 #include <boost/shared_ptr.hpp>
 
 #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,
index d288cd7b97fac90700c5bdf5b58aad148cfb5ae4..69f8e07eb382809b5579577886d270579de2e1a3 100644 (file)
 #include "lyx_forms.h"
 #include "combox.h"
 
+#include <boost/bind.hpp>
+
+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<XFormsView *>(o)), combox_(0), xpos(x), ypos(y)
+XFormsToolbar::XFormsToolbar(LyXView * o)
+       : toolbar_(0),
+         toolbar_buttons_(0),
+         owner_(static_cast<XFormsView *>(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;
        }
        }
index f74fde1b15478eac9801d6110f4bef852e6d45b4..6183bab2bf7ebdf0e0b62ebc28049f880666cd91 100644 (file)
@@ -16,6 +16,8 @@
 #include <vector>
 #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<FuncRequest> 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
index e0b7208c1692f13299fc623ec013e5a9017436d6..f3d92b503ed358904b452770663e06363f4f4318 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <boost/bind.hpp>
 
+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]    = &top;
+       box_map_[Bottom] = &bottom;
+       box_map_[Left]   = &left;
+       box_map_[Center] = &center;
+       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<Position, Box *>::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();
 }
 
 
index d0647277f8e2a39e5bcaa34ae8a4d9104a659e75..ba67f8e38b06329d3d165ebdc9034c695cc493d3 100644 (file)
 #ifndef LyXView_H
 #define LyXView_H
 
-
+#include "LayoutEngine.h"
 #include "forms_fwd.h"
 
 #include "frontends/LyXView.h"
 #include <X11/Xlib.h> // for Pixmap
 
+#include <boost/signals/signal0.hpp>
+
+#include <map>
+
 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<void> 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<Position, lyx::frontend::Box *> box_map_;
+
        /// the minibuffer
        boost::scoped_ptr<XMiniBuffer> minibuffer_;
        ///
index aa0216888b6320c113be41e26245ed3fc2dfba41..40854a4b1f874599adec77b57c029826487f50fa 100644 (file)
@@ -12,6 +12,7 @@
 #include <config.h>
 
 #include "XMiniBuffer.h"
+#include "XFormsView.h"
 
 #include "freebrowser.h"
 #include "xforms_helpers.h"
@@ -24,6 +25,9 @@
 
 #include <boost/bind.hpp>
 
+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);
index 9ed98d50d27654e385bb212e653cf4f0a893a58b..afea4343c8ea4061ea8a5adb65e9df8af91b5025 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "lyx_forms.h"
 
+#include "LayoutEngine.h"
+
 #include <boost/scoped_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/signals/connection.hpp>
@@ -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
index 444e53211189a7b31d764c5ad18addd8938bdb6e..4d9893b49c471a3ea54ed0e0fb29e4a20a445ea8 100644 (file)
 #include <config.h>
 
 #include "XWorkArea.h"
+#include "XFormsView.h"
 
 #include "debug.h"
 #include "XLyXKeySym.h"
 #include "funcrequest.h"
 #include "Timeout.h"
 
+#include <boost/bind.hpp>
+
+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<XFormsView &>(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);
index 9afc1ba5c776c6843926de5b6e4a371e0a2a0380..22d6274da46b1ffc56759dced204865ebead9a08 100644 (file)
@@ -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