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
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))
{}
* 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();
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
///
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
+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.
+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.
* 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
+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.
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(
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);
}
+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.
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);
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
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));
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
+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.
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
FormVSpace.h \
FormWrap.C \
FormWrap.h \
+ LayoutEngine.C \
+ LayoutEngine.h \
LyXKeySymFactory.C \
LyXScreenFactory.C \
XFormsMenubar.C \
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);
}
}
#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;
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());
}
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) {
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);
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);
buttonlist_.push_back(iteminfo);
obj->u_vdata = iteminfo.get();
}
-
}
#include "funcrequest.h"
#include "frontends/Menubar.h"
+#include "LayoutEngine.h"
+
#include <boost/shared_ptr.hpp>
#include "forms_fwd.h"
///
MenuBackend const * menubackend_;
///
+ lyx::frontend::Box * menubar_;
+ ///
+ lyx::frontend::WidgetMap widgets_;
+ ///
struct ItemInfo {
///
ItemInfo(XFormsMenubar * p, MenuItem const * i,
#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;
-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_));
}
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();
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);
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,
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;
}
}
#include <vector>
#include "forms_fwd.h"
+#include "LayoutEngine.h"
+
#include "frontends/Toolbar.h"
#include "ToolbarBackend.h"
class XFormsToolbar : public Toolbar {
public:
/// create an empty toolbar
- XFormsToolbar(LyXView * o, int x, int y);
+ XFormsToolbar(LyXView * o);
///
~XFormsToolbar();
FL_OBJECT * icon;
};
+ ///
+ lyx::frontend::Box * toolbar_;
+ ///
+ lyx::frontend::BoxList * toolbar_buttons_;
+ ///
+ lyx::frontend::WidgetMap widgets_;
+
typedef std::vector<FuncRequest> Funcs;
Funcs funcs;
Tooltips * tooltip_;
/// layout combo
FL_OBJECT * combox_;
- /// x position of end of toolbar
- int xpos;
- /// y position of end of toolbar
- int ypos;
};
#endif
#include <boost/bind.hpp>
+using lyx::frontend::Box;
+
using lyx::support::LibFileSearch;
using std::abs;
}
+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 =
}
+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()
{
}
-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();
}
#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;
/**
*/
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)
/// clear back to normal status message
virtual void clearMessage();
+ boost::signal0<void> metricsUpdated;
+
private:
/**
* setWindowTitle - set title of window
/// 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_;
///
#include <config.h>
#include "XMiniBuffer.h"
+#include "XFormsView.h"
#include "freebrowser.h"
#include "xforms_helpers.h"
#include <boost/bind.hpp>
+using lyx::frontend::Box;
+using lyx::frontend::BoxList;
+using lyx::frontend::WidgetMap;
using std::vector;
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));
}
-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);
#include "lyx_forms.h"
+#include "LayoutEngine.h"
+
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/signals/connection.hpp>
struct fl_freebrowser_;
typedef fl_freebrowser_ FL_FREEBROWSER;
+class XFormsView;
class ControlCommandBuffer;
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();
/// are we showing an informational temporary message ?
bool info_shown_;
+ ///
+ lyx::frontend::Box * minibuffer_;
+ ///
+ lyx::frontend::WidgetMap widgets_;
};
#endif // XMINIBUFFER_H
#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;
} // 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);
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;
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);
#include "frontends/WorkArea.h"
#include "XPainter.h"
+#include "LayoutEngine.h"
+
#include "lyx_forms.h"
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();
///
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