* Positionable and dynamically visible toolbars for the XForms frontend.

* General Toolbars code clean-up.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8707 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2004-04-29 09:54:59 +00:00
parent b36c13278b
commit 5009d66e16
29 changed files with 1150 additions and 912 deletions

View File

@ -349,7 +349,7 @@ void BufferView::Pimpl::setBuffer(Buffer * b)
update();
updateScrollbar();
owner_->updateMenubar();
owner_->updateToolbar();
owner_->updateToolbars();
owner_->updateLayoutChoice();
owner_->updateWindowTitle();
@ -902,7 +902,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
// skip these when selecting
if (cmd.action != LFUN_MOUSE_MOTION) {
owner_->updateLayoutChoice();
owner_->updateToolbar();
owner_->updateToolbars();
}
// slight hack: this is only called currently when we

View File

@ -2,6 +2,14 @@
* buffer.C: increment format to 233.
2004-04-28 Angus Leeming <leeming@lyx.org>
* BufferView_pimpl.C:
* lyxfunc.C:
* text3.C:
s/updateToolbar()/updateToolbars()/
s/Toolbar.h/Toolbars.h/
2004-04-28 Angus Leeming <leeming@lyx.org>
* BufferView.[Ch] (c-tor):

View File

@ -1,3 +1,16 @@
2004-04-28 Angus Leeming <leeming@lyx.org>
* LyXView.[Ch]:
s/Toolbar.h/Toolbars.h/
s/toolbar_/toolbars_/
s/getToolbar()/getToolbars()/
s/updateToolbar()/updateToolbars()/
Make the toolbars_ private.
* Toolbar.[Ch]: removed.
* Toolbars.[Ch]: new files. The old Toolbar class is split into
three new classes, LayoutBox, Toolbar and Toolbars.
2004-04-28 Angus Leeming <leeming@lyx.org>
* WorkAreaFactory.h (create): passed a LyXView &.

View File

@ -14,7 +14,7 @@
#include "LyXView.h"
#include "Dialogs.h"
#include "Timeout.h"
#include "Toolbar.h"
#include "Toolbars.h"
#include "Menubar.h"
#include "buffer.h"
@ -53,7 +53,8 @@ string current_layout;
LyXView::LyXView()
: intl_(new Intl),
: toolbars_(new Toolbars(*this)),
intl_(new Intl),
autosave_timeout_(new Timeout(5000)),
lyxfunc_(new LyXFunc(this)),
dialogs_(new Dialogs(*this)),
@ -98,16 +99,16 @@ boost::shared_ptr<BufferView> const & LyXView::view() const
void LyXView::setLayout(string const & layout)
{
toolbar_->setLayout(layout);
toolbars_->setLayout(layout);
}
void LyXView::updateToolbar()
void LyXView::updateToolbars()
{
bool const math = bufferview_->cursor().inMathed();
bool const table =
getLyXFunc().getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
toolbar_->update(math, table);
toolbars_->update(math, table);
}
@ -138,12 +139,12 @@ void LyXView::updateLayoutChoice()
{
// don't show any layouts without a buffer
if (!view()->buffer()) {
toolbar_->clearLayoutList();
toolbars_->clearLayoutList();
return;
}
// update the layout display
if (toolbar_->updateLayoutList(buffer()->params().textclass)) {
if (toolbars_->updateLayoutList(buffer()->params().textclass)) {
current_layout = buffer()->params().getLyXTextClass().defaultLayoutName();
}
@ -154,7 +155,7 @@ void LyXView::updateLayoutChoice()
bufferview_->cursor().paragraph().layout()->name();
if (layout != current_layout) {
toolbar_->setLayout(layout);
toolbars_->setLayout(layout);
current_layout = layout;
}
}

View File

@ -20,7 +20,7 @@
#include <boost/signals/signal0.hpp>
class Buffer;
class Toolbar;
class Toolbars;
class InsetBase;
class Intl;
class Menubar;
@ -80,9 +80,9 @@ public:
LyXFunc const & getLyXFunc() const { return *lyxfunc_.get(); }
/// return the toolbar for this view
Toolbar & getToolbar() { return *toolbar_.get(); }
Toolbars & getToolbars() { return *toolbars_.get(); }
///
Toolbar const & getToolbar() const { return *toolbar_.get(); }
Toolbars const & getToolbasr() const { return *toolbars_.get(); }
/// return the menubar for this view
Menubar & getMenubar() { return *menubar_.get(); }
@ -107,7 +107,7 @@ public:
void updateLayoutChoice();
/// update the toolbar
void updateToolbar();
void updateToolbars();
/// update the menubar
void updateMenubar();
@ -143,8 +143,6 @@ protected:
/// view's menubar
boost::scoped_ptr<Menubar> menubar_;
/// view's toolbar
boost::scoped_ptr<Toolbar> toolbar_;
private:
/**
@ -157,6 +155,8 @@ private:
/// called on timeout
void autoSave();
/// view's toolbar
boost::scoped_ptr<Toolbars> toolbars_;
/// keyboard mapping object
boost::scoped_ptr<Intl> const intl_;
/// auto-saving of buffers

View File

@ -25,8 +25,8 @@ libfrontends_la_SOURCES = \
Painter.h \
Timeout.C \
Timeout.h \
Toolbar.C \
Toolbar.h \
Toolbars.C \
Toolbars.h \
WorkArea.h \
WorkAreaFactory.h \
font_metrics.h \

View File

@ -1,93 +0,0 @@
/**
* \file Toolbar.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "Toolbar.h"
#include "debug.h"
#include "LyXAction.h"
#include "ToolbarBackend.h"
using std::string;
using std::endl;
Toolbar::Toolbar()
: last_textclass_(-1)
{
}
Toolbar::~Toolbar()
{
}
void Toolbar::init()
{
// extracts the toolbars from the backend
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit)
add(*cit);
}
void Toolbar::display(string const & name, bool show)
{
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->name == name) {
displayToolbar(*cit, show);
return;
}
}
lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
<< name << endl;
}
void Toolbar::update(bool in_math, bool in_table)
{
update();
// extracts the toolbars from the backend
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->flags & ToolbarBackend::MATH)
displayToolbar(*cit, in_math);
else if (cit->flags & ToolbarBackend::TABLE)
displayToolbar(*cit, in_table);
}
}
void Toolbar::clearLayoutList()
{
last_textclass_ = -1;
}
bool Toolbar::updateLayoutList(int textclass)
{
// update the layout display
if (last_textclass_ != textclass) {
updateLayoutList();
last_textclass_ = textclass;
return true;
} else
return false;
}

View File

@ -1,73 +0,0 @@
// -*- C++ -*-
/**
* \file Toolbar.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
*
* Full author contact details are available in file CREDITS.
*/
#ifndef TOOLBAR_H
#define TOOLBAR_H
#include "ToolbarBackend.h"
class LyXView;
/**
* The LyX GUI independent toolbar class
*
* The GUI interface is implemented in the corresponding Toolbar_pimpl class.
*/
class Toolbar {
public:
///
Toolbar();
///
virtual ~Toolbar();
/// Initialize toolbar from backend
void init();
/// update the state of the toolbars
void update(bool in_math, bool in_table);
/// show/hide the named toolbar
void display(std::string const & name, bool show);
/// update the layout combox
virtual void setLayout(std::string const & layout) = 0;
/**
* Populate the layout combox - returns whether we did a full
* update or not
*/
bool updateLayoutList(int textclass);
/// Drop down the layout list
virtual void openLayoutList() = 0;
/// Erase the layout list
virtual void clearLayoutList();
private:
virtual void add(ToolbarBackend::Toolbar const & tb) = 0;
/// update the state of the icons
virtual void update() = 0;
/// show or hide a toolbar
virtual void displayToolbar(ToolbarBackend::Toolbar const & tb,
bool show) = 0;
/// Populate the layout combox.
virtual void updateLayoutList() = 0;
/**
* The last textclass layout list in the layout choice selector
*/
int last_textclass_;
};
#endif

153
src/frontends/Toolbars.C Normal file
View File

@ -0,0 +1,153 @@
/**
* \file Toolbars.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "Toolbars.h"
#include "debug.h"
#include "funcrequest.h"
#include "FuncStatus.h"
#include "lyxfunc.h"
#include "LyXView.h"
using std::endl;
using std::string;
Toolbars::Toolbars(LyXView & owner)
: owner_(owner),
layout_(0),
last_textclass_(-1)
{}
void Toolbars::init()
{
// extracts the toolbars from the backend
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit)
add(*cit);
}
void Toolbars::display(string const & name, bool show)
{
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->name == name) {
displayToolbar(*cit, show);
return;
}
}
lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
<< name << endl;
}
void Toolbars::update(bool in_math, bool in_table)
{
update();
// extracts the toolbars from the backend
ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
for (; cit != end; ++cit) {
if (cit->flags & ToolbarBackend::MATH)
displayToolbar(*cit, in_math);
else if (cit->flags & ToolbarBackend::TABLE)
displayToolbar(*cit, in_table);
}
}
void Toolbars::setLayout(string const & layout)
{
if (layout_)
layout_->set(layout);
}
bool Toolbars::updateLayoutList(int textclass)
{
// update the layout display
if (last_textclass_ != textclass) {
if (layout_)
layout_->update();
last_textclass_ = textclass;
return true;
} else
return false;
}
void Toolbars::openLayoutList()
{
if (layout_)
layout_->open();
}
void Toolbars::clearLayoutList()
{
last_textclass_ = -1;
if (layout_)
layout_->clear();
}
void Toolbars::add(ToolbarBackend::Toolbar const & tbb)
{
ToolbarPtr tb_ptr = make_toolbar(tbb, owner_);
toolbars_[tbb.name] = tb_ptr;
if (tbb.flags & ToolbarBackend::ON)
tb_ptr->show(false);
else
tb_ptr->hide(false);
if (tb_ptr->layout())
layout_ = tb_ptr->layout();
}
void Toolbars::displayToolbar(ToolbarBackend::Toolbar const & tbb,
bool show_it)
{
ToolbarsMap::iterator it = toolbars_.find(tbb.name);
BOOST_ASSERT(it != toolbars_.end());
if (show_it)
it->second->show(true);
else
it->second->hide(true);
}
void Toolbars::update()
{
ToolbarsMap::const_iterator it = toolbars_.begin();
ToolbarsMap::const_iterator const end = toolbars_.end();
for (; it != end; ++it)
it->second->update();
bool const enable = owner_.getLyXFunc().
getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
if (layout_)
layout_->setEnabled(enable);
}

136
src/frontends/Toolbars.h Normal file
View File

@ -0,0 +1,136 @@
// -*- C++ -*-
/**
* \file Toolbars.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*
* The Toolbars class is a container of toolbars.
* It provides accessors to each Toolbar and to the LayoutBox.
*
* Each GUI frontend should provide toolbar and layout boxes by derivation
* from the LayoutBox and Toolbar pure abstract classes.
*
* The Toolbars class has no knowledge at all of the details of each
* frontend's implementation, which requires that each frontend should
* provide a 'make_toolbar' function, signature below.
*/
#ifndef TOOLBARS_H
#define TOOLBARS_H
#include "ToolbarBackend.h"
#include <boost/shared_ptr.hpp>
#include <map>
class LyXView;
class LayoutBox {
public:
virtual ~LayoutBox() {}
/// Select the correct layout in the combox.
virtual void set(std::string const & layout) = 0;
/// Populate the layout combox.
virtual void update() = 0;
/// Erase the layout list.
virtual void clear() = 0;
/// Display the layout list.
virtual void open() = 0;
/// Set the activation status of the combox.
virtual void setEnabled(bool) = 0;
};
class Toolbar {
public:
virtual ~Toolbar() {}
/// Add a button to the bar.
virtual void add(FuncRequest const & func,
std::string const & tooltip) = 0;
/** Hide the bar.
* \param update_metrics is a hint to the layout engine that the
* metrics should be updated.
*/
virtual void hide(bool update_metrics) = 0;
/** Show the bar.
* \param update_metrics is a hint to the layout engine that the
* metrics should be updated.
*/
virtual void show(bool update_metrics) = 0;
/// Refresh the contents of the bar.
virtual void update() = 0;
/// Accessor to the layout combox, if any.
virtual LayoutBox * layout() const = 0;
};
class Toolbars {
public:
///
Toolbars(LyXView & owner);
/// Initialize the toolbars using the backend database.
void init();
/// Show/hide the named toolbar.
void display(std::string const & name, bool show);
/// Update the state of the toolbars.
void update(bool in_math, bool in_table);
/// Select the right layout in the combox.
void setLayout(std::string const & layout);
/** Populate the layout combox - returns whether we did a full
* update or not
*/
bool updateLayoutList(int textclass);
/// Drop down the layout list.
void openLayoutList();
/// Erase the layout list.
void clearLayoutList();
///
typedef boost::shared_ptr<Toolbar> ToolbarPtr;
private:
/// Add a new toolbar.
void add(ToolbarBackend::Toolbar const & tb);
/// Show or hide a toolbar.
void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
/// Update the state of the icons
void update();
/// The parent window.
LyXView & owner_;
/** The layout box is actually owned by whichever toolbar
* contains it. All the Toolbars class needs is a means of
* accessing it.
*
* We don't need to use boost::weak_ptr here because the toolbars
* are also stored here. There are, therefore, no lifetime issues.
*/
LayoutBox * layout_;
/// Toolbar store providing access to individual toolbars by name.
typedef std::map<std::string, ToolbarPtr> ToolbarsMap;
ToolbarsMap toolbars_;
/// The last textclass layout list in the layout choice selector
int last_textclass_;
};
/** Each GUI frontend should provide its own version of this.
*/
Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const &, LyXView &);
#endif // NOT TOOLBARS_H

View File

@ -1,3 +1,10 @@
2004-04-28 Angus Leeming <leeming@lyx.org>
* GToolbar.[Ch]: rewrite code to derive from a single Toolbar or
LayoutBox.
* GView.C: small changes due to changed Toolbar API.
2004-04-28 Angus Leeming <leeming@lyx.org>
* WorkAreaFactory.C (create): No longer passed x, y data.

View File

@ -13,26 +13,21 @@
#include "GToolbar.h"
#include "GView.h"
#include "LyXAction.h"
#include "lyxfunc.h"
#include "FuncStatus.h"
#include "buffer.h"
#include "bufferparams.h"
#include "funcrequest.h"
#include "gettext.h"
#include "Tooltips.h"
#include "support/filetools.h"
#include "support/lstrings.h"
#include "debug.h"
#include "funcrequest.h"
#include "FuncStatus.h"
#include "lyxfunc.h"
using std::string;
namespace
{
namespace {
GView::Position getPosition(ToolbarBackend::Flags const & flags)
{
{
if (flags & ToolbarBackend::TOP)
return GView::Top;
if (flags & ToolbarBackend::BOTTOM)
@ -51,10 +46,7 @@ LyXTextClass const & getTextClass(LyXView const & lv)
}
char const * gToolData = "tool_data";
inline void comboClear(Gtk::Combo & combo)
void comboClear(Gtk::Combo & combo)
{
std::vector<Glib::ustring> strings;
strings.push_back("");
@ -62,238 +54,241 @@ inline void comboClear(Gtk::Combo & combo)
}
inline bool comboIsEmpty(Gtk::Combo & combo)
bool comboIsEmpty(Gtk::Combo & combo)
{
std::vector<Glib::ustring> strings = combo.get_popdown_strings();
return (strings.empty() || (strings.size() == 1 && strings[0] == ""));
}
char const * gToolData = "tool_data";
} // namespace anon
GLayoutBox::GLayoutBox(LyXView & owner,
Gtk::Toolbar & toolbar,
FuncRequest const & func)
: owner_(owner),
internal_(false)
{
combo_.set_value_in_list();
combo_.get_entry()->set_editable(false);
combo_.unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
combo_.get_entry()->unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
comboClear(combo_);
combo_.get_entry()->signal_changed().connect(
SigC::slot(*this,
&GLayoutBox::selected));
combo_.show();
toolbar.tools().push_back(Gtk::Toolbar_Helpers::Element(combo_));
toolbar.tools().back().get_widget()->set_data(
gToolData,
reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
}
GToolbar::GToolbar(LyXView * lyxView, int /*x*/, int /*y*/)
: view_(lyxView), internal_(false)
void GLayoutBox::set(string const & layout)
{
combo_.set_value_in_list();
combo_.get_entry()->set_editable(false);
combo_.unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
combo_.get_entry()->unset_flags(Gtk::CAN_FOCUS | Gtk::CAN_DEFAULT);
comboClear(combo_);
combo_.get_entry()->signal_changed().connect(
SigC::slot(*this,
&GToolbar::onLayoutSelected));
}
LyXTextClass const & tc = getTextClass(owner_);
GToolbar::~GToolbar()
{}
void GToolbar::add(ToolbarBackend::Toolbar const & tbb)
{
Gtk::Toolbar * toolbar = manage(new Gtk::Toolbar);
ToolbarBackend::item_iterator it = tbb.items.begin();
ToolbarBackend::item_iterator end = tbb.items.end();
for (; it != end; ++it)
add(toolbar, *it);
toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS);
GView::Position const position = getPosition(tbb.flags);
if (position == GView::Left || position == GView::Right)
toolbar->set_orientation(Gtk::ORIENTATION_VERTICAL);
GView * gview = static_cast<GView*>(view_);
gview->getBox(position).children().push_back(
Gtk::Box_Helpers::Element(*toolbar, Gtk::PACK_SHRINK));
if (tbb.flags & ToolbarBackend::ON)
toolbar->show();
toolbars_[tbb.name] = toolbar;
}
void GToolbar::add(Gtk::Toolbar * toolbar,
ToolbarBackend::Item const & item)
{
FuncRequest const & func = item.first;
string const & tooltip = item.second;
switch (func.action) {
case ToolbarBackend::SEPARATOR:
toolbar->tools().push_back(Gtk::Toolbar_Helpers::Space());
break;
case ToolbarBackend::MINIBUFFER:
// Not supported yet.
break;
case ToolbarBackend::LAYOUTS:
{
combo_.show();
toolbar->tools().push_back(
Gtk::Toolbar_Helpers::Element(combo_));
toolbar->tools().back().get_widget()->set_data(
gToolData,
reinterpret_cast<void*>(&const_cast<ToolbarBackend::Item&>(item)));
break;
}
default:
{
Glib::ustring xpmName =
Glib::locale_to_utf8(toolbarbackend.getIcon(func));
Glib::ustring tip = Glib::locale_to_utf8(tooltip);
if (xpmName.size() == 0) {
toolbar->tools().push_back(
Gtk::Toolbar_Helpers::ButtonElem(
"",
SigC::bind(SigC::slot(*this, &GToolbar::onButtonClicked),
FuncRequest(func)),
tip));
} else {
Gtk::Image * image =
Gtk::manage(new Gtk::Image(xpmName));
image->show();
toolbar->tools().push_back(
Gtk::Toolbar_Helpers::ButtonElem(
"",
*image,
SigC::bind(SigC::slot(*this, &GToolbar::onButtonClicked),
FuncRequest(func)),
tip));
}
toolbar->tools().back().get_content()->set_data(
gToolData,
reinterpret_cast<void*>(&const_cast<ToolbarBackend::Item&>(item)));
break;
}
}
}
void GToolbar::onButtonClicked(FuncRequest func)
{
view_->getLyXFunc().dispatch(func, true);
}
void GToolbar::onLayoutSelected()
{
if (internal_)
return;
string layoutGuiName = combo_.get_entry()->get_text();
// we get two signal, one of it is empty and useless
if (layoutGuiName.empty())
return;
LyXTextClass const & tc = getTextClass(*view_);
LyXTextClass::const_iterator end = tc.end();
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit) {
if ((*cit)->name() == layoutGuiName) {
view_->getLyXFunc().dispatch(
FuncRequest(LFUN_LAYOUT, (*cit)->name()),
true);
return;
}
}
lyxerr << "ERROR (GToolbar::layoutSelected): layout not found! name : "
<< layoutGuiName
<< std::endl;
}
void GToolbar::displayToolbar(ToolbarBackend::Toolbar const & tbb, bool show_it)
{
ToolbarMap::iterator it = toolbars_.find(tbb.name);
BOOST_ASSERT(it != toolbars_.end());
if (show_it)
it->second->show();
else
it->second->hide();
}
void GToolbar::update()
{
ToolbarMap::iterator itToolbar;
for (itToolbar = toolbars_.begin();
itToolbar != toolbars_.end(); ++itToolbar) {
Gtk::Toolbar * toolbar = itToolbar->second;
Gtk::Toolbar_Helpers::ToolList::iterator it;
for (it = toolbar->tools().begin();
it != toolbar->tools().end(); ++it) {
Gtk::Widget * widget;
switch (it->get_type()) {
case Gtk::TOOLBAR_CHILD_WIDGET:
widget = it->get_widget();
break;
case Gtk::TOOLBAR_CHILD_SPACE:
continue;
default:
widget = it->get_content();
}
ToolbarBackend::Item * item =
reinterpret_cast<ToolbarBackend::Item*>(
widget->get_data(gToolData));
if (item->first.action == int(ToolbarBackend::LAYOUTS)) {
LyXFunc const & lf = view_->getLyXFunc();
bool const sensitive =
lf.getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
widget->set_sensitive(sensitive);
continue;
}
FuncStatus const status = view_->
getLyXFunc().getStatus(item->first);
bool sensitive = status.enabled();
widget->set_sensitive(sensitive);
if (it->get_type() != Gtk::TOOLBAR_CHILD_BUTTON)
return;
if (status.onoff(true))
static_cast<Gtk::Button*>(widget)->
set_relief(Gtk::RELIEF_NORMAL);
if (status.onoff(false))
static_cast<Gtk::Button*>(widget)->
set_relief(Gtk::RELIEF_NONE);
}
}
}
void GToolbar::setLayout(string const & layout)
{
LyXTextClass const & tc = getTextClass(*view_);
internal_ = true;
combo_.get_entry()->set_text(tc[layout]->name());
internal_ = false;
}
void GToolbar::updateLayoutList()
void GLayoutBox::update()
{
LyXTextClass const & tc = getTextClass(*view_);
LyXTextClass::const_iterator end = tc.end();
LyXTextClass const & tc = getTextClass(owner_);
std::vector<Glib::ustring> strings;
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit)
if ((*cit)->obsoleted_by().empty())
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it)
if ((*it)->obsoleted_by().empty())
strings.push_back(
Glib::locale_to_utf8((*cit)->name()));
Glib::locale_to_utf8((*it)->name()));
internal_ = true;
combo_.set_popdown_strings(strings);
internal_ = false;
}
void GToolbar::openLayoutList()
{
combo_.get_list()->activate();
}
void GToolbar::clearLayoutList()
void GLayoutBox::clear()
{
internal_ = true;
comboClear(combo_);
internal_ = false;
}
void GLayoutBox::open()
{
combo_.get_list()->activate();
}
void GLayoutBox::setEnabled(bool sensitive)
{
combo_.set_sensitive(sensitive);
}
void GLayoutBox::selected()
{
if (internal_)
return;
string layoutGuiName = combo_.get_entry()->get_text();
// we get two signal, one of it is empty and useless
if (layoutGuiName.empty())
return;
LyXTextClass const & tc = getTextClass(owner_);
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it) {
string const & name = (*it)->name();
if (name == layoutGuiName) {
owner_.getLyXFunc().dispatch(
FuncRequest(LFUN_LAYOUT, name),
true);
return;
}
}
lyxerr << "ERROR (GLayoutBox::selected): layout not found! name: "
<< layoutGuiName << std::endl;
}
Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
LyXView & owner)
{
return Toolbars::ToolbarPtr(new GToolbar(tbb, owner));
}
GToolbar::GToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & owner)
: owner_(dynamic_cast<GView &>(owner))
{
ToolbarBackend::item_iterator it = tbb.items.begin();
ToolbarBackend::item_iterator end = tbb.items.end();
for (; it != end; ++it)
add(it->first, it->second);
toolbar_.set_toolbar_style(Gtk::TOOLBAR_ICONS);
GView::Position const position = getPosition(tbb.flags);
if (position == GView::Left || position == GView::Right)
toolbar_.set_orientation(Gtk::ORIENTATION_VERTICAL);
owner_.getBox(position).children().push_back(
Gtk::Box_Helpers::Element(toolbar_, Gtk::PACK_SHRINK));
}
void GToolbar::add(FuncRequest const & func, string const & tooltip)
{
switch (func.action) {
case ToolbarBackend::SEPARATOR:
toolbar_.tools().push_back(Gtk::Toolbar_Helpers::Space());
break;
case ToolbarBackend::MINIBUFFER:
// Not supported yet.
break;
case ToolbarBackend::LAYOUTS:
{
layout_.reset(new GLayoutBox(owner_, toolbar_, func));
break;
}
default:
Glib::ustring xpmName =
Glib::locale_to_utf8(toolbarbackend.getIcon(func));
Glib::ustring tip = Glib::locale_to_utf8(tooltip);
if (xpmName.size() == 0) {
toolbar_.tools().push_back(
Gtk::Toolbar_Helpers::ButtonElem(
"",
SigC::bind(SigC::slot(*this, &GToolbar::clicked),
FuncRequest(func)),
tip));
} else {
Gtk::Image * image =
Gtk::manage(new Gtk::Image(xpmName));
image->show();
toolbar_.tools().push_back(
Gtk::Toolbar_Helpers::ButtonElem(
"",
*image,
SigC::bind(SigC::slot(*this, &GToolbar::clicked),
FuncRequest(func)),
tip));
}
toolbar_.tools().back().get_content()->set_data(
gToolData,
reinterpret_cast<void*>(&const_cast<FuncRequest &>(func)));
break;
}
}
void GToolbar::clicked(FuncRequest func)
{
owner_.getLyXFunc().dispatch(func, true);
}
void GToolbar::hide(bool)
{
toolbar_.hide();
}
void GToolbar::show(bool)
{
toolbar_.show();
}
void GToolbar::update()
{
Gtk::Toolbar_Helpers::ToolList::iterator it =
toolbar_.tools().begin();
Gtk::Toolbar_Helpers::ToolList::iterator const end =
toolbar_.tools().end();
for (; it != end; ++it) {
Gtk::Widget * widget;
switch (it->get_type()) {
case Gtk::TOOLBAR_CHILD_WIDGET:
widget = it->get_widget();
break;
case Gtk::TOOLBAR_CHILD_SPACE:
continue;
default:
widget = it->get_content();
}
FuncRequest const & func = *reinterpret_cast<FuncRequest *>(
widget->get_data(gToolData));
if (func.action == int(ToolbarBackend::LAYOUTS))
continue;
FuncStatus const status = owner_.getLyXFunc().getStatus(func);
bool sensitive = status.enabled();
widget->set_sensitive(sensitive);
if (it->get_type() != Gtk::TOOLBAR_CHILD_BUTTON)
return;
if (status.onoff(true))
static_cast<Gtk::Button*>(widget)->
set_relief(Gtk::RELIEF_NORMAL);
if (status.onoff(false))
static_cast<Gtk::Button*>(widget)->
set_relief(Gtk::RELIEF_NONE);
}
}

View File

@ -5,58 +5,62 @@
* Licence details can be found in the file COPYING.
*
* \author Huang Ying
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#ifndef TOOLBAR_PIMPL_H
#define TOOLBAR_PIMPL_H
#ifndef GTOOLBAR_H
#define GTOOLBAR_H
#include <gtkmm.h>
#include "frontends/Toolbar.h"
#include "ToolbarBackend.h"
#include <map>
#include "frontends/Toolbars.h"
#include <boost/scoped_ptr.hpp>
class GToolbar : public Toolbar, public SigC::Object
{
class GView;
class GLayoutBox: public LayoutBox, public SigC::Object {
public:
GToolbar(LyXView * o, int x, int y);
GLayoutBox(LyXView &, Gtk::Toolbar &, FuncRequest const &);
~GToolbar();
// add a new toolbar
void add(ToolbarBackend::Toolbar const & tb);
/// add a new button to the toolbar.
void add(Gtk::Toolbar * toolbar,
ToolbarBackend::Item const & item);
/// display toolbar, not implemented
void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
/// update the state of the icons
/// select the right layout in the combox.
void set(std::string const & layout);
/// Populate the layout combox.
void update();
/// Erase the layout list.
void clear();
/// Display the layout list.
void open();
///
void setEnabled(bool);
/// select the right layout in the combox
void setLayout(std::string const & layout);
/// Populate the layout combox; re-do everything if force is true.
void updateLayoutList();
/// Drop down the layout list
void openLayoutList();
/// Erase the layout list
void clearLayoutList();
private:
void onButtonClicked(FuncRequest);
void onLayoutSelected();
typedef std::map<std::string, Gtk::Toolbar*> ToolbarMap;
ToolbarMap toolbars_;
///
void selected();
Gtk::Combo combo_;
LyXView * view_;
LyXView & owner_;
bool internal_;
};
#endif
class GToolbar : public Toolbar, public SigC::Object {
public:
GToolbar(ToolbarBackend::Toolbar const &, LyXView &);
void add(FuncRequest const & func, std::string const & tooltip);
void hide(bool);
void show(bool);
void update();
LayoutBox * layout() const { return layout_.get(); }
private:
void clicked(FuncRequest);
GView & owner_;
Gtk::Toolbar toolbar_;
boost::scoped_ptr<GLayoutBox> layout_;
};
#endif // NOT GTOOLBAR_H

View File

@ -14,13 +14,14 @@
#include "GView.h"
#include "GMenubar.h"
#include "GMiniBuffer.h"
#include "GToolbar.h"
#include "BufferView.h"
#include "lyx_cb.h"
#include "lyxfunc.h"
#include "MenuBackend.h"
#include "frontends/Toolbars.h"
#include "support/filetools.h"
#include <boost/bind.hpp>
@ -81,8 +82,7 @@ GView::GView()
// Define the components making up the window.
menubar_.reset(new GMenubar(this, menubackend));
toolbar_.reset(new GToolbar(this, 0, 0));
toolbar_->init();
getToolbars().init();
bufferview_.reset(new BufferView(this, 300, 300));
minibuffer_.reset(new GMiniBuffer(this, *controlcommand_));
@ -92,7 +92,7 @@ GView::GView()
signal_focus_in_event().connect(SigC::slot(*this, &GView::onFocusIn));
set_default_size(500, 550);
// Make sure the buttons are disabled if needed.
updateToolbar();
updateToolbars();
string const iconName =
lyx::support::LibFileSearch("images", "lyx", "xpm");
if (!iconName.empty())

View File

@ -1,3 +1,10 @@
2004-04-28 Angus Leeming <leeming@lyx.org>
* QLToolbar.[Ch]: rewrite code to derive from a single Toolbar or
LayoutBox.
* QtView.C: small changes due to changed Toolbar API.
2004-04-28 Angus Leeming <leeming@lyx.org>
* WorkAreaFactory.C (create): No longer passed x, y data.

View File

@ -6,6 +6,7 @@
* \author Lars Gullik Bjønnes
* \author John Levon
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
@ -22,108 +23,56 @@
#include "QtView.h"
#include "QLToolbar.h"
#include "qt_helpers.h"
#include <qcombobox.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
using std::endl;
using std::string;
class QLComboBox : public QComboBox {
public:
QLComboBox(QWidget * parent) : QComboBox(parent) {}
void popup() { QComboBox::popup(); }
};
namespace {
QLToolbar::QLToolbar(LyXView * o)
: owner_(static_cast<QtView *>(o)),
combo_(0)
LyXTextClass const & getTextClass(LyXView const & lv)
{
proxy_.reset(new ToolbarProxy(*this));
return lv.buffer()->params().getLyXTextClass();
}
QMainWindow::ToolBarDock getPosition(ToolbarBackend::Flags const & flags)
{
if (flags & ToolbarBackend::TOP)
return QMainWindow::Top;
if (flags & ToolbarBackend::BOTTOM)
return QMainWindow::Bottom;
if (flags & ToolbarBackend::LEFT)
return QMainWindow::Left;
if (flags & ToolbarBackend::RIGHT)
return QMainWindow::Right;
return QMainWindow::Top;
}
} // namespace anon
QLayoutBox::QLayoutBox(QWidget * parent, QtView & owner)
: combo_(new QComboBox(parent)),
owner_(owner)
{
QSizePolicy p(QSizePolicy::Minimum, QSizePolicy::Fixed);
combo_->setSizePolicy(p);
combo_->setFocusPolicy(QWidget::ClickFocus);
combo_->setMinimumWidth(combo_->sizeHint().width());
QObject::connect(combo_, SIGNAL(activated(const QString &)),
this, SLOT(selected(const QString &)));
}
void QLToolbar::displayToolbar(ToolbarBackend::Toolbar const & tb, bool show)
void QLayoutBox::set(string const & layout)
{
QToolBar * qtb = toolbars_[tb.name];
if (show) {
qtb->show();
} else {
qtb->hide();
}
}
void QLToolbar::update()
{
ButtonMap::const_iterator p = map_.begin();
ButtonMap::const_iterator end = map_.end();
for (; p != end; ++p) {
QToolButton * button = p->first;
FuncRequest const & func = p->second;
FuncStatus const status =
owner_->getLyXFunc().getStatus(func);
button->setToggleButton(true);
button->setOn(status.onoff(true));
button->setEnabled(status.enabled());
}
bool const enable = owner_->getLyXFunc().
getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
// Workaround for Qt bug where setEnabled(true) closes
// the popup
if (combo_ && enable != combo_->isEnabled())
combo_->setEnabled(enable);
}
void QLToolbar::button_selected(QToolButton * button)
{
ButtonMap::const_iterator cit = map_.find(button);
if (cit == map_.end()) {
lyxerr << "non existent tool button selected !" << endl;
return;
}
owner_->getLyXFunc().dispatch(cit->second, true);
}
void QLToolbar::changed_layout(string const & sel)
{
owner_->centralWidget()->setFocus();
LyXTextClass const & tc =
owner_->buffer()->params().getLyXTextClass();
LyXTextClass::const_iterator end = tc.end();
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit) {
// Yes, the _() is correct
if (_((*cit)->name()) == sel) {
owner_->getLyXFunc().dispatch(FuncRequest(LFUN_LAYOUT, (*cit)->name()), true);
return;
}
}
lyxerr << "ERROR (QLToolbar::layoutSelected): layout not found!"
<< endl;
}
void QLToolbar::setLayout(string const & layout)
{
if (!combo_)
return;
LyXTextClass const & tc =
owner_->buffer()->params().getLyXTextClass();
LyXTextClass const & tc = getTextClass(owner_);
QString const & name = qt_(tc[layout]->name());
@ -143,24 +92,20 @@ void QLToolbar::setLayout(string const & layout)
}
void QLToolbar::updateLayoutList()
void QLayoutBox::update()
{
if (!combo_)
return;
LyXTextClass const & tc =
owner_->buffer()->params().getLyXTextClass();
LyXTextClass const & tc = getTextClass(owner_);
combo_->setUpdatesEnabled(false);
combo_->clear();
LyXTextClass::const_iterator cit = tc.begin();
LyXTextClass::const_iterator end = tc.end();
for (; cit != end; ++cit) {
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it) {
// ignore obsolete entries
if ((*cit)->obsoleted_by().empty())
combo_->insertItem(qt_((*cit)->name()));
if ((*it)->obsoleted_by().empty())
combo_->insertItem(qt_((*it)->name()));
}
// needed to recalculate size hint
@ -173,93 +118,143 @@ void QLToolbar::updateLayoutList()
}
void QLToolbar::clearLayoutList()
void QLayoutBox::clear()
{
if (!combo_)
return;
Toolbar::clearLayoutList();
combo_->clear();
}
void QLToolbar::openLayoutList()
void QLayoutBox::open()
{
if (!combo_)
return;
combo_->popup();
}
namespace {
QMainWindow::ToolBarDock getPosition(ToolbarBackend::Flags const & flags)
void QLayoutBox::setEnabled(bool enable)
{
if (flags & ToolbarBackend::TOP)
return QMainWindow::Top;
if (flags & ToolbarBackend::BOTTOM)
return QMainWindow::Bottom;
if (flags & ToolbarBackend::LEFT)
return QMainWindow::Left;
if (flags & ToolbarBackend::RIGHT)
return QMainWindow::Right;
return QMainWindow::Top;
// Workaround for Qt bug where setEnabled(true) closes
// the popup
if (enable != combo_->isEnabled())
combo_->setEnabled(enable);
}
};
void QLToolbar::add(ToolbarBackend::Toolbar const & tb)
void QLayoutBox::selected(const QString & str)
{
string const sel = fromqstr(str);
owner_.centralWidget()->setFocus();
LyXTextClass const & tc = getTextClass(owner_);
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it) {
string const & name = (*it)->name();
// Yes, the _() is correct
if (_(name) == sel) {
owner_.getLyXFunc()
.dispatch(FuncRequest(LFUN_LAYOUT, name),
true);
return;
}
}
lyxerr << "ERROR (QLayoutBox::selected): layout not found!" << endl;
}
Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
LyXView & owner)
{
return Toolbars::ToolbarPtr(new QLToolbar(tbb, owner));
}
QLToolbar::QLToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & owner)
: owner_(dynamic_cast<QtView &>(owner)),
toolbar_(new QToolBar(qt_(tbb.gui_name), &owner_,
getPosition(tbb.flags)))
{
QToolBar * qtb = new QToolBar(qt_(tb.gui_name), owner_,
getPosition(tb.flags));
// give visual separation between adjacent toolbars
qtb->addSeparator();
toolbar_->addSeparator();
ToolbarBackend::item_iterator it = tb.items.begin();
ToolbarBackend::item_iterator end = tb.items.end();
ToolbarBackend::item_iterator it = tbb.items.begin();
ToolbarBackend::item_iterator end = tbb.items.end();
for (; it != end; ++it)
add(qtb, it->first, it->second);
toolbars_[tb.name] = qtb;
displayToolbar(tb, tb.flags & ToolbarBackend::ON);
add(it->first, it->second);
}
void QLToolbar::add(QToolBar * tb,
FuncRequest const & func, string const & tooltip)
void QLToolbar::add(FuncRequest const & func, string const & tooltip)
{
switch (func.action) {
case ToolbarBackend::SEPARATOR:
tb->addSeparator();
toolbar_->addSeparator();
break;
case ToolbarBackend::LAYOUTS: {
combo_ = new QLComboBox(tb);
QSizePolicy p(QSizePolicy::Minimum, QSizePolicy::Fixed);
combo_->setSizePolicy(p);
combo_->setFocusPolicy(QWidget::ClickFocus);
combo_->setMinimumWidth(combo_->sizeHint().width());
QObject::connect(combo_, SIGNAL(activated(const QString &)),
proxy_.get(), SLOT(layout_selected(const QString &)));
case ToolbarBackend::LAYOUTS:
layout_.reset(new QLayoutBox(toolbar_, owner_));
break;
}
case ToolbarBackend::MINIBUFFER:
owner_->addCommandBuffer(tb);
tb->setHorizontalStretchable(true);
owner_.addCommandBuffer(toolbar_);
toolbar_->setHorizontalStretchable(true);
break;
default: {
if (owner_->getLyXFunc().getStatus(func).unknown())
if (owner_.getLyXFunc().getStatus(func).unknown())
break;
QPixmap p = QPixmap(toolbarbackend.getIcon(func).c_str());
QToolButton * button =
new QToolButton(p, toqstr(tooltip), "",
proxy_.get(), SLOT(button_selected()), tb);
this, SLOT(clicked()), toolbar_);
map_[button] = func;
break;
}
}
}
void QLToolbar::hide(bool)
{
toolbar_->hide();
}
void QLToolbar::show(bool)
{
toolbar_->show();
}
void QLToolbar::update()
{
ButtonMap::const_iterator p = map_.begin();
ButtonMap::const_iterator end = map_.end();
for (; p != end; ++p) {
QToolButton * button = p->first;
FuncRequest const & func = p->second;
FuncStatus const status =
owner_.getLyXFunc().getStatus(func);
button->setToggleButton(true);
button->setOn(status.onoff(true));
button->setEnabled(status.enabled());
}
}
void QLToolbar::clicked()
{
QToolButton const * const_button =
static_cast<QToolButton const *>(sender());
QToolButton * button =
const_cast<QToolButton *>(const_button);
ButtonMap::const_iterator it = map_.find(button);
if (it != map_.end())
owner_.getLyXFunc().dispatch(it->second, true);
else
lyxerr << "non existent tool button selected !" << endl;
}

View File

@ -7,95 +7,75 @@
* \author Lars Gullik Bjønnes
* \author John Levon
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#ifndef QLTOOLBAR__H
#ifndef QLTOOLBAR_H
#define QLTOOLBAR_H
#include "frontends/Toolbar.h"
#include "qt_helpers.h"
#include "frontends/Toolbars.h"
#include <boost/scoped_ptr.hpp>
#include <map>
#include <qobject.h>
#include <qtoolbutton.h>
class QComboBox;
class QToolBar;
class QToolButton;
class QtView;
class QToolBar;
class QLComboBox;
class ToolbarProxy;
class QLToolbar : public Toolbar {
public:
friend class ToolbarProxy;
QLToolbar(LyXView * o);
/// add a new toolbar
void add(ToolbarBackend::Toolbar const & tb);
/// add an item to a toolbar
void add(QToolBar * tb, FuncRequest const &, std::string const & tooltip);
/// show or hide a toolbar
void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
/// update the state of the icons
void update();
/// select the right layout in the combox
void setLayout(std::string const & layout);
/// Populate the layout combox.
void updateLayoutList();
/// Drop down the layout list
void openLayoutList();
/// Erase the layout list
void clearLayoutList();
private:
void changed_layout(std::string const & sel);
void button_selected(QToolButton * button);
QtView * owner_;
boost::scoped_ptr<ToolbarProxy> proxy_;
std::map<std::string, QToolBar *> toolbars_;
QLComboBox * combo_;
typedef std::map<QToolButton *, FuncRequest> ButtonMap;
ButtonMap map_;
};
class QLayoutBox;
class QLToolbar;
// moc is mind-numbingly stupid
class ToolbarProxy : public QObject {
class QLayoutBox : public QObject, public LayoutBox {
Q_OBJECT
public:
ToolbarProxy(QLToolbar & owner)
: owner_(owner) {}
public slots:
QLayoutBox(QWidget *, QtView &);
void layout_selected(const QString & str) {
owner_.changed_layout(fromqstr(str));
}
/// select the right layout in the combox.
void set(std::string const & layout);
/// Populate the layout combox.
void update();
/// Erase the layout list.
void clear();
/// Display the layout list.
void open();
///
void setEnabled(bool);
private slots:
void selected(const QString & str);
void button_selected() {
owner_.button_selected(
const_cast<QToolButton *>(
static_cast<QToolButton const *>(sender()))
);
}
private:
QLToolbar & owner_;
QComboBox * combo_;
QtView & owner_;
};
#endif
class QLToolbar : public QObject, public Toolbar {
Q_OBJECT
public:
QLToolbar(ToolbarBackend::Toolbar const &, LyXView &);
void add(FuncRequest const & func, std::string const & tooltip);
void hide(bool);
void show(bool);
void update();
LayoutBox * layout() const { return layout_.get(); }
private slots:
void clicked();
private:
typedef std::map<QToolButton *, FuncRequest> ButtonMap;
QtView & owner_;
QToolBar * toolbar_;
ButtonMap map_;
boost::scoped_ptr<QLayoutBox> layout_;
};
#endif // NOT QLTOOLBAR_H

View File

@ -11,21 +11,25 @@
#include <config.h>
#include "lyx_cb.h"
#include "support/filetools.h"
#include "MenuBackend.h"
#include "lyxfunc.h"
#include "BufferView.h"
#include "lyx_cb.h"
#include "lyxfunc.h"
#include "MenuBackend.h"
#include "frontends/Toolbars.h"
#include "support/filetools.h"
#include <boost/bind.hpp>
#include "QtView.h"
#include "QLToolbar.h"
#include "QLMenubar.h"
#include "qfont_loader.h"
#include "QCommandBuffer.h"
#include "qt_helpers.h"
#include <qapplication.h>
#include <qpixmap.h>
#include <qstatusbar.h>
using lyx::support::LibFileSearch;
@ -52,8 +56,7 @@ QtView::QtView(unsigned int width, unsigned int height)
bufferview_.reset(new BufferView(this, width, height));
menubar_.reset(new QLMenubar(this, menubackend));
toolbar_.reset(new QLToolbar(this));
toolbar_->init();
getToolbars().init();
statusBar()->setSizeGripEnabled(false);
@ -66,7 +69,7 @@ QtView::QtView(unsigned int width, unsigned int height)
setIcon(QPixmap(toqstr(iconname)));
// make sure the buttons are disabled if needed
updateToolbar();
updateToolbars();
// allowing the toolbars to tear off is too easily done,
// and we don't save their orientation anyway. Disable the handle.

View File

@ -1,3 +1,14 @@
2004-04-28 Angus Leeming <leeming@lyx.org>
* LayoutEngine.C (updateMetrics): respect the visible() flag when
positioning the widgets.
* XFormsToolbar.[Ch]: rewrite code to derive from a single Toolbar or
LayoutBox. Leads to multiple, dynamically visible toolbars in the
xforms frontend.
* XFormsView.[Ch]: small changes due to changed Toolbar API.
2004-04-28 Angus Leeming <leeming@lyx.org>
* LayoutEngine.[Ch]: a layout engine for xforms, drawing heavily

View File

@ -116,7 +116,7 @@ void Box::setMinimumDimensions(dimension_t min_w, dimension_t min_h)
min_h_ = min_h;
}
Box::Orientation Box::orientation() const
{
return orientation_;
@ -443,9 +443,17 @@ void WidgetMap::updateMetrics() const
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());
if (box.visible()) {
fl_set_object_geometry(ob,
box.xorigin(), box.yorigin(),
box.width(), box.height());
if (!ob->visible)
fl_show_object(ob);
} else {
if (ob->visible)
fl_hide_object(ob);
}
}
}

View File

@ -168,7 +168,7 @@ public:
/// \returns the just-added Box.
Box & add(FL_OBJECT * widget, BoxList & container,
dimension_t min_w, dimension_t min_h);
dimension_t min_w, dimension_t min_h);
void updateMetrics() const;
private:

View File

@ -17,7 +17,6 @@
#include "Tooltips.h"
#include "xforms_helpers.h"
#include "XFormsView.h"
#include "buffer.h"
#include "bufferparams.h"
@ -46,6 +45,30 @@ const int sepspace = 6; // extra space
const int buttonwidth = 30; // the standard button width
const int height = 30; // the height of all items in the toolbar
namespace {
XFormsView::Position getPosition(ToolbarBackend::Flags const & flags)
{
if (flags & ToolbarBackend::TOP)
return XFormsView::Top;
if (flags & ToolbarBackend::BOTTOM)
return XFormsView::Bottom;
if (flags & ToolbarBackend::LEFT)
return XFormsView::Left;
if (flags & ToolbarBackend::RIGHT)
return XFormsView::Right;
return XFormsView::Top;
}
LyXTextClass const & getTextClass(LyXView const & lv)
{
return lv.buffer()->params().getLyXTextClass();
}
} // namespace anon
XFormsToolbar::toolbarItem::toolbarItem()
: icon(0)
{}
@ -61,13 +84,6 @@ XFormsToolbar::toolbarItem::~toolbarItem()
}
/// Display toolbar, not implemented. But moved out of line so that
/// linking will work properly.
void XFormsToolbar::displayToolbar(ToolbarBackend::Toolbar const & /*tb*/,
bool /*show*/)
{}
void XFormsToolbar::toolbarItem::kill_icon()
{
if (icon) {
@ -95,30 +111,180 @@ XFormsToolbar::toolbarItem::operator=(toolbarItem const & ti)
XFormsToolbar::XFormsToolbar(LyXView * o)
Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
LyXView & owner)
{
return Toolbars::ToolbarPtr(new XFormsToolbar(tbb, owner));
}
XFormsToolbar::XFormsToolbar(ToolbarBackend::Toolbar const & tbb,
LyXView & o)
: toolbar_(0),
toolbar_buttons_(0),
owner_(static_cast<XFormsView *>(o)),
combox_(0)
owner_(static_cast<XFormsView &>(o)),
tooltip_(new Tooltips)
{
tooltip_ = new Tooltips;
position_ = getPosition(tbb.flags);
BoxList & boxlist = owner_.getBox(position_).children();
toolbar_ = &boxlist.push_back(Box(0,0));
// If the toolbar is horizontal, then it contains three
// vertically-aligned Boxes,the center one of which is to
// contain the buttons, aligned horizontally.
// The other two provide some visual padding.
// If it is vertical, then this is swapped around.
Box::Orientation const toolbar_orientation =
(position_ == XFormsView::Left ||
position_ == XFormsView::Right)
? Box::Vertical : Box::Horizontal;
Box::Orientation const padding_orientation =
(toolbar_orientation == Box::Vertical)
? Box::Horizontal : Box::Vertical;
toolbar_->set(padding_orientation);
// A bit of a hack, but prevents 'M-x' causing the addition of
// visible borders.
int const padding =
(tbb.name == "minibuffer") ?
0 : 2 + abs(fl_get_border_width());
toolbar_->children().push_back(Box(padding, padding));
Box & toolbar_center = toolbar_->children().push_back(Box(0,0));
toolbar_center.set(toolbar_orientation);
toolbar_buttons_ = &toolbar_center.children();
toolbar_->children().push_back(Box(padding, padding));
using lyx::frontend::WidgetMap;
owner_->metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics,
&widgets_));
owner_.metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics,
&widgets_));
// Populate the toolbar.
ToolbarBackend::item_iterator it = tbb.items.begin();
ToolbarBackend::item_iterator end = tbb.items.end();
for (; it != end; ++it)
add(it->first, it->second);
}
XFormsToolbar::~XFormsToolbar()
{
fl_freeze_form(owner_->getForm());
fl_freeze_form(owner_.getForm());
// G++ vector does not have clear defined
//toollist.clear();
toollist_.erase(toollist_.begin(), toollist_.end());
fl_unfreeze_form(owner_->getForm());
delete tooltip_;
fl_unfreeze_form(owner_.getForm());
}
namespace {
extern "C" {
void C_ToolbarCB(FL_OBJECT * ob, long ac)
{
if (!ob || !ob->u_vdata)
return;
XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
XFormsView & owner = ptr->owner_;
owner.getLyXFunc().dispatch(ptr->funcs[ac], true);
}
} // extern "C"
} // namespace anon
void XFormsToolbar::hide(bool update_metrics)
{
toolbar_->set(Box::Invisible);
if (update_metrics)
owner_.updateMetrics();
}
void XFormsToolbar::show(bool update_metrics)
{
toolbar_->set(Box::Visible);
toolbar_->show();
if (update_metrics)
owner_.updateMetrics();
}
void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
{
toolbarItem item;
item.func = func;
switch (func.action) {
case ToolbarBackend::SEPARATOR:
toolbar_buttons_->push_back(Box(sepspace, sepspace));
break;
case ToolbarBackend::MINIBUFFER:
// Not implemented.
// XForms uses the same widget to display the buffer messages
// and to input commands.
break;
case ToolbarBackend::LAYOUTS:
layout_.reset(new XLayoutBox(owner_, *this));
break;
default: {
FL_OBJECT * obj;
toolbar_buttons_->push_back(Box(standardspacing,
standardspacing));
item.icon = obj =
fl_add_pixmapbutton(FL_NORMAL_BUTTON,
0, 0, 0, 0, "");
widgets_.add(obj, *toolbar_buttons_, buttonwidth, height);
fl_set_object_resize(obj, FL_RESIZE_ALL);
int gravity = 0;
if (position_ == XFormsView::Top ||
position_ == XFormsView::Left)
gravity = NorthWestGravity;
else if (position_ == XFormsView::Right)
gravity = NorthEastGravity;
else if (position_ == XFormsView::Bottom)
gravity = SouthWestGravity;
fl_set_object_gravity(obj, gravity, gravity);
Funcs::iterator fit = funcs.insert(funcs.end(), func);
int const index = distance(funcs.begin(), fit);
fl_set_object_callback(obj, C_ToolbarCB, index);
// Remove the blue feedback rectangle
fl_set_pixmapbutton_focus_outline(obj, 0);
tooltip_->init(obj, tooltip);
// The view that this object belongs to.
obj->u_vdata = this;
string const xpm = toolbarbackend.getIcon(func);
fl_set_pixmapbutton_file(obj, xpm.c_str());
break;
}
}
toollist_.push_back(item);
}
@ -127,18 +293,12 @@ void XFormsToolbar::update()
ToolbarList::const_iterator p = toollist_.begin();
ToolbarList::const_iterator end = toollist_.end();
for (; p != end; ++p) {
if (p->func.action == int(ToolbarBackend::LAYOUTS) && combox_) {
LyXFunc const & lf = owner_->getLyXFunc();
bool const enable =
lf.getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
setEnabled(combox_, enable);
continue;
}
if (!p->icon)
continue;
FuncStatus const status = owner_->getLyXFunc().getStatus(p->func);
FuncStatus const status =
owner_.getLyXFunc().getStatus(p->func);
if (status.onoff(true)) {
// I'd like to use a different color
// here, but then the problem is to
@ -160,50 +320,54 @@ void XFormsToolbar::update()
fl_deactivate_object(p->icon);
}
}
bool const enable = owner_.getLyXFunc().
getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
if (layout_.get())
layout_->setEnabled(enable);
}
namespace {
void C_layoutSelectedCB(FL_OBJECT * ob, long)
extern "C"
void C_LayoutBoxSelectedCB(FL_OBJECT * ob, long)
{
if (!ob || !ob->u_vdata)
return;
XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
ptr->layoutSelected();
XLayoutBox * ptr = static_cast<XLayoutBox *>(ob->u_vdata);
ptr->selected();
}
} // namespace anon
void XFormsToolbar::layoutSelected()
XLayoutBox::XLayoutBox(LyXView & owner, XFormsToolbar & toolbar)
: owner_(owner)
{
if (!combox_)
return;
toolbar.toolbar_buttons_->push_back(Box(standardspacing, 0));
string const & layoutguiname = getString(combox_);
LyXTextClass const & tc =
owner_->buffer()->params().getLyXTextClass();
combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
0, 0, 135, height, "");
LyXTextClass::const_iterator end = tc.end();
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit) {
if (_((*cit)->name()) == layoutguiname) {
owner_->getLyXFunc().dispatch(FuncRequest(LFUN_LAYOUT, (*cit)->name()), true);
return;
}
}
lyxerr << "ERROR (XFormsToolbar::layoutSelected): layout not found!"
<< endl;
toolbar.widgets_.add(combox_, *toolbar.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);
fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
fl_set_object_resize(combox_, FL_RESIZE_ALL);
combox_->u_vdata = this;
fl_set_object_callback(combox_, C_LayoutBoxSelectedCB, 0);
}
void XFormsToolbar::setLayout(string const & layout)
void XLayoutBox::set(string const & layout)
{
if (!combox_)
return;
LyXTextClass const & tc = getTextClass(owner_);
LyXTextClass const & tc = owner_->buffer()->params().getLyXTextClass();
string const layoutname = _(tc[layout]->name());
int const nnames = fl_get_combox_maxitems(combox_);
@ -217,19 +381,18 @@ void XFormsToolbar::setLayout(string const & layout)
}
void XFormsToolbar::updateLayoutList()
void XLayoutBox::update()
{
if (!combox_)
return;
LyXTextClass const & tc = getTextClass(owner_);
fl_clear_combox(combox_);
LyXTextClass const & tc = owner_->buffer()->params().getLyXTextClass();
LyXTextClass::const_iterator end = tc.end();
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit) {
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it) {
// ignore obsolete entries
if ((*cit)->obsoleted_by().empty()) {
string const & name = _((*cit)->name());
if ((*it)->obsoleted_by().empty()) {
string const & name = _((*it)->name());
fl_addto_combox(combox_, name.c_str());
}
}
@ -239,145 +402,41 @@ void XFormsToolbar::updateLayoutList()
}
void XFormsToolbar::clearLayoutList()
void XLayoutBox::clear()
{
if (!combox_)
return;
Toolbar::clearLayoutList();
fl_clear_combox(combox_);
fl_redraw_object(combox_);
}
void XFormsToolbar::openLayoutList()
void XLayoutBox::open()
{
if (!combox_)
return;
fl_show_combox_browser(combox_);
}
namespace {
void ToolbarCB(FL_OBJECT * ob, long ac)
void XLayoutBox::setEnabled(bool enable)
{
if (!ob || !ob->u_vdata)
return;
XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
XFormsView * owner = ptr->owner_;
owner->getLyXFunc().dispatch(ptr->funcs[ac], true);
::setEnabled(combox_, enable);
}
extern "C" {
void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
void XLayoutBox::selected()
{
ToolbarCB(ob, data);
}
string const layoutguiname = getString(combox_);
}
LyXTextClass const & tc = getTextClass(owner_);
} // namespace anon
void XFormsToolbar::add(ToolbarBackend::Toolbar const & tb)
{
// we can only handle one toolbar
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();
ToolbarBackend::item_iterator end = tb.items.end();
for (; it != end; ++it)
add(it->first, it->second);
}
void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
{
toolbarItem item;
item.func = func;
switch (func.action) {
case ToolbarBackend::SEPARATOR:
toolbar_buttons_->push_back(Box(sepspace, 0));
break;
case ToolbarBackend::MINIBUFFER:
// Not implemented
break;
case ToolbarBackend::LAYOUTS:
toolbar_buttons_->push_back(Box(standardspacing, 0));
if (combox_)
break;
combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
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);
fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
fl_set_object_resize(combox_, FL_RESIZE_ALL);
combox_->u_vdata = this;
fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
break;
default: {
FL_OBJECT * obj;
toolbar_buttons_->push_back(Box(standardspacing, 0));
item.icon = obj =
fl_add_pixmapbutton(FL_NORMAL_BUTTON,
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,
NorthWestGravity);
Funcs::iterator fit = funcs.insert(funcs.end(), func);
int const index = distance(funcs.begin(), fit);
fl_set_object_callback(obj, C_Toolbar_ToolbarCB, index);
// Remove the blue feedback rectangle
fl_set_pixmapbutton_focus_outline(obj, 0);
tooltip_->init(obj, tooltip);
// The view that this object belongs to.
obj->u_vdata = this;
string const xpm = toolbarbackend.getIcon(func);
fl_set_pixmapbutton_file(obj, xpm.c_str());
break;
LyXTextClass::const_iterator it = tc.begin();
LyXTextClass::const_iterator const end = tc.end();
for (; it != end; ++it) {
string const & name = (*it)->name();
if (_(name) == layoutguiname) {
owner_.getLyXFunc()
.dispatch(FuncRequest(LFUN_LAYOUT, name),
true);
return;
}
}
}
toollist_.push_back(item);
lyxerr << "ERROR (XLayoutBox::selected): layout not found!" << endl;
}

View File

@ -13,49 +13,59 @@
#ifndef XFORMSTOOLBAR_H
#define XFROMSTOOLBAR_H
#include <vector>
#include "forms_fwd.h"
#include "LayoutEngine.h"
#include "XFormsView.h"
#include "frontends/Toolbar.h"
#include "ToolbarBackend.h"
#include "frontends/Toolbars.h"
#include <boost/scoped_ptr.hpp>
#include <vector>
class XFormsToolbar;
class XFormsView;
class Tooltips;
class XLayoutBox: public LayoutBox {
public:
XLayoutBox(LyXView & owner, XFormsToolbar & toolbar);
/// select the right layout in the combox.
void set(std::string const & layout);
/// Populate the layout combox.
void update();
/// Erase the layout list.
void clear();
/// Display the layout list.
void open();
///
void setEnabled(bool);
///
void selected();
private:
FL_OBJECT * combox_;
LyXView & owner_;
};
/** The LyX xforms toolbar class
*/
class XFormsToolbar : public Toolbar {
public:
/// create an empty toolbar
XFormsToolbar(LyXView * o);
friend class XLayoutBox;
///
public:
XFormsToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & o);
~XFormsToolbar();
/// add a new toolbar
void add(ToolbarBackend::Toolbar const & tb);
/// add an item to a toolbar
void add(FuncRequest const &, std::string const & tooltip);
/// display toolbar, not implemented
void displayToolbar(ToolbarBackend::Toolbar const & tb, bool show);
/// update the state of the icons
void update();
/// select the right layout in the combox
void setLayout(std::string const & layout);
/// Populate the layout combox.
void updateLayoutList();
/// Drop down the layout list
void openLayoutList();
/// Erase the layout list
void clearLayoutList();
///
void layoutSelected();
void add(FuncRequest const & func, std::string const & tooltip);
void hide(bool);
void show(bool);
void update();
LayoutBox * layout() const { return layout_.get(); }
/// an item on the toolbar
struct toolbarItem
@ -75,6 +85,8 @@ public:
FL_OBJECT * icon;
};
///
XFormsView::Position position_;
///
lyx::frontend::Box * toolbar_;
///
@ -91,11 +103,11 @@ public:
/// The list containing all the buttons
ToolbarList toollist_;
/// owning view
XFormsView * owner_;
XFormsView & owner_;
/// tooltips manager
Tooltips * tooltip_;
boost::scoped_ptr<Tooltips> tooltip_;
/// layout combo
FL_OBJECT * combox_;
boost::scoped_ptr<XLayoutBox> layout_;
};
#endif

View File

@ -13,7 +13,6 @@
#include "XFormsView.h"
#include "XFormsMenubar.h"
#include "XFormsToolbar.h"
#include "XMiniBuffer.h"
#include "BufferView.h"
@ -22,6 +21,7 @@
#include "MenuBackend.h"
#include "frontends/Dialogs.h"
#include "frontends/Toolbars.h"
#include "support/filetools.h" // OnlyFilename()
@ -96,10 +96,7 @@ XFormsView::XFormsView(int width, int height)
fl_set_object_color(obj, FL_MCOL, FL_MCOL);
menubar_.reset(new XFormsMenubar(this, menubackend));
toolbar_.reset(new XFormsToolbar(this));
toolbar_->init();
getToolbars().init();
bufferview_.reset(new BufferView(this, width, height));
minibuffer_.reset(new XMiniBuffer(*this, *controlcommand_));
@ -122,15 +119,15 @@ XFormsView::XFormsView(int width, int height)
// Update the layout so that all widgets fit.
window_.show();
updateMetrics();
updateMetrics(true);
view_state_con =
view_state_changed.connect(boost::bind(&XFormsView::show_view_state, this));
focus_con =
focus_command_buffer.connect(boost::bind(&XMiniBuffer::focus, minibuffer_.get()));
// Make sure the buttons are disabled if needed.
updateToolbar();
updateToolbars();
redraw_con =
getDialogs().redrawGUI().connect(boost::bind(&XFormsView::redraw, this));
}
@ -198,16 +195,25 @@ void XFormsView::show(int x, int y, string const & title)
}
void XFormsView::updateMetrics()
void XFormsView::updateMetrics(bool resize_form)
{
FL_FORM * form = getForm();
// We don't want the window to be downsized.
if (!resize_form)
window_.setMinimumDimensions(form->w, form->h);
window_.updateMetrics();
FL_FORM * form = getForm();
fl_set_form_size(form, window_.width(), window_.height());
fl_freeze_form(form);
if (resize_form)
fl_set_form_size(form, window_.width(), window_.height());
// Emit a signal so that all daughter widgets are layed-out
// correctly.
metricsUpdated();
fl_unfreeze_form(form);
}

View File

@ -71,6 +71,9 @@ public:
/// clear back to normal status message
virtual void clearMessage();
///
void updateMetrics(bool resize_form = false);
///
boost::signal0<void> metricsUpdated;
private:
@ -84,8 +87,6 @@ private:
/// update the minibuffer state message
void show_view_state();
///
void updateMetrics();
/// The top-most box of the layout engine containing all other boxes.
lyx::frontend::Box window_;

View File

@ -1,3 +1,8 @@
2004-04-28 Angus Leeming <leeming@lyx.org>
* insettext.C:
s/updateToolbar()/updateToolbars()/
2004-04-29 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* insetgraphics.C: require file extension (file format change!)

View File

@ -259,7 +259,7 @@ void InsetText::updateLocal(LCursor & cur)
LyXView * lv = cur.bv().owner();
lv->view_state_changed();
lv->updateMenubar();
lv->updateToolbar();
lv->updateToolbars();
if (old_par != cur.par()) {
lv->setLayout(text_.getPar(cur.par()).layout()->name());
old_par = cur.par();

View File

@ -76,7 +76,7 @@
#include "frontends/LyXKeySym.h"
#include "frontends/LyXView.h"
#include "frontends/Menubar.h"
#include "frontends/Toolbar.h"
#include "frontends/Toolbars.h"
#include "support/FileInfo.h"
#include "support/filetools.h"
@ -631,7 +631,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose)
break;
case LFUN_EXEC_COMMAND:
owner->getToolbar().display("minibuffer", true);
owner->getToolbars().display("minibuffer", true);
owner->focus_command_buffer();
break;
@ -955,7 +955,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose)
break;
case LFUN_DROP_LAYOUTS_CHOICE:
owner->getToolbar().openLayoutList();
owner->getToolbars().openLayoutList();
break;
case LFUN_MENU_OPEN_BY_NAME:
@ -1399,7 +1399,7 @@ void LyXFunc::sendDispatchMessage(string const & msg,
FuncRequest const & cmd, bool verbose)
{
owner->updateMenubar();
owner->updateToolbar();
owner->updateToolbars();
if (cmd.action == LFUN_SELFINSERT || !verbose) {
lyxerr[Debug::ACTION] << "dispatch msg is " << msg << endl;

View File

@ -1191,7 +1191,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
bv->switchKeyMap();
bv->owner()->updateMenubar();
bv->owner()->updateToolbar();
bv->owner()->updateToolbars();
break;
}