2 * \file XFormsToolbar.C
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
7 * \author Jean-Marc Lasgouttes
9 * Full author contact details are available in file CREDITS.
12 // Added pseudo-action handling, asierra 180296
16 #include "XFormsToolbar.h"
19 #include "xforms_helpers.h"
20 #include "XFormsView.h"
23 #include "bufferparams.h"
25 #include "funcrequest.h"
26 #include "FuncStatus.h"
30 #include "lyx_forms.h"
33 #include <boost/bind.hpp>
35 using lyx::frontend::Box;
36 using lyx::frontend::BoxList;
44 const int standardspacing = 2; // the usual space between items
45 const int sepspace = 6; // extra space
46 const int buttonwidth = 30; // the standard button width
47 const int height = 30; // the height of all items in the toolbar
49 XFormsToolbar::toolbarItem::toolbarItem()
54 XFormsToolbar::toolbarItem::~toolbarItem()
56 // Lars said here that ~XFormsView() dealt with the icons.
57 // This is not true. But enabling this causes crashes,
58 // because somehow we kill the same icon twice :(
64 /// Display toolbar, not implemented. But moved out of line so that
65 /// linking will work properly.
66 void XFormsToolbar::displayToolbar(ToolbarBackend::Toolbar const & /*tb*/,
71 void XFormsToolbar::toolbarItem::kill_icon()
74 fl_delete_object(icon);
81 XFormsToolbar::toolbarItem &
82 XFormsToolbar::toolbarItem::operator=(toolbarItem const & ti)
87 // If we already have an icon, release it.
88 // But we don't copy the icon from ti
98 XFormsToolbar::XFormsToolbar(LyXView * o)
101 owner_(static_cast<XFormsView *>(o)),
104 tooltip_ = new Tooltips;
106 using lyx::frontend::WidgetMap;
107 owner_->metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics,
112 XFormsToolbar::~XFormsToolbar()
114 fl_freeze_form(owner_->getForm());
116 // G++ vector does not have clear defined
118 toollist_.erase(toollist_.begin(), toollist_.end());
120 fl_unfreeze_form(owner_->getForm());
125 void XFormsToolbar::update()
127 ToolbarList::const_iterator p = toollist_.begin();
128 ToolbarList::const_iterator end = toollist_.end();
129 for (; p != end; ++p) {
130 if (p->func.action == int(ToolbarBackend::LAYOUTS) && combox_) {
131 LyXFunc const & lf = owner_->getLyXFunc();
133 lf.getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
134 setEnabled(combox_, enable);
141 FuncStatus const status = owner_->getLyXFunc().getStatus(p->func);
142 if (status.onoff(true)) {
143 // I'd like to use a different color
144 // here, but then the problem is to
145 // know how to use transparency with
146 // Xpm library. It seems pretty
147 // complicated to me (JMarc)
148 fl_set_object_color(p->icon, FL_LEFT_BCOL, FL_BLUE);
149 fl_set_object_boxtype(p->icon, FL_DOWN_BOX);
151 fl_set_object_color(p->icon, FL_MCOL, FL_BLUE);
152 fl_set_object_boxtype(p->icon, FL_UP_BOX);
154 if (status.enabled()) {
155 fl_activate_object(p->icon);
157 // Is there a way here to specify a
158 // mask in order to show that the
159 // button is disabled? (JMarc)
160 fl_deactivate_object(p->icon);
168 void C_layoutSelectedCB(FL_OBJECT * ob, long)
170 if (!ob || !ob->u_vdata)
172 XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
173 ptr->layoutSelected();
179 void XFormsToolbar::layoutSelected()
184 string const & layoutguiname = getString(combox_);
185 LyXTextClass const & tc =
186 owner_->buffer()->params().getLyXTextClass();
188 LyXTextClass::const_iterator end = tc.end();
189 for (LyXTextClass::const_iterator cit = tc.begin();
191 if (_((*cit)->name()) == layoutguiname) {
192 owner_->getLyXFunc().dispatch(FuncRequest(LFUN_LAYOUT, (*cit)->name()), true);
196 lyxerr << "ERROR (XFormsToolbar::layoutSelected): layout not found!"
201 void XFormsToolbar::setLayout(string const & layout)
206 LyXTextClass const & tc = owner_->buffer()->params().getLyXTextClass();
207 string const layoutname = _(tc[layout]->name());
209 int const nnames = fl_get_combox_maxitems(combox_);
210 for (int i = 1; i <= nnames; ++i) {
211 string const name = fl_get_combox_line(combox_, i);
212 if (name == layoutname) {
213 fl_set_combox(combox_, i);
220 void XFormsToolbar::updateLayoutList()
225 fl_clear_combox(combox_);
226 LyXTextClass const & tc = owner_->buffer()->params().getLyXTextClass();
227 LyXTextClass::const_iterator end = tc.end();
228 for (LyXTextClass::const_iterator cit = tc.begin();
230 // ignore obsolete entries
231 if ((*cit)->obsoleted_by().empty()) {
232 string const & name = _((*cit)->name());
233 fl_addto_combox(combox_, name.c_str());
237 // we need to do this.
238 fl_redraw_object(combox_);
242 void XFormsToolbar::clearLayoutList()
247 Toolbar::clearLayoutList();
248 fl_clear_combox(combox_);
249 fl_redraw_object(combox_);
253 void XFormsToolbar::openLayoutList()
258 fl_show_combox_browser(combox_);
264 void ToolbarCB(FL_OBJECT * ob, long ac)
266 if (!ob || !ob->u_vdata)
269 XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
270 XFormsView * owner = ptr->owner_;
271 owner->getLyXFunc().dispatch(ptr->funcs[ac], true);
277 void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
287 void XFormsToolbar::add(ToolbarBackend::Toolbar const & tb)
289 // we can only handle one toolbar
290 if (!toollist_.empty())
293 // The toolbar contains three vertically-aligned Boxes,
294 // the center one of which is to contain the buttons,
295 // aligned horizontally.
296 // The other two provide some visual padding.
297 BoxList & boxlist = owner_->getBox(XFormsView::Top).children();
298 toolbar_ = &boxlist.push_back(Box(0,0));
300 int const padding = 2 + abs(fl_get_border_width());
301 toolbar_->children().push_back(Box(0, padding));
303 Box & toolbar_center = toolbar_->children().push_back(Box(0,0));
304 toolbar_center.set(Box::Horizontal);
305 toolbar_buttons_ = &toolbar_center.children();
307 toolbar_->children().push_back(Box(0, padding));
309 // Add the buttons themselves.
312 ToolbarBackend::item_iterator it = tb.items.begin();
313 ToolbarBackend::item_iterator end = tb.items.end();
314 for (; it != end; ++it)
315 add(it->first, it->second);
319 void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
324 switch (func.action) {
325 case ToolbarBackend::SEPARATOR:
326 toolbar_buttons_->push_back(Box(sepspace, 0));
328 case ToolbarBackend::MINIBUFFER:
331 case ToolbarBackend::LAYOUTS:
332 toolbar_buttons_->push_back(Box(standardspacing, 0));
336 combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
337 0, 0, 135, height, "");
339 widgets_.add(combox_, *toolbar_buttons_, 135, height);
341 fl_set_combox_browser_height(combox_, 400);
342 fl_set_object_boxtype(combox_, FL_DOWN_BOX);
343 fl_set_object_color(combox_, FL_MCOL, FL_MCOL);
344 fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
345 fl_set_object_resize(combox_, FL_RESIZE_ALL);
347 combox_->u_vdata = this;
348 fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
353 toolbar_buttons_->push_back(Box(standardspacing, 0));
355 fl_add_pixmapbutton(FL_NORMAL_BUTTON,
358 widgets_.add(obj, *toolbar_buttons_, buttonwidth, height);
360 fl_set_object_resize(obj, FL_RESIZE_ALL);
361 fl_set_object_gravity(obj,
365 Funcs::iterator fit = funcs.insert(funcs.end(), func);
366 int const index = distance(funcs.begin(), fit);
367 fl_set_object_callback(obj, C_Toolbar_ToolbarCB, index);
368 // Remove the blue feedback rectangle
369 fl_set_pixmapbutton_focus_outline(obj, 0);
371 tooltip_->init(obj, tooltip);
373 // The view that this object belongs to.
376 string const xpm = toolbarbackend.getIcon(func);
377 fl_set_pixmapbutton_file(obj, xpm.c_str());
382 toollist_.push_back(item);