2 * \file FormColorpicker.C
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
8 * Full author contact details are available in file CREDITS.
13 #include "FormColorpicker.h"
14 #include "forms/form_colorpicker.h"
17 #include "xforms_resize.h"
22 #include "support/filetools.h" // LibFileSearch
23 #include "support/LAssert.h"
24 #include "support/tostr.h"
26 #include "lyx_forms.h"
32 GUI_COLOR_CHOICE = FL_FREE_COL13,
33 GUI_COLOR_HUE_DIAL = FL_FREE_COL14,
37 string const fillLabel(RGBColor const & rgb)
39 return tostr(rgb.r) + ", " + tostr(rgb.g) + ", " + tostr(rgb.b);
43 string const fillLabel(HSVColor const & hsv)
45 int const h = int(hsv.h);
46 int const s = int(100.0 * hsv.s);
47 int const v = int(100.0 * hsv.v);
49 return tostr(h) + ", " + tostr(s) + ", " + tostr(v);
57 // Callback function invoked by xforms when the dialog is closed by the
59 static int C_WMHideCB(FL_FORM * form, void *);
64 FormColorpicker::FormColorpicker()
66 title_(_("Select Color")),
68 icon_pixmap_(0), icon_mask_(0),
69 tooltips_(new Tooltips)
73 FormColorpicker::~FormColorpicker()
76 XFreePixmap(fl_get_display(), icon_pixmap_);
80 RGBColor const & FormColorpicker::requestColor(RGBColor const & color)
87 fl_deactivate_all_forms();
88 fl_activate_form(form());
94 fl_activate_all_forms();
99 void FormColorpicker::show()
106 // make sure the form is up to date.
107 fl_freeze_form(form());
109 fl_unfreeze_form(form());
111 if (form()->visible) {
112 fl_raise_form(form());
113 /* This XMapWindow() will hopefully ensure that
114 * iconified dialogs are de-iconified. Mad props
115 * out to those crazy Xlib guys for forgetting a
116 * XDeiconifyWindow(). At least WindowMaker, when
117 * being notified of the redirected MapRequest will
118 * specifically de-iconify. From source, fvwm2 seems
121 XMapWindow(fl_get_display(), form()->window);
123 // calls to fl_set_form_minsize/maxsize apply only to the next
124 // fl_show_form(), so this comes first.
125 fl_set_form_minsize(form(), minw_, minh_);
127 string const maximize_title = "LyX: " + title_;
128 int const iconify_policy =
129 lyxrc.dialogs_iconify_with_main ? FL_TRANSIENT : 0;
132 FL_PLACE_MOUSE | FL_FREE_SIZE,
134 maximize_title.c_str());
139 void FormColorpicker::hide() const
141 // xforms sometimes tries to process a hint-type MotionNotify, and
142 // use XQueryPointer, without verifying if the window still exists.
143 // So we try to clear out motion events in the queue before the
145 XSync(fl_get_display(), false);
147 if (form() && form()->visible)
148 fl_hide_form(form());
152 void FormColorpicker::build()
154 dialog_.reset(build_colorpicker(this));
155 rgb_.reset(build_colorpicker_rgb(this));
156 hsv_.reset(build_colorpicker_hsv(this));
158 fl_set_object_color(dialog_->button_color,
159 GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
161 fl_set_object_color(hsv_->dial_hue, GUI_COLOR_HUE_DIAL, FL_BLACK);
162 fl_set_dial_bounds(hsv_->dial_hue, 0.0, 360.0);
163 fl_set_dial_step(hsv_->dial_hue, 1.0);
164 fl_set_dial_return(hsv_->dial_hue, FL_RETURN_CHANGED);
166 fl_set_slider_bounds(hsv_->slider_saturation, 0.0, 1.0);
167 fl_set_slider_step(hsv_->slider_saturation, 0.01);
168 fl_set_slider_return(hsv_->slider_saturation, FL_RETURN_CHANGED);
170 fl_set_slider_bounds(hsv_->slider_value, 0.0, 1.0);
171 fl_set_slider_step(hsv_->slider_value, 0.01);
172 fl_set_slider_return(hsv_->slider_value, FL_RETURN_CHANGED);
174 fl_set_slider_bounds(rgb_->slider_red, 0.0, 255.0);
175 fl_set_slider_step(rgb_->slider_red, 1.0);
176 fl_set_slider_return(rgb_->slider_red, FL_RETURN_CHANGED);
178 fl_set_slider_bounds(rgb_->slider_green, 0.0, 255.0);
179 fl_set_slider_step(rgb_->slider_green, 1.0);
180 fl_set_slider_return(rgb_->slider_green, FL_RETURN_CHANGED);
182 fl_set_slider_bounds(rgb_->slider_blue, 0.0, 255.0);
183 fl_set_slider_step(rgb_->slider_blue, 1.0);
184 fl_set_slider_return(rgb_->slider_blue, FL_RETURN_CHANGED);
187 fl_addto_tabfolder(dialog_->tabfolder,_("RGB").c_str(), rgb_->form);
188 fl_addto_tabfolder(dialog_->tabfolder,_("HSV").c_str(), hsv_->form);
192 void FormColorpicker::update() const
194 fl_mapcolor(GUI_COLOR_CHOICE, color_.r, color_.g, color_.b);
196 FL_FORM * folder = fl_get_active_folder(dialog_->tabfolder);
201 if (folder == rgb_->form) {
202 fl_set_slider_value(rgb_->slider_red, color_.r);
203 fl_set_slider_value(rgb_->slider_green, color_.g);
204 fl_set_slider_value(rgb_->slider_blue, color_.b);
206 fl_set_object_label(dialog_->text_color_values,
207 fillLabel(color_).c_str());
209 } else if (folder == hsv_->form) {
210 HSVColor hsv = HSVColor(color_);
211 hsv.h = std::max(hsv.h, 0.0);
213 fl_set_dial_value(hsv_->dial_hue, hsv.h);
214 fl_set_slider_value(hsv_->slider_saturation, hsv.s);
215 fl_set_slider_value(hsv_->slider_value, hsv.v);
217 fl_set_object_label(dialog_->text_color_values,
218 fillLabel(hsv).c_str());
220 RGBColor col = HSVColor(hsv.h, 1.0, 1.0);
221 col.r = std::max(col.r, 0u);
222 fl_mapcolor(GUI_COLOR_HUE_DIAL, col.r, col.g, col.b);
223 fl_redraw_object(hsv_->dial_hue);
228 void FormColorpicker::input(FL_OBJECT * ob, long)
230 if (ob == dialog_->tabfolder) {
233 } else if (ob == hsv_->dial_hue ||
234 ob == hsv_->slider_saturation ||
235 ob == hsv_->slider_value) {
238 } else if (ob == rgb_->slider_red ||
239 ob == rgb_->slider_green ||
240 ob == rgb_->slider_blue) {
243 } else if (ob == dialog_->button_ok) {
247 } else if (ob == dialog_->button_close || ob == 0) {
248 color_ = input_color_;
255 FL_FORM * FormColorpicker::form() const
257 return dialog_.get() ? dialog_->form : 0;
261 Tooltips & FormColorpicker::tooltips() const
267 void FormColorpicker::prepare_to_show()
269 double const scale = get_scale_to_fit(form());
271 scale_form_horizontally(form(), scale);
273 // work around dumb xforms sizing bug
277 fl_set_form_atclose(form(), C_WMHideCB, 0);
279 // set the title for the minimized form
280 if (!lyxrc.dialogs_iconify_with_main)
281 fl_winicontitle(form()->window, title_.c_str());
283 // assign an icon to the form
284 string const iconname =
285 lyx::support::LibFileSearch("images", "lyx", "xpm");
287 if (!iconname.empty()) {
289 icon_pixmap_ = fl_read_pixmapfile(fl_root,
295 fl_set_form_icon(form(), icon_pixmap_, icon_mask_);
300 void FormColorpicker::InputRGB()
302 int const red = int(fl_get_slider_value(rgb_->slider_red));
303 int const green = int(fl_get_slider_value(rgb_->slider_green));
304 int const blue = int(fl_get_slider_value(rgb_->slider_blue));
306 color_ = RGBColor(red, green, blue);
308 fl_freeze_form(dialog_->form);
310 fl_set_object_label(dialog_->text_color_values,
311 fillLabel(color_).c_str());
313 fl_mapcolor(GUI_COLOR_CHOICE, color_.r, color_.g, color_.b);
314 fl_redraw_object(dialog_->button_color);
316 fl_unfreeze_form(dialog_->form);
320 void FormColorpicker::InputHSV()
322 double const hue = fl_get_dial_value(hsv_->dial_hue);
323 double const sat = fl_get_slider_value(hsv_->slider_saturation);
324 double const val = fl_get_slider_value(hsv_->slider_value);
326 HSVColor hsv = HSVColor(hue, sat, val);
329 fl_freeze_form(dialog_->form);
331 fl_set_object_label(dialog_->text_color_values, fillLabel(hsv).c_str());
333 fl_mapcolor(GUI_COLOR_CHOICE, color_.r, color_.g, color_.b);
334 fl_redraw_object(dialog_->button_color);
336 RGBColor col = HSVColor(hue, 1.0, 1.0);
337 col.r = std::max(col.r, 0u);
338 fl_mapcolor(GUI_COLOR_HUE_DIAL, col.r, col.g, col.b);
339 fl_redraw_object(hsv_->dial_hue);
341 fl_unfreeze_form(dialog_->form);
347 void C_FormColorpickerInputCB(FL_OBJECT * ob, long d)
349 lyx::support::Assert(ob && ob->form && ob->form->u_vdata);
350 FormColorpicker * ptr =
351 static_cast<FormColorpicker *>(ob->form->u_vdata);
356 static int C_WMHideCB(FL_FORM * form, void *)
358 // Close the dialog cleanly, even if the WM is used to do so.
359 lyx::support::Assert(form && form->u_vdata);
360 FormColorpicker * ptr = static_cast<FormColorpicker *>(form->u_vdata);