summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4b6d620)
raw | patch | inline | side by side (parent: 4b6d620)
author | cilix42 <cilix42@users.sourceforge.net> | |
Thu, 4 Sep 2008 16:44:24 +0000 (16:44 +0000) | ||
committer | cilix42 <cilix42@users.sourceforge.net> | |
Thu, 4 Sep 2008 16:44:24 +0000 (16:44 +0000) |
index 78c79ebd102fb249ad47cd8ffa1141e486abc0b3..3ca113e856328e0468fc97403d7f547f059dc672 100644 (file)
" <group id=\"defaultscale\" value=\"2\"/>\n"
" <group id=\"maxrecentdocuments\" value=\"36\"/>\n"
" <group id=\"zoomincrement\" value=\"1.414213562\"/>\n"
+" <group id=\"zoomcorrection\" value=\"1.0\" unit=\"mm\"/>\n"
" <group id=\"keyscroll\" value=\"15\"/>\n"
" <group id=\"wheelscroll\" value=\"40\"/>\n"
" <group id=\"spacepans\" value=\"0\"/>\n"
index ef6c030e852377adc250e5cd31d11ea35e0f409f..dcfc4e575bfd006ccf9bfbe49878104f44ed973e 100644 (file)
_misc_small_toolbar.init( "toolbox", "small", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), 0 );
_page_ui.add_line( false, _("Commands bar icon size"), _misc_small_toolbar, "",
- _("Set the size for the commands toolbar to use (requires restart)"), false);
+ _("Set the size for the commands toolbar to use (requires restart)"), false);
_misc_small_secondary.init( "toolbox", "secondary", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), 1 );
_page_ui.add_line( false, _("Tool controls bar icon size"), _misc_small_secondary, "",
- _("Set the size for the secondary toolbar to use (requires restart)"), false);
+ _("Set the size for the secondary toolbar to use (requires restart)"), false);
_misc_small_tools.init( "toolbox.tools", "small", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), 0 );
_page_ui.add_line( false, _("Main toolbar icon size"), _misc_small_tools, "",
- _("Set the size for the main tools to use (requires restart)"), false);
+ _("Set the size for the main tools to use (requires restart)"), false);
_misc_recent.init("options.maxrecentdocuments", "value", 0.0, 1000.0, 1.0, 1.0, 1.0, true, false);
_page_ui.add_line( false, _("Maximum documents in Open Recent:"), _misc_recent, "",
- _("The maximum length of the Open Recent list in the File menu"), false);
+ _("The maximum length of the Open Recent list in the File menu"), false);
+
+ _ui_zoom_correction.init(300, 30, 1.00, 200.0, 1.0, 10.0, 1.0);
+ _page_ui.add_line( false, _("Zoom correction factor (in %):"), _ui_zoom_correction, "",
+ _("Adjust the slider until the length of the ruler on your screen matches its real length. This information is used when zooming to 1:1, 1:2, etc., to display objects in their true sizes"), true);
this->AddPage(_page_ui, _("Interface"), PREFS_PAGE_UI);
}
index 2dd0ca4df33dbe843ba57df726acc4031b178571..a6fc96a3fb3123650c629868f69f19271ad12152 100644 (file)
PrefCheckButton _sel_layer_deselects;
PrefSpinButton _importexport_export, _misc_recent, _misc_simpl;
+ ZoomCorrRulerSlider _ui_zoom_correction;
PrefSpinButton _misc_latency_skew;
PrefCheckButton _misc_comment, _misc_forkvectors, _misc_scripts, _misc_namedicon_delay;
PrefCombo _misc_small_toolbar;
index 6c5473caa062ca39e0e64f0e0257cde57170c024..d4164864b63a0e412b1421c8b935d0a827960dfd 100644 (file)
}
}
+const double ZoomCorrRuler::textsize = 7;
+const double ZoomCorrRuler::textpadding = 5;
+
+ZoomCorrRuler::ZoomCorrRuler(int width, int height) :
+ _unitconv(1.0),
+ _border(5)
+{
+ set_size(width, height);
+}
+
+void ZoomCorrRuler::set_size(int x, int y)
+{
+ _min_width = x;
+ _height = y;
+ set_size_request(x + _border*2, y + _border*2);
+}
+
+// The following two functions are borrowed from 2geom's toy-framework-2; if they are useful in
+// other locations, we should perhaps make them (or adapted versions of them) publicly available
+static void
+draw_text(cairo_t *cr, Geom::Point loc, const char* txt, bool bottom = "false",
+ double fontsize = ZoomCorrRuler::textsize, std::string fontdesc = "Sans") {
+ PangoLayout* layout = pango_cairo_create_layout (cr);
+ pango_layout_set_text(layout, txt, -1);
+
+ // set font and size
+ std::ostringstream sizestr;
+ sizestr << fontsize;
+ fontdesc = fontdesc + " " + sizestr.str();
+ PangoFontDescription *font_desc = pango_font_description_from_string(fontdesc.c_str());
+ pango_layout_set_font_description(layout, font_desc);
+ pango_font_description_free (font_desc);
+
+ PangoRectangle logical_extent;
+ pango_layout_get_pixel_extents(layout, NULL, &logical_extent);
+ cairo_move_to(cr, loc[Geom::X], loc[Geom::Y] - (bottom ? logical_extent.height : 0));
+ pango_cairo_show_layout(cr, layout);
+}
+
+static void
+draw_number(cairo_t *cr, Geom::Point pos, double num) {
+ std::ostringstream number;
+ number << num;
+ draw_text(cr, pos, number.str().c_str(), true);
+}
+
+/*
+ * \arg dist The distance between consecutive minor marks
+ * \arg major_interval Number of marks after which to draw a major mark
+ */
+void
+ZoomCorrRuler::draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int major_interval) {
+ const double zoomcorr = prefs_get_double_attribute("options.zoomcorrection", "value", 1.0);
+ double mark = 0;
+ int i = 0;
+ while (mark <= _drawing_width) {
+ cr->move_to(mark, _height);
+ if ((i % major_interval) == 0) {
+ // major mark
+ cr->line_to(mark, 0);
+ Geom::Point textpos(mark + 3, ZoomCorrRuler::textsize + ZoomCorrRuler::textpadding);
+ draw_number(cr->cobj(), textpos, dist * i);
+ } else {
+ // minor mark
+ cr->line_to(mark, ZoomCorrRuler::textsize + 2 * ZoomCorrRuler::textpadding);
+ }
+ mark += dist * zoomcorr / _unitconv;
+ ++i;
+ }
+}
+
+void
+ZoomCorrRuler::redraw() {
+ Glib::RefPtr<Gdk::Window> window = get_window();
+ Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
+
+ int w, h;
+ window->get_size(w, h);
+ _drawing_width = w - _border * 2;
+
+ cr->set_source_rgb(1.0, 1.0, 1.0);
+ cr->set_fill_rule(Cairo::FILL_RULE_WINDING);
+ cr->rectangle(0, 0, w, _height + _border*2);
+ cr->fill();
+
+ cr->set_source_rgb(0.0, 0.0, 0.0);
+ cr->set_line_width(0.5);
+
+ cr->translate(_border, _border); // so that we have a small white border around the ruler
+ cr->move_to (0, _height);
+ cr->line_to (_drawing_width, _height);
+
+ const char *abbr = prefs_get_string_attribute("options.zoomcorrection", "unit");
+ if (!strcmp(abbr, "cm")) {
+ draw_marks(cr, 0.1, 10);
+ } else if (!strcmp(abbr, "ft")) {
+ draw_marks(cr, 1/12.0, 12);
+ } else if (!strcmp(abbr, "in")) {
+ draw_marks(cr, 0.25, 4);
+ } else if (!strcmp(abbr, "m")) {
+ draw_marks(cr, 1/10.0, 10);
+ } else if (!strcmp(abbr, "mm")) {
+ draw_marks(cr, 10, 10);
+ } else if (!strcmp(abbr, "pc")) {
+ draw_marks(cr, 1, 10);
+ } else if (!strcmp(abbr, "pt")) {
+ draw_marks(cr, 10, 10);
+ } else if (!strcmp(abbr, "px")) {
+ draw_marks(cr, 10, 10);
+ } else {
+ draw_marks(cr, 1, 1);
+ }
+ cr->stroke();
+}
+
+bool
+ZoomCorrRuler::on_expose_event(GdkEventExpose *event) {
+ this->redraw();
+ return true;
+}
+
+void
+ZoomCorrRulerSlider::on_slider_value_changed()
+{
+ if (this->is_visible() || freeze) //only take action if user changed value
+ {
+ freeze = true;
+ prefs_set_double_attribute ("options.zoomcorrection", "value", _slider.get_value() / 100.0);
+ _sb.set_value(_slider.get_value());
+ _ruler.redraw();
+ freeze = false;
+ }
+}
+
+void
+ZoomCorrRulerSlider::on_spinbutton_value_changed()
+{
+ if (this->is_visible() || freeze) //only take action if user changed value
+ {
+ freeze = true;
+ prefs_set_double_attribute ("options.zoomcorrection", "value", _sb.get_value() / 100.0);
+ _slider.set_value(_sb.get_value());
+ _ruler.redraw();
+ freeze = false;
+ }
+}
+
+void
+ZoomCorrRulerSlider::on_unit_changed() {
+ if (GPOINTER_TO_INT(_unit.get_data("sensitive")) == 0) {
+ // when the unit menu is initialized, the unit is set to the default but
+ // it needs to be reset later so we don't perform the change in this case
+ return;
+ }
+ prefs_set_string_attribute ("options.zoomcorrection", "unit", _unit.getUnitAbbr().c_str());
+ double conv = _unit.getConversion(_unit.getUnitAbbr(), "px");
+ _ruler.set_unit_conversion(conv);
+ if (_ruler.is_visible()) {
+ _ruler.redraw();
+ }
+}
+
+void
+ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, double upper,
+ double step_increment, double page_increment, double default_value)
+{
+ double value = prefs_get_double_attribute_limited ("options.zoomcorrection", "value", default_value, lower, upper) * 100.0;
+
+ freeze = false;
+
+ _ruler.set_size(ruler_width, ruler_height);
+
+ _slider.set_size_request(_ruler.width(), -1);
+ _slider.set_range (lower, upper);
+ _slider.set_increments (step_increment, page_increment);
+ _slider.set_value (value);
+ _slider.set_digits(2);
+
+ _slider.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed));
+ _sb.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_spinbutton_value_changed));
+ _unit.signal_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_unit_changed));
+
+ _sb.set_range (lower, upper);
+ _sb.set_increments (step_increment, page_increment);
+ _sb.set_value (value);
+ _sb.set_digits(2);
+
+ _unit.set_data("sensitive", GINT_TO_POINTER(0));
+ _unit.setUnitType(UNIT_TYPE_LINEAR);
+ _unit.set_data("sensitive", GINT_TO_POINTER(1));
+ _unit.setUnit(prefs_get_string_attribute ("options.zoomcorrection", "unit"));
+
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
+ Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
+ alignment1->add(_sb);
+ alignment2->add(_unit);
+
+ table->attach(_slider, 0, 1, 0, 1);
+ table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
+ table->attach(_ruler, 0, 1, 1, 2);
+ table->attach(*alignment2, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0));
+
+ this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
+}
+
void PrefCombo::init(const std::string& prefs_path, const std::string& attr,
Glib::ustring labels[], int values[], int num_items, int default_value)
{
index 0b907ae346b508a4e3bb3186c2938b9abeeb0f85..9f10f8ca864ac6394ced8fde2a7065574262a091 100644 (file)
#include <gtkmm/treeview.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/box.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/drawingarea.h>
#include <gtkmm/frame.h>
#include <gtkmm/filechooserbutton.h>
#include <sigc++/sigc++.h>
void on_value_changed();
};
+class ZoomCorrRuler : public Gtk::DrawingArea {
+public:
+ ZoomCorrRuler(int width = 100, int height = 20);
+ void set_size(int x, int y);
+ void set_unit_conversion(double conv) { _unitconv = conv; }
+ void set_cairo_context(Cairo::RefPtr<Cairo::Context> cr);
+ void redraw();
+
+ int width() { return _min_width + _border*2; }
+
+ static const double textsize;
+ static const double textpadding;
+
+private:
+ bool on_expose_event(GdkEventExpose *event);
+ void draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int major_interval);
+
+ double _unitconv;
+ int _min_width;
+ int _height;
+ int _border;
+ int _drawing_width;
+};
+
+class ZoomCorrRulerSlider : public Gtk::VBox
+{
+public:
+ void init(int ruler_width, int ruler_height, double lower, double upper,
+ double step_increment, double page_increment, double default_value);
+
+private:
+ void on_slider_value_changed();
+ void on_spinbutton_value_changed();
+ void on_unit_changed();
+
+ Gtk::SpinButton _sb;
+ UnitMenu _unit;
+ Gtk::HScale _slider;
+ ZoomCorrRuler _ruler;
+ bool freeze; // used to block recursive updates of slider and spinbutton
+};
+
class PrefCombo : public Gtk::ComboBoxText
{
public:
diff --git a/src/verbs.cpp b/src/verbs.cpp
index a19ac77536ee4a489c9b0db20afbefbb587a9997..6b8d0a1fada0b6a1565550ffde5ad1616a9860cf 100644 (file)
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
}
case SP_VERB_ZOOM_1_1:
{
+ double zcorr = prefs_get_double_attribute ("options.zoomcorrection", "value", 1.0);
NR::Rect const d = dt->get_display_area();
- dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 1.0 );
+ dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 1.0 * zcorr );
break;
}
case SP_VERB_ZOOM_1_2:
{
+ double zcorr = prefs_get_double_attribute ("options.zoomcorrection", "value", 1.0);
NR::Rect const d = dt->get_display_area();
- dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 0.5);
+ dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 0.5 * zcorr );
break;
}
case SP_VERB_ZOOM_2_1:
{
+ double zcorr = prefs_get_double_attribute ("options.zoomcorrection", "value", 1.0);
NR::Rect const d = dt->get_display_area();
- dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 2.0 );
+ dt->zoom_absolute( d.midpoint()[NR::X], d.midpoint()[NR::Y], 2.0 * zcorr );
break;
}
case SP_VERB_ZOOM_PAGE: