mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
A layout engine for XForms.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8704 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
dd01380a27
commit
b03580df17
@ -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
|
||||
|
@ -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))
|
||||
{}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
468
src/frontends/xforms/LayoutEngine.C
Normal file
468
src/frontends/xforms/LayoutEngine.C
Normal file
@ -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
|
189
src/frontends/xforms/LayoutEngine.h
Normal file
189
src/frontends/xforms/LayoutEngine.h
Normal file
@ -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
|
@ -149,6 +149,8 @@ libxforms_la_SOURCES = \
|
||||
FormVSpace.h \
|
||||
FormWrap.C \
|
||||
FormWrap.h \
|
||||
LayoutEngine.C \
|
||||
LayoutEngine.h \
|
||||
LyXKeySymFactory.C \
|
||||
LyXScreenFactory.C \
|
||||
XFormsMenubar.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,8 +23,13 @@
|
||||
#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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -30,6 +30,11 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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] = ⊤
|
||||
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<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);
|
||||
window_.updateMetrics();
|
||||
|
||||
// Parameters for the appearance of the main form
|
||||
int const air = 2;
|
||||
int const bw = abs(fl_get_border_width());
|
||||
FL_FORM * form = getForm();
|
||||
fl_set_form_size(form, window_.width(), window_.height());
|
||||
|
||||
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));
|
||||
|
||||
// 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_end_form();
|
||||
// Emit a signal so that all daughter widgets are layed-out
|
||||
// correctly.
|
||||
metricsUpdated();
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,12 +12,16 @@
|
||||
#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_;
|
||||
///
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -12,12 +12,19 @@
|
||||
#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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user