diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 7cc81b93f..9e4a1dd8e 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -10,6 +10,7 @@ set(THEMEDIR "themes") # Other images which are generated manually: file(GLOB IMAGES_NONTHEMED LIST_DIRECTORIES false "images/non-themed/png/*") +file(GLOB SVG_NONTHEMED LIST_DIRECTORIES false "images/non-themed/rt-splash.svg") file(GLOB SVG_THEMED LIST_DIRECTORIES false "images/themed/svg/*") if(WIN32) @@ -51,6 +52,8 @@ install(DIRECTORY ${THEMEDIR} DESTINATION "${DATADIR}") #install(DIRECTORY ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images/") install(FILES ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images") install(FILES ${SVG_THEMED} DESTINATION "${DATADIR}/images") +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/non-themed/rt-splash.svg" DESTINATION "${DATADIR}/images" RENAME splash.svg) + if(APPLE) # CMake escapes first item quote character. Do not remove 'DUMMY_VARIABLE=' diff --git a/rtdata/images/non-themed/rt-splash.svg b/rtdata/images/non-themed/rt-splash.svg index 87b493153..15ba2532c 100644 --- a/rtdata/images/non-themed/rt-splash.svg +++ b/rtdata/images/non-themed/rt-splash.svg @@ -1,6 +1,4 @@ - - + version="1.1" + viewBox="0 0 146.05 91.545836" + height="346" + width="552"> + width="1.4" + y="-0.2" + x="-0.2" + id="filter3580"> + result="result91" /> + in="SourceGraphic" + operator="over" /> + y1="102.90127" + x1="89.69368" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3697" + xlink:href="#linearGradient3962-8" /> + id="stop3964-8" /> + id="stop3966-8" /> + y1="109.56621" + x1="69.426155" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3699" + xlink:href="#linearGradient3954-7" /> + id="stop3956-7" /> + id="stop3958-6" /> + y1="47.984013" + x1="35.142246" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3701" + xlink:href="#linearGradient4002-3" /> + id="linearGradient4002-3"> + id="stop4004-0" /> + id="stop4006-3" /> + y1="92.042343" + x1="35.907295" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3703" + xlink:href="#linearGradient4024-9" /> + id="stop4026-2" /> + id="stop4028-5" /> + y1="69.662819" + x1="28.165936" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3705" + xlink:href="#linearGradient4018-0" /> + id="linearGradient4018-0"> + id="stop4020-5" /> + id="stop4022-9" /> + y1="50.126869" + x1="104.45396" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3707" + xlink:href="#linearGradient3978-6" /> + style="stop-color:#f18e01;stop-opacity:1;" /> + id="stop3982-2" /> + y1="35.151196" + x1="48.471462" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3709" + xlink:href="#linearGradient3994-4" /> + id="linearGradient3994-4"> + id="stop3996-7" /> + id="stop3998-7" /> + y1="70.38826" + x1="108.90713" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3711" + xlink:href="#linearGradient3970-4" /> + id="stop3972-8" /> + id="stop3974-1" /> + y1="103.2584" + x1="49.885166" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3713" + xlink:href="#linearGradient3946-8" /> + id="stop3948-9" /> + id="stop3950-3" /> + y1="35.440266" + x1="90.159142" + gradientTransform="matrix(0.97301537,0,0,0.97301537,0.02024555,6.4916122)" + gradientUnits="userSpaceOnUse" + id="linearGradient3715" + xlink:href="#linearGradient3986-8" /> + id="stop3988-0" /> + id="stop3990-2" /> + width="1" + y="0" + x="0" + id="filter4905"> + result="result1" + id="feFlood4907" /> - + - + id="feComposite4911" /> + - + - + - + - + - + - + - + - + - + + y1="35.440266" + x1="90.159142" + gradientTransform="matrix(0.97997915,0,0,0.97997915,-15.63941,-144.68006)" + gradientUnits="userSpaceOnUse" + id="linearGradient3695" + xlink:href="#linearGradient3986-8" /> + x="-0.2" + y="-0.2" + height="1.4" + width="1.4"> + flood-color="rgb(255,255,255)" + result="flood" /> + in="flood" + operator="in" + result="composite1" /> + result="blur" /> + in="SourceGraphic" + operator="over" + result="composite2" /> + x="-0.2" + y="-0.2" + height="1.4" + width="1.4"> + flood-color="rgb(255,255,255)" + result="flood" /> + in="flood" + operator="in" + result="composite1" /> + result="blur" /> + in="SourceGraphic" + operator="over" + result="composite2" /> + x="-0.2" + y="-0.2" + height="1.4" + width="1.4"> + flood-color="rgb(255,255,255)" + result="flood" /> + in="flood" + operator="in" + result="composite1" /> + result="blur" /> + in="SourceGraphic" + operator="over" + result="composite2" /> + x="-0.2" + y="-0.2" + height="1.4" + width="1.4"> + flood-color="rgb(255,255,255)" + result="flood" /> + in="flood" + operator="in" + result="composite1" /> + result="blur" /> + in="SourceGraphic" + operator="over" + result="composite2" /> + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - @@ -599,259 +656,551 @@ image/svg+xml - + + transform="translate(0,-205.45415)" + id="layer1"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Apply glow effects using filters. You might need to ungroup the circle elements before applying. You can change the flood color of the "ring shadow" effect to make it white if you want to make the logo usable on a dark background. For logo specifics, refer to rt_logo.svg "Raw": font ITC Eras Std Ultra, appears in Inkscape as ITC Eras Standard - Ultra-Bold, 60pt, -3px spacing between characters."Therapee": font ITC Eras Std Medium, appears in Inkscape as ITC Eras Standard - Medium, 60pt, +1px spacing between characters.Version: font ITC Eras Std Bold, appears in Inkscape as ITC Eras Standard - Bold, 64pt, skewed -3°. RawTherapee splash screen design version 1.1 from 2017-01-28 | www.rawtherapee.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Release Candidate 1 + - + transform="matrix(1.0054447,0,0,1.0054447,35.903372,-17.90912)"> + style="color:#000000;fill:url(#linearGradient1684);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1686);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1688);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1690);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1692);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1694);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1696);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1698);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1700);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + style="color:#000000;fill:url(#linearGradient1702);fill-opacity:1;stroke:#000000;stroke-width:0.19347176;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.15686275" /> + id="path1620" /> + id="path1622" /> + id="g1654"> + id="path1628" /> + id="path1630" /> + id="path1632" /> + id="path1634" /> + id="path1636" /> + id="path1638" /> + id="path1640" /> + id="path1642" /> + id="path1644" /> + id="path1646" /> + id="path1648" /> + id="path1650" /> + id="path1652" /> - Apply glow effects using filters. You might need to ungroup the circle elements before applying. You can change the flood color of the "ring shadow" effect to make it white if you want to make the logo usable on a dark background. For logo specifics, refer to rt_logo.svg "Raw": font ITC Eras Std Ultra, appears in Inkscape as ITC Eras Standard - Ultra-Bold, 60pt, -3px spacing between characters."Therapee": font ITC Eras Std Medium, appears in Inkscape as ITC Eras Standard - Medium, 60pt, +1px spacing between characters.Version: font ITC Eras Std Bold, appears in Inkscape as ITC Eras Standard - Bold, 64pt, skewed -3°. RawTherapee splash screen design version 1.1 from 2017-01-28 | www.rawtherapee.com Therapee GNU GPLv3 5 . 5 - + id="tspan1674">. 5 + transform="matrix(0.24804687,0,0,0.2480469,-175.38276,273.1232)" + id="g1682"> Development - - - Release Candidate 1 + id="tspan1678">Development diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index b18a8f2d9..48bb19aed 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -62,7 +62,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) cAddPicker = colPickAdd ? Gdk::Cursor::create(display, colPickAdd, (int)(4.*s), (int)(21.*s)) : Gdk::Cursor::create(display, Gdk::PLUS); cCropDraw = cropDraw ? Gdk::Cursor::create(display, cropDraw, (int)(3.*s), (int)(3.*s)) : Gdk::Cursor::create(display, Gdk::DIAMOND_CROSS); cCrosshair = crosshair ? Gdk::Cursor::create(display, crosshair, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::CROSSHAIR); - cEmpty = empty ? Gdk::Cursor::create(display, empty, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BLANK_CURSOR); + cEmpty = empty ? Gdk::Cursor::create(display, empty, 12, 12) /* PNG: do not scale */ : Gdk::Cursor::create(display, Gdk::BLANK_CURSOR); cHandClosed = handClosed ? Gdk::Cursor::create(display, handClosed, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND1); cHandOpen = handOpen ? Gdk::Cursor::create(display, handOpen, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND2); cMoveBL = moveBL ? Gdk::Cursor::create(display, moveBL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BOTTOM_LEFT_CORNER); diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index e8b92062a..a9e53989f 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -734,6 +734,7 @@ void DiagonalCurveEditorSubGroup::switchGUI() dCurve->paramCurveEd.at(3) ); + double s = (double)RTScalable::getScale(); highlights->setValue (dCurve->paramCurveEd.at(4)); highlights->setLabel(label[3]); lights->setValue (dCurve->paramCurveEd.at(5)); @@ -744,7 +745,10 @@ void DiagonalCurveEditorSubGroup::switchGUI() shadows->setLabel(label[0]); shcSelector->coloredBar.setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); shcSelector->coloredBar.setBgGradient(bgGradient); - shcSelector->setMargins( (leftBar ? CBAR_WIDTH + CBAR_MARGIN : RADIUS), RADIUS ); + shcSelector->setMargins( + (int)( ((leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5) * s ), + (int)((RADIUS - 1.5) * s) + ); paramCurve->setColoredBar(leftBar, nullptr); paramCurve->queue_resize_no_redraw(); updateEditButton(dCurve, editParam, editParamConn); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index e6fde1bc8..a2fe46531 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -176,6 +176,25 @@ void setExpandAlignProperties(Gtk::Widget *widget, bool hExpand, bool vExpand, e widget->set_valign(vAlign); } +Gtk::Border getPadding(const Glib::RefPtr style) +{ + Gtk::Border padding; + if (!style) { + return padding; + } + + int s = (double)RTScalable::getScale(); + padding = style->get_padding(); + if (s > 1) { + padding.set_left(padding.get_left() * s); + padding.set_right(padding.get_right() * s); + padding.set_top(padding.get_top() * s); + padding.set_bottom(padding.get_bottom() * s); + } + + return padding; +} + bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference) { @@ -576,7 +595,7 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) : setExpandAlignProperties(headerHBox, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); if (useEnabled) { - statusImage = Gtk::manage(new RTImage(*(disabledImage.operator ->()))); + statusImage = Gtk::manage(new RTImage(disabledImage)); imageEvBox = Gtk::manage(new Gtk::EventBox()); imageEvBox->add(*statusImage); imageEvBox->set_above_child(true); @@ -585,7 +604,7 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) : imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0); } else { - statusImage = Gtk::manage(new RTImage(*(openedImage.operator ->()))); + statusImage = Gtk::manage(new RTImage(openedImage)); headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0); } @@ -629,7 +648,7 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : if (useEnabled) { - statusImage = Gtk::manage(new RTImage(*(disabledImage.operator ->()))); + statusImage = Gtk::manage(new RTImage(disabledImage)); imageEvBox = Gtk::manage(new Gtk::EventBox()); imageEvBox->set_name("MyExpanderStatus"); imageEvBox->add(*statusImage); @@ -639,7 +658,7 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0); } else { - statusImage = Gtk::manage(new RTImage(*(openedImage.operator ->()))); + statusImage = Gtk::manage(new RTImage(openedImage)); headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0); } @@ -759,12 +778,12 @@ void MyExpander::set_inconsistent(bool isInconsistent) if (useEnabled) { if (isInconsistent) { - statusImage->set(inconsistentImage->get_pixbuf()); + statusImage->set(inconsistentImage->get_surface()); } else { if (enabled) { - statusImage->set(enabledImage->get_pixbuf()); + statusImage->set(enabledImage->get_surface()); } else { - statusImage->set(disabledImage->get_pixbuf()); + statusImage->set(disabledImage->get_surface()); } } } @@ -790,14 +809,14 @@ void MyExpander::setEnabled(bool isEnabled) enabled = false; if (!inconsistent) { - statusImage->set(disabledImage->get_pixbuf()); + statusImage->set(disabledImage->get_surface()); message.emit(); } } else { enabled = true; if (!inconsistent) { - statusImage->set(enabledImage->get_pixbuf()); + statusImage->set(enabledImage->get_surface()); message.emit(); } } @@ -833,9 +852,9 @@ void MyExpander::set_expanded( bool expanded ) if (!useEnabled) { if (expanded ) { - statusImage->set(openedImage->get_pixbuf()); + statusImage->set(openedImage->get_surface()); } else { - statusImage->set(closedImage->get_pixbuf()); + statusImage->set(closedImage->get_surface()); } } @@ -878,9 +897,19 @@ bool MyExpander::on_toggle(GdkEventButton* event) if (!useEnabled) { if (isVisible) { - statusImage->set(closedImage->get_pixbuf()); + statusImage->set(closedImage->get_surface()); + if (closedImage->get_surface().operator bool()) { + Cairo::RefPtr p = closedImage->get_surface(); + int w = p->get_width(); + int h = p->get_height(); + } } else { - statusImage->set(openedImage->get_pixbuf()); + statusImage->set(openedImage->get_surface()); + if (openedImage->get_surface().operator bool()) { + Cairo::RefPtr p = openedImage->get_surface(); + int w = p->get_width(); + int h = p->get_height(); + } } } @@ -905,10 +934,10 @@ bool MyExpander::on_enabled_change(GdkEventButton* event) if (event->button == 1) { if (enabled) { enabled = false; - statusImage->set(disabledImage->get_pixbuf()); + statusImage->set(disabledImage->get_surface()); } else { enabled = true; - statusImage->set(enabledImage->get_pixbuf()); + statusImage->set(enabledImage->get_surface()); } message.emit(); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 38876d40a..1ab989882 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -43,6 +43,7 @@ void writeFailed (Gtk::Window& parent, const std::string& filename); void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide = true, bool useBgColor = true, bool fullImageVisible = true); gboolean acquireGUI(void* data); void setExpandAlignProperties(Gtk::Widget *widget, bool hExpand, bool vExpand, enum Gtk::Align hAlign, enum Gtk::Align vAlign); +Gtk::Border getPadding(const Glib::RefPtr style); class IdleRegister final : public rtengine::NonCopyable diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index f680c7322..81d4ee170 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -70,8 +70,10 @@ LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool isDragged(false), low_enabled(enable_low) { - set_can_focus(true); + set_can_focus(false); // prevent moving the grid while you're moving a point add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK); + set_name("LabGrid"); + get_style_context()->add_class("drawingarea"); } void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb) const @@ -157,12 +159,15 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) } Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled Cairo::RefPtr cr = getContext(); if (isDirty()) { int width = allocation.get_width(); int height = allocation.get_height(); + int s = RTScalable::getScale(); + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); // clear background @@ -170,19 +175,31 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) cr->set_operator (Cairo::OPERATOR_CLEAR); cr->paint (); cr->set_operator (Cairo::OPERATOR_OVER); - style->render_background(cr, 0, 0, width, height); + style->render_background(cr, + inset * s + padding.get_left() - s, + inset * s + padding.get_top() - s, + width - 2 * inset * s - padding.get_right() - padding.get_left() + 2 * s, + height - 2 * inset * s - padding.get_top() - padding.get_bottom() + 2 * s + ); // drawing the cells - cr->translate(inset, inset); + cr->translate(inset * s + padding.get_left(), inset * s + padding.get_top()); cr->set_antialias(Cairo::ANTIALIAS_NONE); - width -= 2 * inset; - height -= 2 * inset; + width -= 2 * inset * s + padding.get_right() + padding.get_left(); + height -= 2 * inset * s + padding.get_top() + padding.get_bottom(); + // flip y: cr->translate(0, height); cr->scale(1., -1.); const int cells = 8; float step = 12000.f / float(cells/2); + double cellW = double(width) / double(cells); + double cellH = double(height) / double(cells); + double cellYMin = 0.; + double cellYMax = std::floor(cellH); for (int j = 0; j < cells; j++) { + double cellXMin = 0.; + double cellXMax = std::floor(cellW); for (int i = 0; i < cells; i++) { float R, G, B; float x, y, z; @@ -193,9 +210,18 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) Color::Lab2XYZ(25000.f, a, b, x, y, z); Color::xyz2srgb(x, y, z, R, G, B); cr->set_source_rgb(R / 65535.f, G / 65535.f, B / 65535.f); - cr->rectangle(width * i / float(cells), height * j / float(cells), width / float(cells) - 1, height / float(cells) - 1); + cr->rectangle( + cellXMin, + cellYMin, + cellXMax - cellXMin - (i == cells-1 ? 0. : double(s)), + cellYMax - cellYMin - (j == cells-1 ? 0. : double(s)) + ); + cellXMin = cellXMax; + cellXMax = std::floor(cellW * double(i+2) + 0.01); cr->fill(); } + cellYMin = cellYMax; + cellYMax = std::floor(cellH * double(j+2) + 0.01); } // drawing the connection line @@ -205,7 +231,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) hia = .5f * (width + width * high_a); lob = .5f * (height + height * low_b); hib = .5f * (height + height * high_b); - cr->set_line_width(2.); + cr->set_line_width(2. * double(s)); cr->set_source_rgb(0.6, 0.6, 0.6); cr->move_to(loa, lob); cr->line_to(hia, hib); @@ -215,18 +241,18 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) if (low_enabled) { cr->set_source_rgb(0.1, 0.1, 0.1); if (litPoint == LOW) { - cr->arc(loa, lob, 5, 0, 2. * rtengine::RT_PI); + cr->arc(loa, lob, 5 * s, 0, 2. * rtengine::RT_PI); } else { - cr->arc(loa, lob, 3, 0, 2. * rtengine::RT_PI); + cr->arc(loa, lob, 3 * s, 0, 2. * rtengine::RT_PI); } cr->fill(); } cr->set_source_rgb(0.9, 0.9, 0.9); if (litPoint == HIGH) { - cr->arc(hia, hib, 5, 0, 2. * rtengine::RT_PI); + cr->arc(hia, hib, 5 * s, 0, 2. * rtengine::RT_PI); } else { - cr->arc(hia, hib, 3, 0, 2. * rtengine::RT_PI); + cr->arc(hia, hib, 3 * s, 0, 2. * rtengine::RT_PI); } cr->fill(); } @@ -279,11 +305,16 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) delayconn.disconnect(); } + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + State oldLitPoint = litPoint; - int width = get_allocated_width() - 2 * inset, height = get_allocated_height() - 2 * inset; - const float mouse_x = std::min(std::max(event->x - inset, 0.), double(width)); - const float mouse_y = std::min(std::max(height - 1 - event->y + inset, 0.), double(height)); + int s = RTScalable::getScale(); + int width = get_allocated_width() - 2 * inset * s - padding.get_right() - padding.get_left(); + int height = get_allocated_height() - 2 * inset * s - padding.get_top() - padding.get_bottom(); + const float mouse_x = std::min(double(std::max(event->x - inset * s - padding.get_right(), 0.)), double(width)); + const float mouse_y = std::min(double(std::max(get_allocated_height() - 1 - event->y - inset * s - padding.get_bottom(), 0.)), double(height)); const float ma = (2.0 * mouse_x - width) / (float)width; const float mb = (2.0 * mouse_y - height) / (float)height; if (isDragged) { @@ -332,14 +363,22 @@ Gtk::SizeRequestMode LabGridArea::get_request_mode_vfunc() const void LabGridArea::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const { - minimum_width = 50; - natural_width = 150; // same as GRAPH_SIZE from mycurve.h + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + int s = RTScalable::getScale(); + int p = padding.get_left() + padding.get_right(); + + minimum_width = 50 * s + p; + natural_width = 150 * s + p; // same as GRAPH_SIZE from mycurve.h } void LabGridArea::get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const { - minimum_height = natural_height = width; + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + + minimum_height = natural_height = width - padding.get_left() - padding.get_right() + padding.get_top() + padding.get_bottom(); } diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index 00266c91b..dbb0cc427 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -50,21 +50,21 @@ private: enum State { NONE, HIGH, LOW }; State litPoint; - float low_a; - float high_a; - float low_b; - float high_b; + double low_a; + double high_a; + double low_b; + double high_b; - float defaultLow_a; - float defaultHigh_a; - float defaultLow_b; - float defaultHigh_b; + double defaultLow_a; + double defaultHigh_a; + double defaultLow_b; + double defaultHigh_b; ToolPanelListener *listener; bool edited; bool isDragged; sigc::connection delayconn; - static const int inset = 2; + static const int inset = 5; bool low_enabled; diff --git a/rtgui/main.cc b/rtgui/main.cc index b4d1c7a75..1db73655f 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -319,45 +319,37 @@ RTWindow *create_rt_window() if (options.fontFamily != "default") { //GTK318 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 - css = Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", options.fontFamily, options.fontSize * scale); + css = Glib::ustring::compose ("* { font-family: %1; font-size: %2px}", options.fontFamily, options.fontSize * scale); #else - css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", options.fontFamily, options.fontSize * scale); + css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt}", options.fontFamily, options.fontSize * scale); #endif //GTK318 fontScale = options.fontSize / 9.f; - } else if (scale == 2) { + } else { Glib::RefPtr style = Gtk::StyleContext::create(); Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); + int pt; if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { int fontSize = pfd.get_size(); bool isPix = pfd.get_size_is_absolute(); - printf("FONT SIZE = %d pt\n", fontSize); - - - double r = style->get_screen()->get_resolution(); - printf("RESOLUTION = %.3f\n", r); - - + int resolution = (int)style->get_screen()->get_resolution(); if (isPix) { - // 1pt = 1/72in @ 96 ppi - // HOMBRE: If the font unit is px, is it alredy scaled up to match the resolution ? - double resolution = style->get_screen()->get_resolution(); - // px >inch >pt >"scaled pt" - int pt = (int)(fontSize / 96. * 72 * (96. / resolution) + 0.49); + // HOMBRE: guessing here... // if resolution is lower than 192ppi, we're supposing that it's already expressed in a scale==1 scenario if (resolution >= 192) { - // it's already scaled up, no need to set the font size - resolution /= 2.; // Reducing the value for a scale==1 case - pt /= 2.; - } else { - // fontSize is for scale==1, we have to scale up - css = Glib::ustring::compose ("* { font-size: %1pt }", pt * scale); + // converting the resolution to a scale==1 scenario + resolution /= 2; } - fontScale = (float)pt / 9.f; + // 1pt = 1/72in @ 96 ppi + // HOMBRE: If the font unit is px, is it alredy scaled up to match the resolution ? + // px >inch >pt >"scaled pt" + pt = (int)(fontSize / 96. * 72 * (96. / resolution) + 0.49); } else { - int pt = fontSize / Pango::SCALE; - css = Glib::ustring::compose ("* { font-size: %1pt }", pt * scale); - fontScale = (float)pt / 9.f; + pt = fontSize / Pango::SCALE; + } + fontScale = (float)pt / 9.f; + if (scale > 1 || pt != 9) { + css = Glib::ustring::compose ("* { font-size: %1pt}", pt * scale); } } else { fontScale = 1.f; diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 215eac429..5684bec33 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -21,11 +21,30 @@ #include #include -MyCurve::MyCurve () : pipetteR(-1.f), pipetteG(-1.f), pipetteB(-1.f), pipetteVal(-1.f), listener(nullptr), cursor_type(CSArrow), graphW(0), graphH(0), mod_type(Gdk::MODIFIER_MASK), cursorX(0), cursorY(0), snapToMinDistX(0.0), snapToMinDistY(0.0), snapToValX(0.0), snapToValY(0.0) +MyCurve::MyCurve () : + pipetteR(-1.f), + pipetteG(-1.f), + pipetteB(-1.f), + pipetteVal(-1.f), + listener(nullptr), + cursor_type(CSArrow), + graphX(0), + graphY(0), + graphW(0), + graphH(0), + mod_type(Gdk::MODIFIER_MASK), + cursorX(0), + cursorY(0), + snapToMinDistX(0.0), + snapToMinDistY(0.0), + snapToValX(0.0), + snapToValY(0.0) { - graphX = get_allocation().get_width() - RADIUS * 2; - graphY = get_allocation().get_height() - RADIUS * 2; + int s = RTScalable::getScale(); + int pointDiameter = (int)(RADIUS * 2.) * s; + graphW = get_allocation().get_width() - pointDiameter; + graphH = get_allocation().get_height() - pointDiameter; prevGraphW = graphW; prevGraphH = graphH; buttonPressed = false; @@ -55,26 +74,17 @@ MyCurve::~MyCurve () } } -int MyCurve::calcDimensions () +void MyCurve::calcDimensions () { - int newRequestedW, newRequestedH; + double newRequestedW, newRequestedH; + double s = (double)RTScalable::getScale(); newRequestedW = newRequestedH = get_allocation().get_width(); - if (leftBar && !bottomBar) { - newRequestedH -= CBAR_WIDTH + CBAR_MARGIN - RADIUS; - } - - if (!leftBar && bottomBar) { - newRequestedH += CBAR_WIDTH + CBAR_MARGIN - RADIUS; - } - - graphW = newRequestedW - RADIUS - (leftBar ? (CBAR_WIDTH + CBAR_MARGIN) : RADIUS); - graphH = newRequestedH - RADIUS - (bottomBar ? (CBAR_WIDTH + CBAR_MARGIN) : RADIUS); - graphX = newRequestedW - RADIUS - graphW; - graphY = RADIUS + graphH; - - return newRequestedH; + graphX = ((double)RADIUS + (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN : 0.)) * s; + graphH = graphW = newRequestedW - graphX - (double)RADIUS * s; + graphY = (double)RADIUS * s + graphW; + return; } Gtk::SizeRequestMode MyCurve::get_request_mode_vfunc () const @@ -92,28 +102,23 @@ void MyCurve::get_preferred_height_vfunc (int &minimum_height, int &natural_heig void MyCurve::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - natural_width = minimum_width = GRAPH_SIZE + 2 * RADIUS; + int s = RTScalable::getScale(); + natural_width = minimum_width = (GRAPH_SIZE + (int)(RADIUS * 2.) + (leftBar ? (CBAR_WIDTH + 2 + CBAR_MARGIN) : 0)) * s; } void MyCurve::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { minimum_height = width; + int s = RTScalable::getScale(); if (leftBar && !bottomBar) { - minimum_height -= CBAR_WIDTH + CBAR_MARGIN - RADIUS; + minimum_height -= (CBAR_WIDTH + 2 + CBAR_MARGIN) * s; } if (!leftBar && bottomBar) { - minimum_height += CBAR_WIDTH + CBAR_MARGIN - RADIUS; + minimum_height += (CBAR_WIDTH + 2 + CBAR_MARGIN) * s; } - /* - graphW = width - RADIUS - (leftBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS); - graphH = minimum_height - RADIUS - (bottomBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS); - graphX = width - RADIUS - graphW; - graphY = RADIUS + graphH; - */ - natural_height = minimum_height; } @@ -174,10 +179,10 @@ bool MyCurve::snapCoordinateY(double testedVal, double realVal) float MyCurve::getVal(LUTf &curve, int x) { - if (size_t(graphW - 2) == curve.getSize()) { + if (size_t(graphW) == curve.getSize()) { return curve[x]; } else { - return curve.getVal01(float(x) / (graphW - 3)); + return curve.getVal01(float(x) / graphW); } } diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index f555ab7ef..82dd4a1a4 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -29,9 +29,9 @@ #include "guiutils.h" #include "options.h" -#define RADIUS 3 /** radius of the control points */ -#define CBAR_WIDTH 10 /** width of the colored bar (border included) */ -#define CBAR_MARGIN 2 /** spacing between the colored bar and the graph */ +#define RADIUS 3.5 /** radius of the control points ; must be x.5 to target the center of a pixel */ +#define CBAR_WIDTH 10 /** inner width of the colored bar (border excluded) */ +#define CBAR_MARGIN 1 /** spacing between the colored bar and the graph's bullet when set at 0,0 */ #define SQUARE 2 /** half length of the square shape of the tangent handles */ #define MIN_DISTANCE 5 /** min distance between control points */ #define GRAPH_SIZE 150 /** size of the curve editor graphic */ @@ -67,8 +67,8 @@ protected: ColoredBar *leftBar; ColoredBar *bottomBar; CursorShape cursor_type; - int graphX, graphY, graphW, graphH; /// position and dimensions of the graphic area, excluding surrounding space for the points or for the colored bar - int prevGraphW, prevGraphH; /// previous inner width and height of the editor + double graphX, graphY, graphW, graphH; /// position and dimensions of the inner graphic area, excluding the graph's border and the surrounding space for the points or for the colored bar + double prevGraphW, prevGraphH; /// previous inner width and height of the editor Gdk::ModifierType mod_type; int cursorX; /// X coordinate in the graph of the cursor int cursorY; /// Y coordinate in the graph of the cursor @@ -96,16 +96,10 @@ protected: std::vector editedPos; virtual std::vector get_vector (int veclen) = 0; - int getGraphMinSize() - { - return GRAPH_SIZE + RADIUS + 1; - } bool snapCoordinateX(double testedVal, double realVal); bool snapCoordinateY(double testedVal, double realVal); float getVal(LUTf &curve, int x); - - // return value = new requested height - int calcDimensions (); + void calcDimensions (); public: MyCurve (); diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index f70f4af0f..8336ac539 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -21,16 +21,23 @@ #include #include -MyDiagonalCurve::MyDiagonalCurve () : closest_point(0), clampedX(0.0), clampedY(0.0), deltaX(0.0), deltaY(0.0), distanceX(0.0), distanceY(0.0), ugpX(0.0), ugpY(0.0), activeParam(-1), bghistvalid(false) +MyDiagonalCurve::MyDiagonalCurve () : + MyCurve(), + closest_point(0), + clampedX(0.0), + clampedY(0.0), + deltaX(0.0), + deltaY(0.0), + distanceX(0.0), + distanceY(0.0), + ugpX(0.0), + ugpY(0.0), + activeParam(-1), + bghistvalid(false) { - graphW = get_allocation().get_width() - RADIUS * 2; - graphH = get_allocation().get_height() - RADIUS * 2; - prevGraphW = graphW; - prevGraphH = graphH; grab_point = -1; lit_point = -1; - buttonPressed = false; bghist = new unsigned int[256]; @@ -182,7 +189,7 @@ void MyDiagonalCurve::interpolate () prevGraphW = graphW; prevGraphH = graphH; - int nbPoints = rtengine::max(graphW - 2, 201); + unsigned int nbPoints = (unsigned int)graphW; point(nbPoints); get_LUT (point); upoint.reset(); @@ -215,14 +222,19 @@ void MyDiagonalCurve::draw (int handle) return; } - // re-calculate curve if dimensions changed - int currPointSize = point.getUpperBound(); + const double s = (double)RTScalable::getScale(); - if (curveIsDirty || /*prevGraphW != graphW || prevGraphH != graphH ||*/ (currPointSize == GRAPH_SIZE && (graphW - 3 > GRAPH_SIZE)) || (currPointSize > GRAPH_SIZE && (graphW - 2 <= GRAPH_SIZE || graphW - 3 != currPointSize))) { + // re-calculate curve if dimensions changed + int currLUTSize = point.getUpperBound(); + + if (curveIsDirty + || (currLUTSize == (GRAPH_SIZE * s) && (graphW > (GRAPH_SIZE * s))) + || (currLUTSize > (GRAPH_SIZE * s) && (graphW <= (GRAPH_SIZE * s) || graphW != currLUTSize)) ) + { interpolate (); } - currPointSize = point.getUpperBound(); + currLUTSize = point.getUpperBound(); Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL; @@ -240,6 +252,36 @@ void MyDiagonalCurve::draw (int handle) Gdk::RGBA c; + cr->set_line_width (1.0 * s); + + // draw the left colored bar + if (leftBar) { + // first the background + BackBuffer *bb = this; + leftBar->setDrawRectangle(1. * s, graphY - graphH - 0.5, CBAR_WIDTH * s, graphH); + leftBar->expose(*this, bb); + + // now the border + c = style->get_border_color(state); + cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); + cr->rectangle(0.5 * s, graphY - graphH - 0.5 - 0.5 * s, (CBAR_WIDTH + 1) * s, (double)graphH + 1. + 1. * s); + cr->stroke(); + } + + // draw the bottom colored bar + if (bottomBar) { + // first the background + BackBuffer *bb = this; + bottomBar->setDrawRectangle(graphX - 0.5, graphY + (RADIUS + CBAR_MARGIN + 1.) * s, graphW + 1., CBAR_WIDTH * s); + bottomBar->expose(*this, bb); + + // now the border + c = style->get_border_color (state); + cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); + cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + (RADIUS + CBAR_MARGIN + 0.5) * s, graphW + 1. + 0.5 * s, (CBAR_WIDTH + 1.) * s); + cr->stroke(); + } + // histogram in the background if (bghistvalid) { // find highest bin @@ -251,9 +293,9 @@ void MyDiagonalCurve::draw (int handle) } // draw histogram - cr->set_line_width (1.0); - double stepSize = (graphW - 3) / 255.0; - cr->move_to ( double(graphX + 1), double(graphY - 1) ); + cr->set_line_width (1.0 * s); + double stepSize = graphW / 255.0; + cr->move_to (graphX, graphY); c = style->get_color(state); cr->set_source_rgba (c.get_red(), c.get_green(), c.get_blue(), 0.2); @@ -264,27 +306,27 @@ void MyDiagonalCurve::draw (int handle) val = graphH-2; */ //if (i>0) - cr->line_to (double(graphX) + 1.5 + double(i)*stepSize, double(graphY - 1) - val); + cr->line_to (graphX + double(i)*stepSize, graphY - val); } - cr->line_to (double(graphX) + 1.5 + 255.*stepSize, double(graphY - 1)); + cr->line_to (graphX + 255.*stepSize, graphY); cr->close_path(); cr->fill (); } // draw the grid lines: - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_antialias (Cairo::ANTIALIAS_NONE); for (int i = 0; i <= 10; i++) { // horizontal lines - cr->move_to (double(graphX) + 0.5 , double(graphY) - max(0.5, double(graphH * i / 10) - 0.5)); - cr->rel_line_to (double(graphW - 1) , 0.); + cr->move_to (graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s - (graphH + 1. + 1. * s) * (double)i / 10.); + cr->rel_line_to (graphW + 1. + 1. * s, 0.); // vertical lines - cr->move_to (double(graphX) + max(0.5, double(graphW * i / 10) - 0.5), double(graphY)); - cr->rel_line_to (0. , double(-graphH + 1)); + cr->move_to (graphX - 0.5 - 0.5 * s + (graphW + 1. + 1. * s) * (double)i / 10., graphY + 0.5 + 0.5 * s); + cr->rel_line_to (0., -graphH - 1. - 1. * s); } cr->stroke (); @@ -297,31 +339,27 @@ void MyDiagonalCurve::draw (int handle) } std::valarray ds (1); - ds[0] = 4; + ds[0] = 4 * s; cr->set_dash (ds, 0); - cr->move_to (double(graphX) + 1.5, double(graphY) - 1.5); - cr->rel_line_to (double(graphW - 3), double(-graphH + 3)); + cr->move_to (graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s); + cr->rel_line_to (graphW + 1. + 1. * s, -(graphH + 1. + 1. * s)); cr->stroke (); cr->unset_dash (); cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); // draw upper and lower bounds - float graphH_ = float(graphH - 3); - float graphX_ = float(graphX) + 1.5; - float graphY_ = float(graphY) - 1.5; - if (curve.type == DCT_Parametric && activeParam > 0 && lpoint.getUpperBound() > 1 && upoint.getUpperBound() > 1) { cr->set_source_rgba (1.0, 1.0, 1.0, 0.1); - cr->move_to (graphX_, getVal(upoint, 0) * -graphH_ + graphY_); + cr->move_to (graphX, getVal(upoint, 0) * -graphH + graphY); for (int i = 1; i < graphW - 2; ++i) { - cr->line_to (float(i) + graphX_, getVal(upoint, i) * -graphH_ + graphY_); + cr->line_to ((double)i + graphX, getVal(upoint, i) * -graphH + graphY); } for (int i = graphW - 3; i >= 0; --i) { - cr->line_to (float(i) + graphX_, getVal(lpoint, i) * -graphH_ + graphY_); + cr->line_to ((double)i + graphX, getVal(lpoint, i) * -graphH + graphY); } cr->fill (); @@ -346,34 +384,34 @@ void MyDiagonalCurve::draw (int handle) if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteR, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteR, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteG, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteG, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteB, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteB, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } } if (pipetteVal > -1.f) { - cr->set_line_width (2.); + cr->set_line_width (2. * s); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteVal, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteVal, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); - cr->set_line_width (1.); + cr->set_line_width (1. * s); } } @@ -383,9 +421,9 @@ void MyDiagonalCurve::draw (int handle) if (curve.type == DCT_NURBS) { unsigned int nbPoints; std::valarray ch_ds (1); - ch_ds[0] = 2; + ch_ds[0] = 2 * s; cr->set_dash (ch_ds, 0); - cr->set_line_width (0.75); + cr->set_line_width (0.75 * s); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); std::vector points = getPoints(); nbPoints = ((int)points.size() - 1) / 2; @@ -393,10 +431,10 @@ void MyDiagonalCurve::draw (int handle) for (unsigned int i = 1; i < nbPoints; i++) { int pos = i * 2 + 1; - double x1 = double(graphX) + 1.5 + double(graphW - 3) * points[pos - 2]; // project (curve.at(i), 0, 1, graphW); - double y1 = double(graphY) - 1.5 - double(graphH - 3) * points[pos - 1]; // project (curve.y.at(i)i], 0, 1, graphH); - double x2 = double(graphX) + 0.5 + double(graphW - 3) * points[pos]; // project (curve.at(i), 0, 1, graphW); - double y2 = double(graphY) - 1.5 - double(graphH - 3) * points[pos + 1]; // project (curve.y.at(i), 0, 1, graphH); + double x1 = graphX + graphW * points[pos - 2]; // project (curve.at(i), 0, 1, graphW); + double y1 = graphY - graphH * points[pos - 1]; // project (curve.y.at(i)i], 0, 1, graphH); + double x2 = graphX + graphW * points[pos ]; // project (curve.at(i), 0, 1, graphW); + double y2 = graphY - graphH * points[pos + 1]; // project (curve.y.at(i), 0, 1, graphH); // set the color of the line when the point is snapped to the cage if (curve.x.size() == nbPoints && snapToElmt >= 1000 && ((int(i) == (snapToElmt - 1000)) || (int(i) == (snapToElmt - 999)))) { @@ -411,49 +449,19 @@ void MyDiagonalCurve::draw (int handle) } cr->unset_dash (); - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); } // draw curve cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX_, getVal(point, 0) * -graphH_ + graphY_); + cr->move_to (graphX, getVal(point, 0) * -graphH + graphY); - for (int i = 1; i < graphW - 2; ++i) { - cr->line_to (float(i) + graphX_, getVal(point, i) * -graphH_ + graphY_); + for (int i = 1; i < graphW; ++i) { + cr->line_to ((double)i + graphX, (double)getVal(point, i) * -graphH + graphY); } cr->stroke (); - // draw the left colored bar - if (leftBar) { - // first the background - int bWidth = CBAR_WIDTH; - BackBuffer *bb = this; - leftBar->setDrawRectangle(1, graphY - graphH + 1, bWidth - 2, graphH - 2); - leftBar->expose(*this, bb); - - // now the border - c = style->get_border_color(state); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(0.5, graphY - graphH + 0.5, bWidth - 1, graphH - 1); - cr->stroke(); - } - - // draw the bottom colored bar - if (bottomBar) { - // first the background - int bWidth = CBAR_WIDTH; - BackBuffer *bb = this; - bottomBar->setDrawRectangle(graphX + 1, graphY + CBAR_MARGIN + 1, graphW - 2, bWidth - 2); - bottomBar->expose(*this, bb); - - // now the border - c = style->get_border_color (state); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(graphX + 0.5, graphY + CBAR_MARGIN + 0.5, graphW - 1, bWidth - 1 ); - cr->stroke(); - } - // draw bullets if (curve.type != DCT_Parametric) { c = style->get_color (state); @@ -479,17 +487,17 @@ void MyDiagonalCurve::draw (int handle) } } - double x = double(graphX + 1) + double((graphW - 2) * curve.x.at(i)); // project (curve.x.at(i), 0, 1, graphW); - double y = double(graphY - 1) - double((graphH - 2) * curve.y.at(i)); // project (curve.y.at(i), 0, 1, graphH); + double x = graphX + graphW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); + double y = graphY - graphH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); - cr->arc (x, y, RADIUS + 0.5, 0, 2 * rtengine::RT_PI); + cr->arc (x, y, RADIUS * s + 0.5, 0, 2 * rtengine::RT_PI); cr->fill (); if (i == edited_point) { - cr->set_line_width(2.); - cr->arc (x, y, RADIUS + 3.5, 0, 2 * rtengine::RT_PI); + cr->set_line_width(2. * s); + cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI); cr->stroke(); - cr->set_line_width(1.); + cr->set_line_width(1. * s); } } @@ -519,13 +527,6 @@ bool MyDiagonalCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) return false; } -/*void MyDiagonalCurve::graphSizeRequest (Gtk::Requisition* req) { - req->width = getGraphMinSize(); - // The real height request should take care of the presence of the vertical - // scroll bar and its width - req->height = sized ? getGraphMinSize() : get_allocation().get_width(); -}*/ - bool MyDiagonalCurve::handleEvents (GdkEvent* event) { @@ -541,8 +542,10 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) return false; } - double minDistanceX = double(MIN_DISTANCE) / double(graphW - 1); - double minDistanceY = double(MIN_DISTANCE) / double(graphH - 1); + double s = RTScalable::getScale(); + + double minDistanceX = double(MIN_DISTANCE) / graphW * s; + double minDistanceY = double(MIN_DISTANCE) / graphH * s; switch (event->type) { case GDK_BUTTON_PRESS: @@ -1020,11 +1023,12 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi /* graphW and graphH are the size of the graph */ calcDimensions(); - if ((graphW < 0) || (graphH < 0)) { + if (graphW < 0. || graphH < 0.) { return; } - double minDistanceX = double(MIN_DISTANCE) / double(graphW - 1); + double s = (double)RTScalable::getScale(); + double minDistanceX = MIN_DISTANCE / graphW * s; if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS || curve.type == DCT_CatumullRom) { // get the pointer position @@ -1074,12 +1078,13 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi /* graphW and graphH are the size of the graph */ calcDimensions(); - double minDistanceX = double(MIN_DISTANCE) / double(graphW - 1); - - if ((graphW < 0) || (graphH < 0)) { + if (graphW < 0. || graphH < 0.) { return false; } + double s = (double)RTScalable::getScale(); + double minDistanceX = double(MIN_DISTANCE) * s / graphW; + snapToElmt = -100; if (curve.type != DCT_Parametric) { @@ -1150,13 +1155,13 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider) /* graphW and graphH are the size of the graph */ calcDimensions(); - double minDistanceX = double(MIN_DISTANCE) / double(graphW - 1); - //double minDistanceY = double(MIN_DISTANCE) / double(graphH-1); - - if ((graphW < 0) || (graphH < 0)) { + if (graphW < 0. || graphH < 0.) { return; } + double s = (double)RTScalable::getScale(); + double minDistanceX = double(MIN_DISTANCE) * s / graphW; + snapToElmt = -100; if (curve.type != DCT_Parametric) { @@ -1284,8 +1289,8 @@ void MyDiagonalCurve::getCursorPositionFromCurve(float x) clampedX = x; clampedY = point.getVal01(x); - cursorX = int(clampedX * float(graphW - 3)) + graphX + 1.5; - cursorY = graphY - int(clampedY * float(graphH - 3)); + cursorX = (int)(clampedX * graphW + graphX); + cursorY = (int)(graphY - clampedY * graphH); } // x = cursor position found in the event @@ -1294,17 +1299,17 @@ void MyDiagonalCurve::getCursorPositionFromCurve(int x) // the graph is refreshed only if a new point is created (snapped to a pixel) cursorX = x - graphX; - clampedX = (float(cursorX) - 1.5) / float(graphW - 3); + clampedX = (double)cursorX / graphW; clampedY = point.getVal01(clampedX); - cursorY = graphY - int(float(1. - clampedY) * float(graphH - 3)); + cursorY = (int)(graphY - (1. - clampedY) * graphH); } void MyDiagonalCurve::getCursorPosition(Gdk::EventType evType, bool isHint, int evX, int evY, Gdk::ModifierType modifierKey) { int tx, ty; int prevCursorX, prevCursorY; - double incrementX = 1. / double(graphW); - double incrementY = 1. / double(graphH); + double incrementX = 1. / graphW; + double incrementY = 1. / graphH; // getting the cursor position switch (evType) { diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 9b64ee516..ee7a2de5f 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -22,6 +22,7 @@ #include MyFlatCurve::MyFlatCurve () : + MyCurve(), clampedX(0.0), clampedY(0.0), deltaX(0.0), @@ -42,13 +43,8 @@ MyFlatCurve::MyFlatCurve () : draggingElement(false) { - graphW = get_allocation().get_width() - RADIUS * 2; - graphH = get_allocation().get_height() - RADIUS * 2; - prevGraphW = graphW; - prevGraphH = graphH; lit_point = -1; closest_point = 0; - buttonPressed = false; editedHandle = FCT_EditedHandle_None; area = FCT_Area_None; tanHandlesDisplayed = false; @@ -61,7 +57,7 @@ MyFlatCurve::MyFlatCurve () : signal_event().connect( sigc::mem_fun(*this, &MyFlatCurve::handleEvents) ); - // By default, we create a curve with 8 control points + // By default, we create a curve with 6 control points curve.type = FCT_MinMaxCPoints; defaultCurve(); @@ -119,8 +115,7 @@ void MyFlatCurve::interpolate () prevGraphW = graphW; prevGraphH = graphH; - int nbPoints = graphW - 2; - point(nbPoints); + point((unsigned int)graphW); get_LUT (point); upoint.reset (); lpoint.reset (); @@ -138,16 +133,18 @@ void MyFlatCurve::draw () return; } - // re-calculate curve if dimensions changed - int currPointSize = point.getUpperBound(); + double s = (double)RTScalable::getScale(); - if (curveIsDirty || /*prevGraphW != graphW || prevGraphH != graphH ||*/ (currPointSize == GRAPH_SIZE && (graphW - 3 > GRAPH_SIZE)) || (currPointSize > GRAPH_SIZE && (graphW - 2 <= GRAPH_SIZE || graphW - 3 != currPointSize))) { + // re-calculate curve if dimensions changed + int currLUTSize = point.getUpperBound(); + + if (curveIsDirty + || (currLUTSize == (GRAPH_SIZE * s) && (graphW > (GRAPH_SIZE * s))) + || (currLUTSize > (GRAPH_SIZE * s) && (graphW <= (GRAPH_SIZE * s) || graphW != currLUTSize)) ) + { interpolate (); } - double innerW = double(graphW - 2); - double innerH = double(graphH - 2); - Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL; Glib::RefPtr style = get_style_context(); @@ -164,59 +161,54 @@ void MyFlatCurve::draw () Gdk::RGBA c; - cr->set_line_width (1.0); - - // draw f(x)=0.5 line - c = style->get_border_color(state); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - std::valarray ds (1); - ds[0] = 4; - cr->set_dash (ds, 0); - cr->move_to (double(graphX) + 1.5, double(graphY - graphH / 2) - 0.5); - cr->rel_line_to (double(graphW - 3), 0.); - cr->stroke (); - - cr->unset_dash (); - - cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); // draw the left colored bar if (leftBar) { // first the background - int bWidth = CBAR_WIDTH; BackBuffer *bb = this; - leftBar->setDrawRectangle(1, graphY - graphH + 1, bWidth - 2, graphH - 2); + leftBar->setDrawRectangle(1. * s, graphY - graphH - 0.5, CBAR_WIDTH * s, graphH); leftBar->expose(*this, bb); // now the border c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(0.5, graphY - graphH + 0.5, bWidth - 1, graphH - 1); + cr->rectangle(0.5 * s, graphY - graphH - 0.5 - 0.5 * s, (CBAR_WIDTH + 1) * s, (double)graphH + 1. + 1. * s); cr->stroke(); } // draw the bottom colored bar if (bottomBar) { // first the background - int bWidth = CBAR_WIDTH; BackBuffer *bb = this; - bottomBar->setDrawRectangle(graphX + 1, graphY + CBAR_MARGIN + 1, graphW - 2, bWidth - 2); + bottomBar->setDrawRectangle(graphX - 0.5, graphY + (RADIUS + CBAR_MARGIN + 1.) * s, graphW + 1., CBAR_WIDTH * s); bottomBar->expose(*this, bb); // now the border c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(graphX + 0.5, graphY + CBAR_MARGIN + 0.5, graphW - 1, bWidth - 1 ); + cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + (RADIUS + CBAR_MARGIN + 0.5) * s, graphW + 1. + 0.5 * s, (CBAR_WIDTH + 1.) * s); cr->stroke(); } + // draw f(x)=0.5 line + c = style->get_border_color(state); + cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); + std::valarray ds (1); + ds[0] = 4 * s; + cr->set_dash (ds, 0); + cr->move_to (graphX - 1. * s, graphY - graphH / 2.); + cr->rel_line_to (graphW + 2 * s, 0.); + cr->stroke (); + + cr->unset_dash (); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0 * s); cr->set_line_cap(Cairo::LINE_CAP_BUTT); // draw the pipette values if (pipetteR > -1.f || pipetteG > -1.f || pipetteB > -1.f) { - cr->set_line_width (0.75); + cr->set_line_width (0.75 * s); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); int n = 0; @@ -235,34 +227,34 @@ void MyFlatCurve::draw () if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteR, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteR, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteG, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteG, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteB, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteB, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } } if (pipetteVal > -1.f) { - cr->set_line_width (2.); + cr->set_line_width (2. * s); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (double(graphX) + 1.5 + double(graphW - 3)*pipetteVal, double(graphY) - 1.5); - cr->rel_line_to (0, double(-graphH + 3)); + cr->move_to (graphX + graphW*pipetteVal, graphY + 1. * s); + cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); - cr->set_line_width (1.); + cr->set_line_width (1. * s); } } @@ -273,7 +265,7 @@ void MyFlatCurve::draw () for (int i = 0; i < (int)curve.x.size(); ++i) { if (curve.x.at(i) != -1.) { - int coloredLineWidth = min( max(75, graphW) / 75, 8 ); + double coloredLineWidth = rtengine::min( rtengine::max(75. * s, graphW) / (75. * s), 8. * s); cr->set_line_width (coloredLineWidth); colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_VERTICAL_BAR, colorCallerId, this); @@ -283,8 +275,8 @@ void MyFlatCurve::draw () cr->set_line_width (2 * coloredLineWidth); } - cr->move_to (double(graphX) + 1 + innerW * curve.x.at(i), double(graphY - 1)); - cr->rel_line_to (0., -innerH); + cr->move_to (graphX + graphW * curve.x.at(i), graphY + 0.5 + 0.5 * s ); + cr->rel_line_to (0., -graphH - 1. - s); cr->stroke (); cr->set_line_width (coloredLineWidth); @@ -310,39 +302,39 @@ void MyFlatCurve::draw () colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_HORIZONTAL_BAR, colorCallerId, this); cr->set_source_rgb (ccRed, ccGreen, ccBlue); - cr->move_to (double(graphX + 1) , double(graphY - 1) - innerH * curve.y.at(point)); - cr->rel_line_to (innerW, 0.); + cr->move_to (graphX - 0.5 - 0.5 * s , graphY - graphH * curve.y.at(point)); + cr->rel_line_to (graphW + 1. + s, 0.); cr->stroke (); } } } // endif - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); } else { cr->set_source_rgb (0.5, 0.0, 0.0); if (edited_point > -1 || ((lit_point > -1) && ((area & (FCT_Area_H | FCT_Area_V | FCT_Area_Point)) || editedHandle == FCT_EditedHandle_CPointUD)) ) { // draw the lit_point's vertical line if (edited_point > -1 || (editedHandle & (FCT_EditedHandle_CPointUD | FCT_EditedHandle_CPoint | FCT_EditedHandle_CPointY))) { - cr->set_line_width (2.0); + cr->set_line_width (2.0 * s); } int point = edited_point > -1 ? edited_point : lit_point; - cr->move_to (double(graphX) + 1 + innerW * curve.x.at(point), double(graphY - 1)); - cr->rel_line_to (0., -innerH); + cr->move_to (graphX + graphW * curve.x.at(point), graphY + 0.5 + 0.5 * s ); + cr->rel_line_to (0., -graphH - 1. - s); cr->stroke (); - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); // draw the lit_point's horizontal line if (editedHandle & (FCT_EditedHandle_CPointUD | FCT_EditedHandle_CPoint | FCT_EditedHandle_CPointY)) { - cr->set_line_width (2.0); + cr->set_line_width (2.0 * s); } - cr->move_to (double(graphX + 1) , double(graphY - 1) - innerH * curve.y.at(point)); - cr->rel_line_to (innerW, 0.); + cr->move_to (graphX - 0.5 - 0.5 * s , graphY - graphH * curve.y.at(point)); + cr->rel_line_to (graphW + 1. + s, 0.); cr->stroke (); - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); } } @@ -351,14 +343,14 @@ void MyFlatCurve::draw () // draw the graph's borders: c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(double(graphX) + 0.5, double(graphY) - 0.5, double(graphW - 1), double(-graphH + 1)); + cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s, graphW + 1. + 1. * s, -(graphH + 1. + 1. * s)); cr->stroke (); - double lineMinLength = 1. / graphW * SQUARE * 0.9; + double lineMinLength = 1. / graphW * (double)(SQUARE) * 0.9 * s; if (tanHandlesDisplayed && lit_point != -1 && getHandles(lit_point) && curve.x.at(lit_point) != -1.) { - double x = double(graphX + 1) + innerW * curve.x.at(lit_point); - double y = double(graphY) - innerH * curve.y.at(lit_point); + double x = graphX + graphW * curve.x.at(lit_point); + double y = graphY - graphH * curve.y.at(lit_point); double x2; double square; bool crossingTheFrame; @@ -377,7 +369,7 @@ void MyFlatCurve::draw () crossingTheFrame = true; } - x2 = double(graphX + 1) + innerW * leftTanX; + x2 = graphX + graphW * leftTanX; if (curve.x.at(lit_point) - leftTanX > lineMinLength || crossingTheFrame) { // The left tangential vector reappear on the right side @@ -385,9 +377,9 @@ void MyFlatCurve::draw () cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to (double(graphX + 1), y); + cr->line_to (graphX - 0.5 - 0.5 * s, y); cr->stroke (); - cr->move_to (double(graphX) + innerW, y); + cr->move_to (graphX + graphW + 0.5 + 0.5 * s, y); } cr->line_to (x2, y); @@ -395,7 +387,7 @@ void MyFlatCurve::draw () } // draw tangential knot - square = area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE; + square = (area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE) * s; cr->rectangle(x2 - square, y - square, 2.*square, 2.*square); cr->fill(); @@ -413,7 +405,7 @@ void MyFlatCurve::draw () crossingTheFrame = true; } - x2 = double(graphX + 1) + innerW * rightTanX; + x2 = graphX + graphW * rightTanX; if (rightTanX - curve.x.at(lit_point) > lineMinLength || crossingTheFrame) { // The left tangential vector reappear on the right side @@ -421,9 +413,9 @@ void MyFlatCurve::draw () cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to (double(graphX) + innerW, y); + cr->line_to (graphX + graphW + 0.5 + 0.5 * s, y); cr->stroke (); - cr->move_to (double(graphX + 1), y); + cr->move_to (graphX - 0.5 - 0.5 * s, y); } cr->line_to (x2, y); @@ -431,7 +423,7 @@ void MyFlatCurve::draw () } // draw tangential knot - square = area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE; + square = (area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE) * s; cr->rectangle(x2 - square, y - square, 2.*square, 2.*square); cr->fill(); } @@ -439,19 +431,15 @@ void MyFlatCurve::draw () // draw curve c = style->get_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - float graphH_ = float(graphH - 3); - float graphX_ = float(graphX) + 1.5; - float graphY_ = float(graphY) - 1.5; - cr->move_to (graphX_, getVal(point, 0) * -graphH_ + graphY_); + cr->move_to (graphX, getVal(point, 0) * -graphH + graphY); - for (int i = 1; i < graphW - 2; ++i) { - cr->line_to (float(i) + graphX_, getVal(point, i) * -graphH_ + graphY_); + for (int i = 1; i < graphW; ++i) { + cr->line_to ((double)i + graphX, (double)getVal(point, i) * -graphH + graphY); } cr->stroke (); // draw bullets - //if (curve.type!=FCT_Parametric) for (int i = 0; i < (int)curve.x.size(); ++i) { if (curve.x.at(i) != -1.) { if (i == edited_point) { @@ -471,18 +459,18 @@ void MyFlatCurve::draw () cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); } - double x = double(graphX + 1) + innerW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); - double y = double(graphY - 1) - innerH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); + double x = graphX + graphW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); + double y = graphY - graphH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); - cr->arc (x, y, (double)RADIUS, 0, 2 * rtengine::RT_PI); + cr->arc (x, y, RADIUS * s + 0.5, 0, 2 * rtengine::RT_PI); cr->fill (); if (i == edited_point) { cr->set_source_rgb (1.0, 0.0, 0.0); - cr->set_line_width(2.); - cr->arc (x, y, RADIUS + 3.5, 0, 2 * rtengine::RT_PI); + cr->set_line_width(2. * s); + cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI); cr->stroke(); - cr->set_line_width(1.); + cr->set_line_width(1. * s); } } @@ -499,20 +487,20 @@ void MyFlatCurve::draw () // yellow cr->set_source_rgb (1.0, 1.0, 0.0); - cr->rectangle(double(graphX + 1) + innerW * (leftTanHandle.centerX - halfSquareSizeX), - double(graphY - 1) - innerH * (leftTanHandle.centerY + halfSquareSizeY), - innerW * minDistanceX, - innerW * minDistanceY); + cr->rectangle(graphX + graphW * (leftTanHandle.centerX - halfSquareSizeX), + graphY - graphH * (leftTanHandle.centerY + halfSquareSizeY), + graphW * minDistanceX, + graphW * minDistanceY); cr->fill(); // RIGHT handle // blue cr->set_source_rgb (0.0, 0.0, 1.0); - cr->rectangle(double(graphX + 1) + innerW * (rightTanHandle.centerX - halfSquareSizeX), - double(graphY - 1) - innerH * (rightTanHandle.centerY + halfSquareSizeY), - innerW * minDistanceX, - innerW * minDistanceY); + cr->rectangle(graphX + graphW * (rightTanHandle.centerX - halfSquareSizeX), + graphY - graphH * (rightTanHandle.centerY + halfSquareSizeY), + graphW * minDistanceX, + graphW * minDistanceY); cr->fill(); } @@ -526,11 +514,13 @@ bool MyFlatCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) allocation.set_x(0); allocation.set_y(0); + int s = RTScalable::getScale(); + // setDrawRectangle will allocate the backbuffer Surface if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) { setDirty(true); - if (prevGraphW > GRAPH_SIZE || graphW > GRAPH_SIZE) { + if (prevGraphW > (GRAPH_SIZE * s) || graphW > (GRAPH_SIZE * s)) { curveIsDirty = true; } } @@ -608,8 +598,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) return false; } - minDistanceX = double(MIN_DISTANCE) / double(graphW - 1); - minDistanceY = double(MIN_DISTANCE) / double(graphH - 1); + double s = RTScalable::getScale(); + + minDistanceX = double(MIN_DISTANCE) / graphW * s; + minDistanceY = double(MIN_DISTANCE) / graphH * s; switch (event->type) { @@ -1310,11 +1302,13 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier // hide the tangent handles tanHandlesDisplayed = false; + int s = RTScalable::getScale(); + // Action on BUTTON_PRESS and no edited point switch (area) { case (FCT_Area_Insertion): { - rtengine::FlatCurve rtCurve(getPoints(), GRAPH_SIZE); + rtengine::FlatCurve rtCurve(getPoints(), true, GRAPH_SIZE * s); std::vector::iterator itx, ity, itlt, itrt; int num = (int)curve.x.size(); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c67d57fe6..6e5cc7c9d 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2331,11 +2331,11 @@ void Preferences::switchFontTo (const Glib::ustring &newFontFamily, const int ne try { //GTK318 -#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 - fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", newFontFamily, newFontSize)); -#else - fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize)); -#endif +//#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 +// fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", newFontFamily, newFontSize * RTScalable::getScale())); +//#else + fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize * RTScalable::getScale())); +//#endif //GTK318 } catch (Glib::Error &err) { printf ("Error: \"%s\"\n", err.what().c_str()); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index bf74ebce6..cc734456e 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -55,10 +55,38 @@ RTImage::RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileNam setImage (fileName, rtlFileName); } -RTImage::RTImage (Glib::RefPtr &pixbuf) +RTImage::RTImage (Glib::RefPtr &pbuf) +{ + if (surface) { + surface.clear(); + } + if (pbuf) { + set(pbuf); + this->pixbuf = pbuf; + } +} + +RTImage::RTImage (Cairo::RefPtr &surf) { if (pixbuf) { - set(pixbuf); + pixbuf.clear(); + } + if (surf) { + set(surf); + surface = surf; + } +} + +RTImage::RTImage (Glib::RefPtr &other) +{ + if (other) { + if (other->get_surface()) { + surface = other->get_surface(); + set(surface); + } else { + pixbuf = other->get_pixbuf(); + set(pixbuf); + } } } @@ -84,7 +112,6 @@ void RTImage::setDPInScale (const double newDPI, const int newScale) RTScalable::setDPInScale(newDPI, newScale); dpiBack = getDPI(); scaleBack = getScale(); - //printf("RTImage::setDPInScale : New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTImage\n", scaleBack, dpiBack, newDPI); updateImages(); } } @@ -95,13 +122,11 @@ void RTImage::changeImage (const Glib::ustring& imageName) if (pixbuf) { auto iterator = pixbufCache.find (imageName); - //printf("changeImage / pixbufCache[%d] : \"%s\" %s!\n", (int)(pixbufCache.size()), imageName.c_str(), iterator == pixbufCache.end () ? "not found" : "found"); assert(iterator != pixbufCache.end ()); pixbuf = iterator->second; set(iterator->second); } else { // if no Pixbuf is set, we update or create a Cairo::ImageSurface auto iterator = surfaceCache.find (imageName); - //printf("changeImage / surfaceCache[%d] : \"%s\" %s!\n", (int)(surfaceCache.size()), imageName.c_str(), iterator == surfaceCache.end () ? "not found" : "found"); if (iterator == surfaceCache.end ()) { auto surf = createImgSurfFromFile(imageName); iterator = surfaceCache.emplace (imageName, surf).first; @@ -111,6 +136,33 @@ void RTImage::changeImage (const Glib::ustring& imageName) } } +Cairo::RefPtr RTImage::get_surface() +{ + return surface; +} + +int RTImage::get_width() +{ + if (surface) { + return surface->get_width(); + } + if (pixbuf) { + return pixbuf->get_width(); + } + return -1; +} + +int RTImage::get_height() +{ + if (surface) { + return surface->get_height(); + } + if (pixbuf) { + return pixbuf->get_height(); + } + return -1; +} + void RTImage::init() { dpiBack = RTScalable::getDPI(); @@ -138,7 +190,6 @@ Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::u { Cairo::RefPtr surf; - //printf("Creating \"%s\"\n", fileName.c_str()); try { surf = loadImage(fileName, getTweakedDPI()); @@ -146,12 +197,10 @@ Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::u /* double x=0., y=0.; cairo_surface_get_device_scale(surf->cobj(), &x, &y); - //printf(" -> Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); if (getScale() == 2) { cairo_surface_set_device_scale(surf->cobj(), 0.5, 0.5); cairo_surface_get_device_scale(surf->cobj(), &x, &y); surf->flush(); - //printf(" Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); } */ } catch (const Glib::Exception& exception) { diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 54ab5b66d..481772ad6 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -39,12 +39,17 @@ public: RTImage (); RTImage (RTImage &other); RTImage (Glib::RefPtr &pixbuf); + RTImage (Cairo::RefPtr &surf); RTImage(Cairo::RefPtr other); RTImage (Glib::RefPtr &other); RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void changeImage (const Glib::ustring& imageName); + Cairo::RefPtr get_surface(); + int get_width(); + int get_height(); + static void init(); static void updateImages (); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index e8e7f46fa..d55ce30fd 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -24,11 +24,13 @@ SHCSelector::SHCSelector() : movingPosition(-1), tmpX(0.0), tmpPos(0.0), wslider(0.0), cl(nullptr), coloredBar(RTO_Left2Right) { + int s = RTScalable::getScale(); + positions[0] = defaults[0] = 0.25; positions[1] = defaults[1] = 0.5; positions[2] = defaults[2] = 0.75; - leftMargin = RADIUS; - rightMargin = RADIUS; + leftMargin = (RADIUS - 1.5) * s; + rightMargin = (RADIUS - 1.5) * s; Glib::RefPtr style = get_style_context(); style->add_class("drawingarea"); @@ -57,13 +59,14 @@ void SHCSelector::get_preferred_height_vfunc (int &minimum_height, int &natural_ void SHCSelector::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 100; - natural_width = 150; + int s = RTScalable::getScale(); + minimum_width = 100 * s; + natural_width = 150 * s; } void SHCSelector::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - natural_height = minimum_height = 14; + natural_height = minimum_height = 14 * RTScalable::getScale(); } void SHCSelector::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const @@ -135,8 +138,10 @@ void SHCSelector::updateBackBuffer() int w = get_width () - leftMargin - rightMargin; int h = get_height (); - wslider = std::max(int(h / 5), 10); - double hwslider = double(wslider) / 2.; + double s = RTScalable::getScale(); + + wslider = (double)std::max(h / 5, 10) * s; + double hwslider = wslider / 2.; // clear bg cr->set_source_rgba (0., 0., 0., 0.); @@ -146,22 +151,23 @@ void SHCSelector::updateBackBuffer() // set the box's colors - cr->set_line_width (1.0); + cr->set_line_width (1.0 * s); cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); cr->set_line_cap(Cairo::LINE_CAP_BUTT); + int coloredBarHeight = (int)((double)h * 5.5 / 7. + 0.5); if (is_sensitive() && coloredBar.canGetColors()) { // gradient background // this will eventually create/update the off-screen BackBuffer - coloredBar.setDrawRectangle(leftMargin + 1, 1, w - 2, int(float(h) * 5.5f / 7.f + 0.5f)); + coloredBar.setDrawRectangle(leftMargin + 1 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s); // that we're displaying here coloredBar.expose(*this, cr); } else { - style->render_background(cr, leftMargin + 1, 1, w - 2, int(float(h) * 5.5f / 7.f + 0.5f)); + style->render_background(cr, leftMargin + 1 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s); } // draw the box's borders - style->render_frame(cr, leftMargin + 1, 1, w - 2, int(float(h) * 5.5f / 7.f + 0.5f)); + style->render_frame(cr, leftMargin, 0, w, coloredBarHeight); // draw sliders @@ -169,82 +175,43 @@ void SHCSelector::updateBackBuffer() if (i == movingPosition) { style->set_state(Gtk::STATE_FLAG_ACTIVE); } - /* - else if (i==litCursor) - style->set_state(Gtk::STATE_FLAG_PRELIGHT); - */ else if (!is_sensitive()) { style->set_state(Gtk::STATE_FLAG_INSENSITIVE); } else { style->set_state(Gtk::STATE_FLAG_NORMAL); } - style->render_slider(cr, leftMargin + 0.5 + (w - 1)*positions[i] - hwslider, vb, wslider, h - vb, Gtk::ORIENTATION_VERTICAL); + style->render_slider(cr, (double)leftMargin + 1. * s + ((double)w - 2. * s) * positions[i] - (double)hwslider, (double)vb * s, wslider, (double)h - (double)vb * s, Gtk::ORIENTATION_VERTICAL); style->set_state(Gtk::STATE_FLAG_NORMAL); } - /* - for (int i=0; i<3; i++) { - double posX = leftMargin+0.5+(w-1)*positions[i]; - double arrowY = h-(h*3.5/7.-0.5)-vb; - double baseY = h-0.5-vb; - double centerY = (arrowY+baseY)/2.; - cr->move_to (posX, arrowY); - cr->line_to (posX+hwslider, centerY); - cr->line_to (posX+hwslider, baseY); - cr->line_to (posX-hwslider, baseY); - cr->line_to (posX-hwslider, centerY); - cr->close_path(); - if (i==movingPosition) { - // moved (selected) - Gdk::RGBA c = style->get_background_color(Gtk::STATE_FLAG_SELECTED); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (Gtk::STATE_FLAG_SELECTED); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - / * - else if (i==litCursor) { - // prelight - Gdk::RGBA c = style->get_background_color(Gtk::STATE_FLAG_PRELIGHT); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (Gtk::STATE_FLAG_PRELIGHT); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - * / - else { - // normal - Gdk::RGBA c = style->get_background_color(is_sensitive() ? Gtk::STATE_FLAG_ACTIVE : Gtk::STATE_FLAG_INSENSITIVE); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (is_sensitive() ? Gtk::STATE_FLAG_ACTIVE : Gtk::STATE_FLAG_INSENSITIVE); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - } - */ - // draw text for the slider that is being moved if (movingPosition >= 0) { int i = movingPosition; int offset; - int layout_width, layout_height; + int layout_width = 0, layout_height = 0; + + Glib::RefPtr context = get_pango_context () ; + Pango::FontDescription fontd(get_style_context()->get_font()); + + // update font + fontd.set_weight (Pango::WEIGHT_NORMAL); + fontd.set_absolute_size((double)h * 0.8 * (double)Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); layout->get_pixel_size(layout_width, layout_height); - offset = positions[i] > 0.5 ? -layout_width - 1 - hwslider : 1 + hwslider; + offset = positions[i] > 0.5 ? -layout_width - 1 * (int)s - hwslider : 1 * (int)s + hwslider; cr->set_source_rgb (0., 0., 0.); - cr->set_line_width(3.); + cr->set_line_width(3. * s); cr->set_line_join(Cairo::LINE_JOIN_ROUND); cr->set_line_cap(Cairo::LINE_CAP_ROUND); - cr->move_to (leftMargin + w * positions[i] + offset, 0.); + cr->move_to ((double)leftMargin + (double)w * positions[i] + (double)offset, 0.); layout->add_to_cairo_context (cr); cr->stroke_preserve(); - cr->set_line_width(0.5); + cr->set_line_width(0.5 * s); cr->set_source_rgb (1., 1., 1.); cr->fill (); } @@ -274,13 +241,18 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event) double w = double(get_width () - leftMargin - rightMargin); movingPosition = -1; - for (int i = 0; i < 3; i++) - if (event->x > double(leftMargin) + w * positions[i] - wslider / 2. && event->x < double(leftMargin) + w * positions[i] + wslider / 2) { + double s = RTScalable::getScale(); + + for (int i = 0; i < 3; i++) { + double currPos = double(leftMargin) + 1. * s + (w - 2. * s) * positions[i]; + double hwslider = wslider / 2.; + if (event->x >= currPos - hwslider && event->x <= currPos + hwslider) { movingPosition = i; tmpX = event->x; tmpPos = positions[i]; break; } + } queue_draw (); return true; @@ -315,23 +287,24 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) { if (movingPosition >= 0) { - int w = get_width (); - positions[movingPosition] = tmpPos + (event->x - tmpX) / w; + double s = RTScalable::getScale(); + double innerw = double(get_width () - leftMargin - rightMargin) - 2. * s; + positions[movingPosition] = tmpPos + (event->x - tmpX) / innerw; if (positions[movingPosition] < 0) { positions[movingPosition] = 0.0; } - if (movingPosition > 0 && positions[movingPosition] < positions[movingPosition - 1] + wslider / w) { - positions[movingPosition] = positions[movingPosition - 1] + wslider / w; + if (movingPosition > 0 && positions[movingPosition] < positions[movingPosition - 1] + wslider / innerw) { + positions[movingPosition] = positions[movingPosition - 1] + wslider / innerw; } if (positions[movingPosition] > 1.0) { positions[movingPosition] = 1.0; } - if (movingPosition < 2 && positions[movingPosition] > positions[movingPosition + 1] - wslider / w) { - positions[movingPosition] = positions[movingPosition + 1] - wslider / w; + if (movingPosition < 2 && positions[movingPosition] > positions[movingPosition + 1] - wslider / innerw) { + positions[movingPosition] = positions[movingPosition + 1] - wslider / innerw; } if (cl) { diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index 891095e6f..30c0fec4f 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -171,13 +171,21 @@ void ThresholdSelector::get_preferred_height_vfunc (int &minimum_height, int &na void ThresholdSelector::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 60; - natural_width = 150; + int s = RTScalable::getScale(); + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + int margins = padding.get_left() + padding.get_right(); + minimum_width = 60 * s + margins; + natural_width = 150 * s + margins; } void ThresholdSelector::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - natural_height = minimum_height = 23; + int s = RTScalable::getScale(); + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + int margins = padding.get_left() + padding.get_right(); + natural_height = minimum_height = 26 * s + margins; } void ThresholdSelector::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const @@ -251,8 +259,12 @@ void ThresholdSelector::on_realize() void ThresholdSelector::updateBackBuffer() { + if (!get_realized() || !isDirty() || !get_allocated_width() || !get_allocated_height()) { + return; + } + // This will create or update the size of the BackBuffer::surface - setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, get_width(), get_height(), true); + setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, get_allocated_width(), get_allocated_height(), true); if (!surface) { return; @@ -260,52 +272,55 @@ void ThresholdSelector::updateBackBuffer() Cairo::RefPtr cr = Cairo::Context::create(surface); Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled cr->set_source_rgba (0., 0., 0., 0.); cr->set_operator (Cairo::OPERATOR_CLEAR); cr->paint (); cr->set_operator (Cairo::OPERATOR_OVER); - double positions01[4]; - int w = get_width (); - int h = get_height (); + double s = (double)RTScalable::getScale(); - int wslider = 10; - int hwslider = wslider / 2; - int iw = w - wslider - 2 * hb; // inner width (excluding padding for sliders) + double positions01[4]; + int w = get_allocated_width (); + int h = get_allocated_height (); + + + double wslider = sliderWidth * s; // constant must be an odd value + double hwslider = wslider / 2.; + double verticalSliderPadding = std::floor(((double)h - (double)padding.get_top() - (double)padding.get_bottom()) * verticalSliderPaddingFactor + 0.5); positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT); positions01[TS_TOPLEFT] = to01(TS_TOPLEFT); positions01[TS_BOTTOMRIGHT] = to01(TS_BOTTOMRIGHT); positions01[TS_TOPRIGHT] = to01(TS_TOPRIGHT); - // set the box's colors - cr->set_line_width (1.0); - cr->set_line_cap(Cairo::LINE_CAP_BUTT); - + double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; + double innerBarY = verticalSliderPadding + 1. * s + (double)padding.get_top(); + double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; + double innerBarH = (double)h - innerBarY - verticalSliderPadding - 1. * s - (double)padding.get_bottom(); if (is_sensitive() && coloredBar.canGetColors()) { if (updatePolicy == RTUP_DYNAMIC) { coloredBar.setDirty(true); } // this will eventually create/update the off-screen Surface for the gradient area only ! - coloredBar.setDrawRectangle(hb + hwslider, int(float(h) * 1.5f / 7.f + 0.5f), iw + 1, int(float(h) * 4.f / 7.f + 0.5f)); + coloredBar.setDrawRectangle(innerBarX, innerBarY, innerBarW, innerBarH); // that we're displaying here coloredBar.expose(*this, cr); } else { - style->render_background(cr, hb + hwslider, int(float(h) * 1.5f / 7.f + 0.5f), iw + 1, int(float(h) * 4.f / 7.f + 0.5f)); + style->render_background(cr, innerBarX, innerBarY, innerBarW, innerBarH); } - // draw the box's borders - style->render_frame(cr, hb + hwslider - 0.5, double(int(float(h) * 1.5f / 7.f)) + 0.5, iw + 1, double(int(float(h) * 4.f / 7.f))); - - cr->set_line_width (1.); - cr->set_antialias(Cairo::ANTIALIAS_NONE); - // draw curve + double yStart = innerBarY + innerBarH - 1. * s; + double yEnd = innerBarY + 1. * s; + double xStart = innerBarX; + double xEnd = innerBarX + innerBarW; + double iw = xEnd - xStart; + double ih = yEnd - yStart; + if (bgCurveProvider) { - double yStart = double(int(float(h) * 5.5f / 7.f)) - 0.5; - double yEnd = double(int(float(h) * 1.5f / 7.f)) + 1.5; std::vector pts = bgCurveProvider->getCurvePoints(this); // the values sent by the provider are not checked (assumed to be correct) @@ -315,29 +330,30 @@ void ThresholdSelector::updateBackBuffer() ++i; double y = *i; ++i; - cr->move_to (hb + hwslider + iw * x + 0.5, (yEnd - yStart)*y + yStart); + cr->move_to (xStart, ih*y + yStart); for (; i < pts.end(); ) { x = *i; ++i; y = *i; ++i; - cr->line_to (hb + hwslider + iw * x + 0.5, (yEnd - yStart)*y + yStart); + cr->line_to (xStart + iw * x, ih*y + yStart); } } else { // Draw a straight line because not enough points has been sent - double yStart = double(int(float(h) * 5.5f / 7.f)) - 0.5; - cr->move_to (hb + hwslider + 0.5, yStart); - cr->line_to (hb + hwslider + iw + 0.5, yStart); + cr->move_to (xStart, yEnd); + cr->rel_line_to (iw, 0.); } } else { if (!separatedSliders) { - double yStart = initalEq1 ? double(int(float(h) * 1.5f / 7.f)) + 1.5 : double(int(float(h) * 5.5f / 7.f)) - 0.5; - double yEnd = initalEq1 ? double(int(float(h) * 5.5f / 7.f)) - 0.5 : double(int(float(h) * 1.5f / 7.f)) + 1.5; ThreshCursorId p[4]; + double yStart_ = yStart; + double yEnd_ = yEnd; if (initalEq1) { + std::swap(yStart_, yEnd_); + p[0] = TS_TOPLEFT; p[1] = TS_BOTTOMLEFT; p[2] = TS_BOTTOMRIGHT; @@ -350,54 +366,60 @@ void ThresholdSelector::updateBackBuffer() } if (positions[p[1]] > minValTop) { // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same - cr->move_to (hb + hwslider, yStart); + cr->move_to (innerBarX, yStart_); } else { - cr->move_to (hb + hwslider, yEnd); + cr->move_to (innerBarX, yEnd_); } if (positions[p[0]] > minValTop) { - cr->line_to (hb + hwslider + iw * positions01[p[0]] + 0.5, yStart); + cr->line_to (xStart + iw * positions01[p[0]], yStart_); } if (positions[p[1]] > minValTop) { - cr->line_to (hb + hwslider + iw * positions01[p[1]] + 0.5, yEnd); + cr->line_to (xStart + iw * positions01[p[1]], yEnd_); } - cr->line_to (hb + hwslider + iw * positions01[p[2]] + 0.5, yEnd); + cr->line_to (xStart + iw * positions01[p[2]], yEnd_); if (doubleThresh && positions[p[2]] < maxValTop) { - cr->line_to (hb + hwslider + iw * positions01[p[3]] + 0.5, yStart); + cr->line_to (xStart + iw * positions01[p[3]], yStart_); if (positions[p[3]] < maxValTop) { - cr->line_to (hb + hwslider + iw + 0.5, yStart); + cr->line_to (xEnd, yStart_); } } } } cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + cr->set_line_join(Cairo::LINE_JOIN_BEVEL); - if (is_sensitive() && coloredBar.canGetColors()) { - // draw surrounding curve + if (is_sensitive()) { + // draw surrounding curve (black) cr->set_source_rgb (0., 0., 0.); - cr->set_line_width (5.0); + cr->set_line_width (4. * s); cr->stroke_preserve(); } - // draw curve + // draw inner curve (white) if (is_sensitive()) { cr->set_source_rgb (1., 1., 1.); } else { cr->set_source_rgba (0., 0., 0., 0.5); } - - cr->set_line_width (1.5); + cr->set_line_width (2. * s); cr->stroke (); + // draw the box's borders + style->render_frame(cr, innerBarX - 1. * s, innerBarY - 1. * s, innerBarW + 2. * s, innerBarH + 2. * s); + // draw sliders - //if (!(litCursor == TS_UNDEFINED && movedCursor == TS_UNDEFINED)) { Gtk::StateFlags currState = style->get_state(); + cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_cap(Cairo::LINE_CAP_ROUND); + for (int i = 0; i < (doubleThresh ? 4 : 2); ++i) { if (!is_sensitive()) { style->set_state(Gtk::STATE_FLAG_INSENSITIVE); @@ -409,68 +431,21 @@ void ThresholdSelector::updateBackBuffer() style->set_state(Gtk::STATE_FLAG_NORMAL); } - double posX = hb + iw * positions01[i] + 0.5; - double arrowY = i == 0 || i == 2 ? h - (h * 3. / 7. - 0.5) - vb : h * 3. / 7. - 0.5 + vb; - double baseY = i == 0 || i == 2 ? h - 0.5 - vb : 0.5 + vb; + double posX = xStart + iw * positions01[i]; + double arrowY = i == 0 || i == 2 ? yStart - 3. * s : yEnd + 3. * s; + double baseY = i == 0 || i == 2 ? (double)h - (double)padding.get_bottom() - 0.5 * s : (double)padding.get_top() + 0.5 * s; - style->render_slider(cr, posX, i == 0 || i == 2 ? arrowY : baseY, wslider, i == 0 || i == 2 ? baseY - arrowY : arrowY - baseY, Gtk::ORIENTATION_HORIZONTAL); + style->render_slider(cr, posX - hwslider, i == 0 || i == 2 ? arrowY : baseY, wslider, i == 0 || i == 2 ? baseY - arrowY : arrowY - baseY, Gtk::ORIENTATION_HORIZONTAL); } style->set_state(currState); - - /* - * - Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL; - - cr->set_line_width (1.); - for (int i=0; i<(doubleThresh?4:2); i++) { - double posX = hb+hwslider+iw*positions01[i]+0.5; - double arrowY = i==0 || i==2 ? h-(h*2.5/7.-0.5)-vb : h*2.5/7.-0.5+vb; - double baseY = i==0 || i==2 ? h-0.5-vb : 0.5+vb; - double centerY = (arrowY+baseY)/2.; - cr->move_to (posX, arrowY); - cr->line_to (posX+hwslider, centerY); - cr->line_to (posX+hwslider, baseY); - cr->line_to (posX-hwslider, baseY); - cr->line_to (posX-hwslider, centerY); - cr->close_path(); - if (i==movedCursor) { - // moved (selected) - c = style->get_background_color(Gtk::STATE_FLAG_SELECTED); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (Gtk::STATE_FLAG_SELECTED); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - else if (i==secondaryMovedCursor || (movedCursor==TS_UNDEFINED && i==litCursor)) { - // prelight - c = style->get_background_color(Gtk::STATE_FLAG_PRELIGHT); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (Gtk::STATE_FLAG_PRELIGHT); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - else { - // normal - c = style->get_background_color(is_sensitive() ? Gtk::STATE_FLAG_ACTIVE : Gtk::STATE_FLAG_INSENSITIVE); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill_preserve (); - c = style->get_border_color (is_sensitive() ? Gtk::STATE_FLAG_ACTIVE : Gtk::STATE_FLAG_INSENSITIVE); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->stroke (); - } - } - */ - //} } bool ThresholdSelector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { // on_realize & updateBackBuffer have to be called before - if (get_realized() && get_width() && get_height()) { + if (get_realized() && get_allocated_width() && get_allocated_height()) { if (isDirty()) { updateBackBuffer(); } @@ -525,7 +500,20 @@ bool ThresholdSelector::on_leave_notify_event (GdkEventCrossing* event) bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) { - int w = get_width (); + int w = get_allocated_width (); + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + + double s = (double)RTScalable::getScale(); + double wslider = sliderWidth * s; // constant must be an odd value + double hwslider = wslider / 2.; + + double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; + double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; + + double xStart = innerBarX + 0.5 * s; + double xEnd = innerBarX + innerBarW - 0.5 * s; + double iw = xEnd - xStart; findLitCursor(event->x, event->y); @@ -544,7 +532,7 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) dRange = maxValTop - minValTop; } - double dX = ( (event->x - tmpX) * dRange ) / ( w - 2 * hb ); + double dX = ( (event->x - tmpX) * dRange ) / iw; // slow motion if CTRL is pressed if (event->state & Gdk::CONTROL_MASK) { @@ -581,9 +569,9 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) // update the tooltip updateTooltip(); - sig_val_changed.emit(); - queue_draw (); + + sig_val_changed.emit(); } else { if (litCursor != oldLitCursor) { queue_draw (); @@ -598,18 +586,27 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) void ThresholdSelector::findLitCursor(int posX, int posY) { - int w = get_width (); - int h = get_height (); + int w = get_allocated_width (); + int h = get_allocated_height (); + Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); // already scaled + + double s = (double)RTScalable::getScale(); + double wslider = sliderWidth * s; // constant must be an odd value + double hwslider = wslider / 2.; + + double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; + double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; litCursor = TS_UNDEFINED; if (posY >= 0 && posY <= h / 2) { - if (posX > 0 && posX < w) { + if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) { litCursor = TS_TOPLEFT; if (doubleThresh) { // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same - double cursorX = (posX - hb) * (maxValTop - minValTop) / (w - 2 * hb) + minValTop; + double cursorX = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; if (cursorX > positions[TS_TOPRIGHT] || std::fabs(cursorX - positions[TS_TOPRIGHT]) < std::fabs(cursorX - positions[TS_TOPLEFT])) { litCursor = TS_TOPRIGHT; @@ -617,12 +614,12 @@ void ThresholdSelector::findLitCursor(int posX, int posY) } } } else if (posY > h / 2 && posY < h) { - if (posX > 0 && posX < w) { + if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) { litCursor = TS_BOTTOMLEFT; if (doubleThresh) { // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same - double cursorX = (posX - hb) * (maxValTop - minValTop) / (w - 2 * hb) + minValTop; + double cursorX = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; if (cursorX > positions[TS_BOTTOMRIGHT] || std::fabs(cursorX - positions[TS_BOTTOMRIGHT]) < std::fabs(cursorX - positions[TS_BOTTOMLEFT])) { litCursor = TS_BOTTOMRIGHT; diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h index 0b0f46d5f..fff707959 100644 --- a/rtgui/thresholdselector.h +++ b/rtgui/thresholdselector.h @@ -100,8 +100,8 @@ protected: double positions[4]; eUpdatePolicy updatePolicy; - const static int hb = 3; // horizontal border - const static int vb = 0; // vertical border + constexpr static double sliderWidth = 11.; // constant must be an odd value + constexpr static double verticalSliderPaddingFactor = 1.5 / 7.; void initValues (); void findLitCursor(int posX, int posY); diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 87105e2a5..0f3113065 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -700,7 +700,6 @@ void ThumbBrowserBase::enableInspector() bool ThumbBrowserBase::Internal::on_configure_event(GdkEventConfigure *configure_event) { - double resolution = get_window()->get_screen()->get_resolution(); return true; }