Add hidpi support for threshold selector and curves

This commit is contained in:
Pandagrapher 2022-12-25 15:35:25 +01:00
parent 3c348599dc
commit c48531448e
15 changed files with 302 additions and 566 deletions

View File

@ -23,77 +23,20 @@
ColoredBar::ColoredBar (eRTOrientation orient)
{
orientation = orient;
dirty = true;
this->x = this->y = this->w = this->h = 0;
}
bool ColoredBar::setDrawRectangle(int newX, int newY, int newW, int newH, bool updateBackBufferSize)
void ColoredBar::setColoredBarSize(const int newX, const int newY, const int newW, const int newH)
{
return BackBuffer::setDrawRectangle(Cairo::FORMAT_ARGB32, newX, newY, newW, newH, updateBackBufferSize);
this->x = newX;
this->y = newY;
this->w = newW;
this->h = newH;
}
/*
* Redraw the bar to a Cairo::ImageSurface
*/
void ColoredBar::expose(Gtk::DrawingArea &drawingArea, Cairo::RefPtr<Cairo::ImageSurface> destSurface)
void ColoredBar::updateColoredBar(const Cairo::RefPtr< Cairo::Context> &cr)
{
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !destSurface) {
return;
}
updateBackBuffer(drawingArea);
Gdk::Rectangle rect(x, y, w, h);
copySurface(destSurface, &rect);
}
/*
* Redraw the bar to a Gdk::Window
*/
void ColoredBar::expose(Gtk::DrawingArea &drawingArea, Glib::RefPtr<Gdk::Window> destWindow)
{
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !destWindow) {
return;
}
updateBackBuffer(drawingArea);
Gdk::Rectangle rect(x, y, w, h);
copySurface(destWindow, &rect);
}
void ColoredBar::expose(Gtk::DrawingArea &drawingArea, const Cairo::RefPtr< Cairo::Context> &cr)
{
// look out if the Surface has to be redrawn
if (!surfaceCreated()) {
return;
}
updateBackBuffer(drawingArea);
Gdk::Rectangle rect(x, y, w, h);
copySurface(cr, &rect);
}
/*
* Redraw the bar to a Gdk::Window
*/
void ColoredBar::expose(Gtk::DrawingArea &drawingArea, BackBuffer *backBuffer)
{
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !backBuffer) {
return;
}
updateBackBuffer(drawingArea);
Gdk::Rectangle rect(x, y, w, h);
copySurface(backBuffer, &rect);
}
void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea)
{
if (isDirty()) {
Cairo::RefPtr<Cairo::Context> cr = getContext();
if (w > 0 && h > 0) {
// the bar has to be drawn to the Surface first
if (!bgGradient.empty()) {
// a gradient has been set, we use it
@ -104,20 +47,20 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea)
switch (orientation) {
case (RTO_Left2Right):
bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.);
bggradient = Cairo::LinearGradient::create (0., 0., static_cast<double>(w), 0.);
break;
case (RTO_Right2Left):
bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.);
bggradient = Cairo::LinearGradient::create (static_cast<double>(w), 0., 0., 0.);
break;
case (RTO_Bottom2Top):
bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.);
bggradient = Cairo::LinearGradient::create (0., static_cast<double>(h), 0., 0.);
break;
case (RTO_Top2Bottom):
default:
bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h));
bggradient = Cairo::LinearGradient::create (0., 0., 0., static_cast<double>(h));
break;
}
@ -126,13 +69,13 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea)
}
cr->set_source (bggradient);
cr->rectangle(0, 0, w, h);
cr->rectangle(static_cast<double>(x), static_cast<double>(y), static_cast<double>(w), static_cast<double>(h));
cr->fill();
} else {
// ask the ColorProvider to provide colors :) for each pixels
if (colorProvider) {
surface->flush();
// Create surface
const auto surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w, h);
unsigned char *surfaceData = surface->get_data();
cr->set_antialias(Cairo::ANTIALIAS_NONE);
@ -205,25 +148,22 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea)
break;
}
surface->mark_dirty();
cr->set_source(surface, 0., 0.);
cr->rectangle(static_cast<double>(x), static_cast<double>(y), static_cast<double>(w), static_cast<double>(h));
cr->fill();
}
}
// has it been updated or not, we assume that the Surface has been correctly set (we don't handle allocation error)
setDirty(false);
}
}
void ColoredBar::setBgGradient (const std::vector<GradientMilestone> &milestones)
{
bgGradient = milestones;
setDirty(true);
}
void ColoredBar::clearBgGradient ()
{
bgGradient.clear();
setDirty(true);
}
bool ColoredBar::canGetColors()

View File

@ -30,11 +30,15 @@
* the bar itself, i.e. use render_background (depending on its Gtk::StyleContext)
*
*/
class ColoredBar final : private BackBuffer, public ColorCaller
class ColoredBar final : public ColorCaller
{
private:
void updateBackBuffer(Gtk::DrawingArea &drawingArea);
// ColoredBar position and size parameters
int x;
int y;
int w;
int h;
protected:
eRTOrientation orientation;
@ -42,12 +46,9 @@ protected:
public:
explicit ColoredBar (eRTOrientation orient);
bool setDrawRectangle(int newX, int newY, int newW, int newH, bool updateBackBufferSize = true);
void setColoredBarSize(const int newX, const int newY, const int newW, const int newH); // Note: updateColoredBar shall be called after to update the bar
void expose(Gtk::DrawingArea &drawingArea, Glib::RefPtr<Gdk::Window> destWindow);
void expose(Gtk::DrawingArea &drawingArea, Cairo::RefPtr<Cairo::ImageSurface> destSurface);
void expose(Gtk::DrawingArea &drawingArea, BackBuffer *backBuffer);
void expose(Gtk::DrawingArea &drawingArea, const Cairo::RefPtr< Cairo::Context> &cr);
void updateColoredBar(const Cairo::RefPtr< Cairo::Context> &cr);
bool canGetColors();
@ -56,8 +57,4 @@ public:
// by clearing the gradient, the ColorProvider will have to provide colors on a per pixel basis if a ColorProvider
// has been set, through ColorProvider::colorForValue on next ColoredBar::expose
void clearBgGradient ();
void setDirty(bool isDirty) {
BackBuffer::setDirty(isDirty);
}
};

View File

@ -442,7 +442,7 @@ void CurveEditorSubGroup::initButton (Gtk::Button &button, const Glib::ustring &
vAlign = options.curvebboxpos == 0 || options.curvebboxpos == 2 ? Gtk::ALIGN_FILL : Gtk::ALIGN_END;
}
button.add (*Gtk::manage (new RTImage(iconName, Gtk::ICON_SIZE_BUTTON)));
button.add (*Gtk::manage (new RTImage(iconName, Gtk::ICON_SIZE_LARGE_TOOLBAR)));
button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT);
if (!tooltip.empty()) {
button.set_tooltip_text(M(tooltip));

View File

@ -33,7 +33,6 @@
#include "rtimage.h"
#include "options.h"
#include "popuptogglebutton.h"
#include "rtscalable.h"
#include "../rtengine/curves.h"
@ -429,7 +428,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff ()
prevState = editCustomConn.block(true);
editCustom->set_active(false);
customCurve->pipetteMouseOver(nullptr, nullptr, 0);
customCurve->setDirty(true);
if (!prevState) {
editCustomConn.block(false);
@ -438,7 +436,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff ()
prevState = editNURBSConn.block(true);
editNURBS->set_active(false);
NURBSCurve->pipetteMouseOver(nullptr, nullptr, 0);
NURBSCurve->setDirty(true);
if (!prevState) {
editNURBSConn.block(false);
@ -447,7 +444,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff ()
prevState = editParamConn.block(true);
editParam->set_active(false);
paramCurve->pipetteMouseOver(nullptr, nullptr, 0);
paramCurve->setDirty(true);
if (!prevState) {
editParamConn.block(false);
@ -462,12 +458,10 @@ void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, i
case (DCT_Spline):
case (DCT_CatumullRom):
customCurve->pipetteMouseOver(curveEditor, provider, modifierKey);
customCurve->setDirty(true);
break;
case (DCT_Parametric): {
paramCurve->pipetteMouseOver(curveEditor, provider, modifierKey);
paramCurve->setDirty(true);
float pipetteVal = 0.f;
editedAdjuster = nullptr;
int n = 0;
@ -518,7 +512,6 @@ void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, i
case (DCT_NURBS):
NURBSCurve->pipetteMouseOver(curveEditor, provider, modifierKey);
NURBSCurve->setDirty(true);
break;
default: // (DCT_Linear, DCT_Unchanged)
@ -765,8 +758,8 @@ void DiagonalCurveEditorSubGroup::switchGUI()
shcSelector->coloredBar.setColorProvider(barColorProvider, dCurve->getBottomBarCallerId());
shcSelector->coloredBar.setBgGradient(bgGradient);
shcSelector->setMargins(
(int)( RTScalable::scalePixelSize((leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5) ),
(int)( RTScalable::scalePixelSize(RADIUS - 1.5) )
(int)( (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5 ),
(int)( RADIUS - 1.5 )
);
paramCurve->setColoredBar(leftBar, nullptr);
paramCurve->queue_resize_no_redraw();
@ -895,11 +888,9 @@ void DiagonalCurveEditorSubGroup::loadPressed ()
if (p[0] == (double)(DCT_Spline) || p[0] == (double)(DCT_CatumullRom)) {
customCurve->setPoints (p);
customCurve->queue_draw ();
customCurve->notifyListener ();
} else if (p[0] == (double)(DCT_NURBS)) {
NURBSCurve->setPoints (p);
NURBSCurve->queue_draw ();
NURBSCurve->notifyListener ();
} else if (p[0] == (double)(DCT_Parametric)) {
shcSelector->setPositions ( p[1], p[2], p[3] );
@ -908,7 +899,6 @@ void DiagonalCurveEditorSubGroup::loadPressed ()
darks->setValue (p[6]);
shadows->setValue (p[7]);
paramCurve->setPoints (p);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
}
}
@ -966,7 +956,6 @@ void DiagonalCurveEditorSubGroup::pastePressed ()
case DCT_Spline: // custom
case DCT_CatumullRom:
customCurve->setPoints (curve);
customCurve->queue_draw ();
customCurve->notifyListener ();
break;
@ -981,13 +970,11 @@ void DiagonalCurveEditorSubGroup::pastePressed ()
darks->setValue (curve[6]);
shadows->setValue (curve[7]);
paramCurve->setPoints (curve);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
break;
case DCT_NURBS: // NURBS
NURBSCurve->setPoints (curve);
NURBSCurve->queue_draw ();
NURBSCurve->notifyListener ();
break;

View File

@ -206,7 +206,6 @@ void FlatCurveEditorSubGroup::editModeSwitchedOff ()
bool prevState = editCPointsConn.block(true);
editCPoints->set_active(false);
CPointsCurve->pipetteMouseOver(nullptr, nullptr, 0);
CPointsCurve->setDirty(true);
if (!prevState) {
editCPointsConn.block(false);
@ -220,7 +219,6 @@ void FlatCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, int m
switch((FlatCurveType)(curveEditor->curveType->getSelected())) {
case (FCT_MinMaxCPoints):
CPointsCurve->pipetteMouseOver(curveEditor, provider, modifierKey);
CPointsCurve->setDirty(true);
break;
default: // (DCT_Linear, DCT_Unchanged)
@ -238,7 +236,6 @@ bool FlatCurveEditorSubGroup::pipetteButton1Pressed(EditDataProvider *provider,
switch((FlatCurveType)(curveEditor->curveType->getSelected())) {
case (FCT_MinMaxCPoints):
isDragging = CPointsCurve->pipetteButton1Pressed(provider, modifierKey);
CPointsCurve->setDirty(true);
break;
default: // (DCT_Linear, DCT_Unchanged)
@ -256,7 +253,6 @@ void FlatCurveEditorSubGroup::pipetteButton1Released(EditDataProvider *provider)
switch((FlatCurveType)(curveEditor->curveType->getSelected())) {
case (FCT_MinMaxCPoints):
CPointsCurve->pipetteButton1Released(provider);
CPointsCurve->setDirty(true);
break;
default: // (DCT_Linear, DCT_Unchanged)
@ -272,7 +268,6 @@ void FlatCurveEditorSubGroup::pipetteDrag(EditDataProvider *provider, int modifi
switch((FlatCurveType)(curveEditor->curveType->getSelected())) {
case (FCT_MinMaxCPoints):
CPointsCurve->pipetteDrag(provider, modifierKey);
CPointsCurve->setDirty(true);
break;
default: // (DCT_Linear, DCT_Unchanged)
@ -441,7 +436,6 @@ void FlatCurveEditorSubGroup::loadPressed ()
if (p[0] == (double)(FCT_MinMaxCPoints)) {
CPointsCurve->setPoints (p);
CPointsCurve->queue_draw ();
CPointsCurve->notifyListener ();
}
}
@ -481,7 +475,6 @@ void FlatCurveEditorSubGroup::pastePressed ()
switch (type) {
case FCT_MinMaxCPoints: // min/max control points
CPointsCurve->setPoints (curve);
CPointsCurve->queue_draw ();
CPointsCurve->notifyListener ();
break;

View File

@ -41,7 +41,7 @@ MyCurve::MyCurve () :
snapToValX(0.0),
snapToValY(0.0)
{
int pointDiameter = RTScalable::scalePixelSize((int)(RADIUS * 2.));
int pointDiameter = (int)(RADIUS * 2.);
graphW = get_allocation().get_width() - pointDiameter;
graphH = get_allocation().get_height() - pointDiameter;
prevGraphW = graphW;
@ -76,13 +76,12 @@ MyCurve::~MyCurve ()
void MyCurve::calcDimensions ()
{
double newRequestedW, newRequestedH;
const double s = RTScalable::scalePixelSize(1.);
newRequestedW = newRequestedH = get_allocation().get_width();
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;
graphX = (double)RADIUS + (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN : 0.);
graphH = graphW = newRequestedW - graphX - (double)RADIUS;
graphY = (double)RADIUS + graphW;
return;
}
@ -109,11 +108,11 @@ void MyCurve::get_preferred_height_for_width_vfunc (int width, int &minimum_heig
minimum_height = width;
if (leftBar && !bottomBar) {
minimum_height -= RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN);
minimum_height -= CBAR_WIDTH + 2 + CBAR_MARGIN;
}
if (!leftBar && bottomBar) {
minimum_height += RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN);
minimum_height += CBAR_WIDTH + 2 + CBAR_MARGIN;
}
natural_height = minimum_height;
@ -185,22 +184,11 @@ float MyCurve::getVal(LUTf &curve, int x)
void MyCurve::on_style_updated ()
{
setDirty(true);
queue_draw ();
}
void MyCurve::refresh()
{
if (leftBar != nullptr) {
leftBar->setDirty(true);
}
if (bottomBar != nullptr) {
bottomBar->setDirty(true);
}
setDirty(true);
Glib::RefPtr<Gdk::Window> win = get_window();
if (win) {

View File

@ -57,7 +57,7 @@ class MyCurveIdleHelper;
class CurveEditor;
class EditDataProvider;
class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable
class MyCurve : public Gtk::DrawingArea, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable
{
friend class MyCurveIdleHelper;
@ -150,6 +150,6 @@ public:
void clearPixmap ()
{
myCurve->setDirty(true);
myCurve->queue_draw();
}
};

View File

@ -23,7 +23,6 @@
#include "mydiagonalcurve.h"
#include "editcallbacks.h"
#include "rtscalable.h"
#include "../rtengine/curves.h"
@ -150,8 +149,7 @@ void MyDiagonalCurve::updateLocallabBackground(double ref)
return false;
}
mcih->clearPixmap();
mcih->myCurve->queue_draw();
mcih->clearPixmap();
--mcih->pending;
@ -250,24 +248,18 @@ void MyDiagonalCurve::interpolate ()
curveIsDirty = false;
}
void MyDiagonalCurve::draw (int handle)
void MyDiagonalCurve::updateDrawingArea (const int handle, const ::Cairo::RefPtr< Cairo::Context> &cr)
{
if (!isDirty()) {
if (!get_realized()) {
return;
}
if (!surfaceCreated()) {
return;
}
const double s = RTScalable::scalePixelSize(1.);
// 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)) )
|| (currLUTSize == GRAPH_SIZE && (graphW > GRAPH_SIZE))
|| (currLUTSize > GRAPH_SIZE && (graphW <= GRAPH_SIZE || graphW != currLUTSize)) )
{
interpolate ();
}
@ -277,20 +269,17 @@ void MyDiagonalCurve::draw (int handle)
Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL;
Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
Cairo::RefPtr<Cairo::Context> cr = getContext();
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
// clear background
cr->set_source_rgba (0., 0., 0., 0.);
cr->set_operator (Cairo::OPERATOR_CLEAR);
cr->paint ();
// Setup drawing
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
cr->set_operator (Cairo::OPERATOR_OVER);
// Render background
style->render_background(cr, graphX, graphY-graphH, graphW, graphH);
Gdk::RGBA c;
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
// Draw Locallab reference value in the background
if (locallabRef > 0.0) {
@ -309,28 +298,26 @@ void MyDiagonalCurve::draw (int handle)
// 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);
leftBar->setColoredBarSize(1., graphY - graphH - 0.5, CBAR_WIDTH, graphH);
leftBar->updateColoredBar(cr);
// 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->rectangle(0.5, graphY - graphH - 0.5 - 0.5, CBAR_WIDTH + 1, (double)graphH + 1. + 1.);
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);
bottomBar->setColoredBarSize(graphX - 0.5, graphY + RADIUS + CBAR_MARGIN + 1., graphW + 1., CBAR_WIDTH);
bottomBar->updateColoredBar(cr);
// 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->rectangle(graphX - 0.5 - 0.5, graphY + CBAR_MARGIN + 0.5, graphW + 1. + 0.5, CBAR_WIDTH + 1.);
cr->stroke();
}
@ -345,7 +332,7 @@ void MyDiagonalCurve::draw (int handle)
}
// draw histogram
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
double stepSize = graphW / 255.0;
cr->move_to (graphX, graphY);
c = style->get_color(state);
@ -367,18 +354,18 @@ void MyDiagonalCurve::draw (int handle)
}
// draw the grid lines:
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
c = style->get_border_color(state);
cr->set_source_rgba (c.get_red(), c.get_green(), c.get_blue(), 0.3);
cr->set_antialias (Cairo::ANTIALIAS_NONE);
for (int i = 0; i <= 10; i++) {
// horizontal lines
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.);
cr->move_to (graphX - 0.5 - 0.5, graphY + 0.5 + 0.5 - (graphH + 1. + 1.) * (double)i / 10.);
cr->rel_line_to (graphW + 1. + 1., 0.);
// vertical lines
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->move_to (graphX - 0.5 - 0.5 + (graphW + 1. + 1.) * (double)i / 10., graphY + 0.5 + 0.5);
cr->rel_line_to (0., -graphH - 1. - 1.);
}
cr->stroke ();
@ -390,16 +377,15 @@ void MyDiagonalCurve::draw (int handle)
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
}
std::valarray<double> ds (1);
ds[0] = 4 * s;
const std::valarray<double> ds = {4.};
cr->set_dash (ds, 0);
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->move_to (graphX - 0.5 - 0.5, graphY + 0.5 + 0.5);
cr->rel_line_to (graphW + 1. + 1., -(graphH + 1. + 1.));
cr->stroke ();
cr->unset_dash ();
cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
// draw upper and lower bounds
if (curve.type == DCT_Parametric && activeParam > 0 && lpoint.getUpperBound() > 1 && upoint.getUpperBound() > 1) {
@ -436,34 +422,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 (graphX + graphW * static_cast<double>(pipetteR), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteR), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
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 (graphX + graphW * static_cast<double>(pipetteG), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteG), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
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 (graphX + graphW * static_cast<double>(pipetteB), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteB), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
cr->stroke ();
}
}
if (pipetteVal > -1.f) {
cr->set_line_width (2. * s);
cr->set_line_width (2.);
c = style->get_color (state);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->move_to (graphX + graphW * static_cast<double>(pipetteVal), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteVal), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
cr->stroke ();
cr->set_line_width (1. * s);
cr->set_line_width (1.);
}
}
@ -472,10 +458,9 @@ void MyDiagonalCurve::draw (int handle)
// draw the cage of the NURBS curve
if (curve.type == DCT_NURBS) {
unsigned int nbPoints;
std::valarray<double> ch_ds (1);
ch_ds[0] = 2 * s;
const std::valarray<double> ch_ds = {2.};
cr->set_dash (ch_ds, 0);
cr->set_line_width (0.75 * s);
cr->set_line_width (0.75);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
std::vector<double> points = getPoints();
nbPoints = ((int)points.size() - 1) / 2;
@ -501,7 +486,7 @@ void MyDiagonalCurve::draw (int handle)
}
cr->unset_dash ();
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
}
// draw curve
@ -542,40 +527,26 @@ void MyDiagonalCurve::draw (int handle)
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 * s + 0.5, 0, 2 * rtengine::RT_PI);
cr->arc (x, y, RADIUS + 0.5, 0, 2 * rtengine::RT_PI);
cr->fill ();
if (i == edited_point) {
cr->set_line_width(2. * s);
cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI);
cr->set_line_width(2.);
cr->arc (x, y, RADIUS + 2., 0, 2 * rtengine::RT_PI);
cr->stroke();
cr->set_line_width(1. * s);
cr->set_line_width(1.);
}
}
}
setDirty(false);
queue_draw();
}
bool MyDiagonalCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
{
Gtk::Allocation allocation = get_allocation();
allocation.set_x(0);
allocation.set_y(0);
// Draw drawing area
// Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported
updateDrawingArea(lit_point, cr);
// setDrawRectangle will allocate the backbuffer Surface
if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) {
setDirty(true);
if (prevGraphW > GRAPH_SIZE || graphW > GRAPH_SIZE) {
curveIsDirty = true;
}
}
draw (lit_point);
copySurface(cr);
return false;
}
@ -594,10 +565,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
return false;
}
const double s = RTScalable::scalePixelSize(1.);
double minDistanceX = double(MIN_DISTANCE) / graphW * s;
double minDistanceY = double(MIN_DISTANCE) / graphH * s;
double minDistanceX = double(MIN_DISTANCE) / graphW;
double minDistanceY = double(MIN_DISTANCE) / graphH;
switch (event->type) {
case GDK_BUTTON_PRESS:
@ -644,8 +613,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
curve.y.at(closest_point) = clampedY;
curveIsDirty = true;
setDirty(true);
draw (closest_point);
queue_draw();
notifyListener ();
}
@ -680,8 +648,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
editedPos.at(1) = curve.y.at(edited_point);
coordinateAdjuster->setPos(editedPos);
coordinateAdjuster->startNumericalAdjustment(newBoundaries);
setDirty(true);
draw (lit_point);
queue_draw();
new_type = CSArrow;
}
}
@ -701,8 +668,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
if (lit_point != edited_point) {
edited_point = lit_point;
curveIsDirty = true;
setDirty(true);
draw (lit_point);
queue_draw();
std::vector<CoordinateAdjuster::Boundaries> newBoundaries;
newBoundaries.resize(2);
int size = curve.x.size();
@ -774,8 +740,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
curve.x.push_back (0);
curve.y.push_back (0);
curveIsDirty = true;
setDirty(true);
draw (lit_point);
queue_draw();
}
}
@ -788,8 +753,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
}
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
queue_draw();
}
grab_point = -1;
@ -809,8 +773,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
new_type = CSArrow;
lit_point = -1;
pipetteR = pipetteG = pipetteB = -1.f;
setDirty(true);
draw (lit_point);
queue_draw();
}
}
@ -854,8 +817,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
}
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
queue_draw();
if (lit_point > -1) {
editedPos.at(0) = curve.x.at(lit_point);
@ -884,8 +846,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
}
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
queue_draw();
}
}
} else {
@ -986,8 +947,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event)
if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) {
// we recalculate the curve only if we have to
curveIsDirty = true;
setDirty(true);
draw (lit_point);
queue_draw();
notifyListener ();
if (coordinateAdjuster->is_visible()) {
@ -1069,8 +1029,7 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi
return;
}
const double s = RTScalable::scalePixelSize(1.);
double minDistanceX = MIN_DISTANCE / graphW * s;
double minDistanceX = MIN_DISTANCE / graphW;
if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS || curve.type == DCT_CatumullRom) {
// get the pointer position
@ -1092,12 +1051,11 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi
}
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
queue_draw();
}
}
} else {
draw(lit_point);
queue_draw();
}
if (edited_point == -1) {
@ -1124,8 +1082,7 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi
return false;
}
const double s = RTScalable::scalePixelSize(1.);
double minDistanceX = double(MIN_DISTANCE) * s / graphW;
double minDistanceX = double(MIN_DISTANCE) / graphW;
snapToElmt = -100;
@ -1172,8 +1129,7 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi
}
curveIsDirty = true;
setDirty(true);
draw (lit_point);
queue_draw();
notifyListener ();
}
@ -1201,8 +1157,7 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider)
return;
}
const double s = RTScalable::scalePixelSize(1.);
double minDistanceX = double(MIN_DISTANCE) * s / graphW;
double minDistanceX = double(MIN_DISTANCE) / graphW;
snapToElmt = -100;
@ -1221,8 +1176,7 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider)
}
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
queue_draw();
}
grab_point = -1;
@ -1309,8 +1263,7 @@ void MyDiagonalCurve::pipetteDrag(EditDataProvider *provider, int modifierKey)
if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) {
// we recalculate the curve only if we have to
curveIsDirty = true;
setDirty(true);
draw (lit_point);
queue_draw();
notifyListener ();
if (lit_point > -1 && coordinateAdjuster->is_visible()) {
@ -1505,7 +1458,6 @@ void MyDiagonalCurve::setPoints (const std::vector<double>& p)
}
curveIsDirty = true;
setDirty(true);
queue_draw ();
}
@ -1520,8 +1472,7 @@ void MyDiagonalCurve::setPos(double pos, int chanIdx)
}
curveIsDirty = true;
setDirty(true);
draw(lit_point);
queue_draw();
notifyListener ();
}
@ -1530,8 +1481,7 @@ void MyDiagonalCurve::stopNumericalAdjustment()
if (edited_point > -1) {
edited_point = grab_point = lit_point = -1;
coordinateAdjuster->stopNumericalAdjustment();
setDirty(true);
draw(lit_point);
queue_draw();
}
}
@ -1539,13 +1489,12 @@ void MyDiagonalCurve::setType (DiagonalCurveType t)
{
curve.type = t;
setDirty(true);
queue_draw();
}
void MyDiagonalCurve::setActiveParam (int ac)
{
activeParam = ac;
setDirty(true);
queue_draw ();
}
@ -1579,7 +1528,6 @@ void MyDiagonalCurve::updateBackgroundHistogram (const LUTu & hist)
}
mcih->clearPixmap();
mcih->myCurve->queue_draw();
--mcih->pending;
@ -1632,6 +1580,5 @@ void MyDiagonalCurve::reset(const std::vector<double> &resetCurve, double identi
break;
}
setDirty(true);
draw(-1);
queue_draw();
}

View File

@ -64,7 +64,7 @@ protected:
bool bghistvalid;
double locallabRef; // Locallab reference value to display in the background
void draw (int handle);
void updateDrawingArea (const int handle, const ::Cairo::RefPtr< Cairo::Context> &cr);
void interpolate ();
void findClosestPoint();
CursorShape motionNotify(CursorShape type, double minDistanceX, double minDistanceY, int num);

View File

@ -23,7 +23,6 @@
#include "myflatcurve.h"
#include "editcallbacks.h"
#include "rtscalable.h"
#include "../rtengine/curves.h"
@ -130,24 +129,18 @@ void MyFlatCurve::interpolate ()
curveIsDirty = false;
}
void MyFlatCurve::draw ()
void MyFlatCurve::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr)
{
if (!isDirty()) {
if (!get_realized()) {
return;
}
if (!surfaceCreated()) {
return;
}
const double s = RTScalable::scalePixelSize(1.);
// 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)) )
|| (currLUTSize == GRAPH_SIZE && (graphW > GRAPH_SIZE))
|| (currLUTSize > GRAPH_SIZE && (graphW <= GRAPH_SIZE || graphW != currLUTSize)) )
{
interpolate ();
}
@ -155,20 +148,17 @@ void MyFlatCurve::draw ()
Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL;
Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
Cairo::RefPtr<Cairo::Context> cr = getContext();
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
// clear background
cr->set_source_rgba (0., 0., 0., 0.);
cr->set_operator (Cairo::OPERATOR_CLEAR);
cr->paint ();
// Setup drawing
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
cr->set_operator (Cairo::OPERATOR_OVER);
// Render background
style->render_background(cr, graphX, graphY-graphH, graphW, graphH);
Gdk::RGBA c;
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
// Draw Locallab reference value in the background
if (locallabRef > 0.0) {
@ -187,49 +177,46 @@ void MyFlatCurve::draw ()
// 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);
leftBar->setColoredBarSize(1., graphY - graphH - 0.5, CBAR_WIDTH, graphH);
leftBar->updateColoredBar(cr);
// 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->rectangle(0.5, graphY - graphH - 0.5 - 0.5, CBAR_WIDTH + 1, (double)graphH + 1.);
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);
bottomBar->setColoredBarSize(graphX - 0.5, graphY + RADIUS + CBAR_MARGIN + 1., graphW + 1., CBAR_WIDTH);
bottomBar->updateColoredBar(cr);
// 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->rectangle(graphX - 0.5 - 0.5, graphY + RADIUS + CBAR_MARGIN + 0.5, graphW + 1. + 1., CBAR_WIDTH + 1.);
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<double> ds (1);
ds[0] = 4 * s;
const std::valarray<double> ds = {4.};
cr->set_dash (ds, 0);
cr->move_to (graphX - 1. * s, graphY - graphH / 2.);
cr->rel_line_to (graphW + 2 * s, 0.);
cr->move_to (graphX - 1., graphY - graphH / 2.);
cr->rel_line_to (graphW + 2, 0.);
cr->stroke ();
cr->unset_dash ();
cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
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 * s);
cr->set_line_width (0.75);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
int n = 0;
@ -248,34 +235,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 (graphX + graphW * static_cast<double>(pipetteR), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteR), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
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 (graphX + graphW * static_cast<double>(pipetteG), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteG), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
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 (graphX + graphW * static_cast<double>(pipetteB), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteB), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
cr->stroke ();
}
}
if (pipetteVal > -1.f) {
cr->set_line_width (2. * s);
cr->set_line_width (2.);
c = style->get_color (state);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->move_to (graphX + graphW * static_cast<double>(pipetteVal), graphY + 1. * s);
cr->rel_line_to (0, -graphH - 1. * s);
cr->move_to (graphX + graphW * static_cast<double>(pipetteVal), graphY + 1.);
cr->rel_line_to (0, -graphH - 1.);
cr->stroke ();
cr->set_line_width (1. * s);
cr->set_line_width (1.);
}
}
@ -286,7 +273,7 @@ void MyFlatCurve::draw ()
for (int i = 0; i < (int)curve.x.size(); ++i) {
if (curve.x.at(i) != -1.) {
double coloredLineWidth = rtengine::min<double>( rtengine::max<double>(75. * s, graphW) / (75. * s), 8. * s);
double coloredLineWidth = rtengine::min<double>( rtengine::max<double>(75., graphW) / 75., 8.);
cr->set_line_width (coloredLineWidth);
colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_VERTICAL_BAR, colorCallerId, this);
@ -296,8 +283,8 @@ void MyFlatCurve::draw ()
cr->set_line_width (2 * coloredLineWidth);
}
cr->move_to (graphX + graphW * curve.x.at(i), graphY + 0.5 + 0.5 * s );
cr->rel_line_to (0., -graphH - 1. - s);
cr->move_to (graphX + graphW * curve.x.at(i), graphY + 0.5 + 0.5);
cr->rel_line_to (0., -graphH - 1. - 1.);
cr->stroke ();
cr->set_line_width (coloredLineWidth);
@ -323,39 +310,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 (graphX - 0.5 - 0.5 * s , graphY - graphH * curve.y.at(point));
cr->rel_line_to (graphW + 1. + s, 0.);
cr->move_to (graphX - 0.5 - 0.5 , graphY - graphH * curve.y.at(point));
cr->rel_line_to (graphW + 1. + 1., 0.);
cr->stroke ();
}
}
}
// endif
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
} 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 * s);
cr->set_line_width (2.0);
}
int point = edited_point > -1 ? edited_point : lit_point;
cr->move_to (graphX + graphW * curve.x.at(point), graphY + 0.5 + 0.5 * s );
cr->rel_line_to (0., -graphH - 1. - s);
cr->move_to (graphX + graphW * curve.x.at(point), graphY + 0.5 + 0.5);
cr->rel_line_to (0., -graphH - 1. - 1.);
cr->stroke ();
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
// draw the lit_point's horizontal line
if (editedHandle & (FCT_EditedHandle_CPointUD | FCT_EditedHandle_CPoint | FCT_EditedHandle_CPointY)) {
cr->set_line_width (2.0 * s);
cr->set_line_width (2.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->move_to (graphX - 0.5 - 0.5 , graphY - graphH * curve.y.at(point));
cr->rel_line_to (graphW + 1. + 1., 0.);
cr->stroke ();
cr->set_line_width (1.0 * s);
cr->set_line_width (1.0);
}
}
@ -364,10 +351,10 @@ 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(graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s, graphW + 1. + 1. * s, -(graphH + 1. + 1. * s));
cr->rectangle(graphX - 0.5 - 0.5, graphY + 0.5 + 0.5, graphW + 1. + 1., -(graphH + 1. + 1.));
cr->stroke ();
double lineMinLength = 1. / graphW * (double)(SQUARE) * 0.9 * s;
double lineMinLength = 1. / graphW * (double)(SQUARE) * 0.9;
if (tanHandlesDisplayed && lit_point != -1 && getHandles(lit_point) && curve.x.at(lit_point) != -1.) {
double x = graphX + graphW * curve.x.at(lit_point);
@ -398,9 +385,9 @@ void MyFlatCurve::draw ()
cr->move_to (x, y);
if (crossingTheFrame) {
cr->line_to (graphX - 0.5 - 0.5 * s, y);
cr->line_to (graphX - 0.5 - 0.5, y);
cr->stroke ();
cr->move_to (graphX + graphW + 0.5 + 0.5 * s, y);
cr->move_to (graphX + graphW + 0.5 + 0.5, y);
}
cr->line_to (x2, y);
@ -408,7 +395,7 @@ void MyFlatCurve::draw ()
}
// draw tangential knot
square = (area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE) * s;
square = (area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE);
cr->rectangle(x2 - square, y - square, 2.*square, 2.*square);
cr->fill();
@ -434,9 +421,9 @@ void MyFlatCurve::draw ()
cr->move_to (x, y);
if (crossingTheFrame) {
cr->line_to (graphX + graphW + 0.5 + 0.5 * s, y);
cr->line_to (graphX + graphW + 0.5 + 0.5, y);
cr->stroke ();
cr->move_to (graphX - 0.5 - 0.5 * s, y);
cr->move_to (graphX - 0.5 - 0.5, y);
}
cr->line_to (x2, y);
@ -444,7 +431,7 @@ void MyFlatCurve::draw ()
}
// draw tangential knot
square = (area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE) * s;
square = (area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE);
cr->rectangle(x2 - square, y - square, 2.*square, 2.*square);
cr->fill();
}
@ -483,15 +470,15 @@ void MyFlatCurve::draw ()
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 * s + 0.5, 0, 2 * rtengine::RT_PI);
cr->arc (x, y, RADIUS + 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. * s);
cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI);
cr->set_line_width(2.);
cr->arc (x, y, RADIUS + 2., 0, 2 * rtengine::RT_PI);
cr->stroke();
cr->set_line_width(1. * s);
cr->set_line_width(1.);
}
}
@ -524,30 +511,14 @@ void MyFlatCurve::draw ()
graphW * minDistanceY);
cr->fill();
}
setDirty(false);
queue_draw();
}
bool MyFlatCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
{
Gtk::Allocation allocation = get_allocation();
allocation.set_x(0);
allocation.set_y(0);
// Draw drawing area
// Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported
updateDrawingArea(cr);
const int s = RTScalable::scalePixelSize(1);
// setDrawRectangle will allocate the backbuffer Surface
if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) {
setDirty(true);
if (prevGraphW > (GRAPH_SIZE * s) || graphW > (GRAPH_SIZE * s)) {
curveIsDirty = true;
}
}
draw ();
copySurface(cr);
return false;
}
@ -619,10 +590,8 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
return false;
}
const double s = RTScalable::scalePixelSize(1.);
minDistanceX = double(MIN_DISTANCE) / graphW * s;
minDistanceY = double(MIN_DISTANCE) / graphH * s;
minDistanceX = double(MIN_DISTANCE) / graphW;
minDistanceY = double(MIN_DISTANCE) / graphH;
switch (event->type) {
@ -680,8 +649,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
curve.rightTangent.at(closest_point) = 0.35;
curveIsDirty = true;
setDirty(true);
draw ();
queue_draw();
notifyListener ();
lit_point = closest_point;
@ -738,8 +706,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
new_type = CSArrow;
tanHandlesDisplayed = false;
edited_point = lit_point;
setDirty(true);
draw ();
queue_draw();
std::vector<CoordinateAdjuster::Boundaries> newBoundaries(4);
int size = curve.x.size();
@ -787,8 +754,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
// the cursor is close to an existing point
if (lit_point != edited_point) {
edited_point = lit_point;
setDirty(true);
draw ();
queue_draw();
std::vector<CoordinateAdjuster::Boundaries> newBoundaries(4);
int size = curve.x.size();
@ -910,8 +876,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
break;
}
setDirty(true);
draw ();
queue_draw();
retval = true;
//notifyListener ();
}
@ -1042,8 +1007,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
}
if ((lit_point != previous_lit_point) || (prevArea != area)) {
setDirty(true);
draw ();
queue_draw();
}
if (coordinateAdjuster->is_visible() && edited_point == -1) {
@ -1121,8 +1085,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
if (curve.leftTangent.at(lit_point) != prevValue) {
curveIsDirty = true;
setDirty(true);
draw ();
queue_draw();
notifyListener ();
if (coordinateAdjuster->is_visible()) {
@ -1153,8 +1116,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
if (curve.rightTangent.at(lit_point) != prevValue) {
curveIsDirty = true;
setDirty(true);
draw ();
queue_draw();
notifyListener ();
editedPos.at(3) = curve.rightTangent.at(lit_point);
coordinateAdjuster->setPos(editedPos);
@ -1198,8 +1160,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event)
lit_point = -1;
tanHandlesDisplayed = false;
pipetteR = pipetteG = pipetteB = -1.f;
setDirty(true);
draw ();
queue_draw();
}
retval = true;
@ -1290,11 +1251,10 @@ void MyFlatCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider,
if (edited_point == -1) {
if (editedHandle == FCT_EditedHandle_None && lit_point != previous_lit_point) {
setDirty(true);
draw ();
queue_draw();
}
} else {
draw();
queue_draw();
}
if (edited_point == -1) {
@ -1321,13 +1281,11 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier
// hide the tangent handles
tanHandlesDisplayed = false;
const int s = RTScalable::scalePixelSize(1);
// Action on BUTTON_PRESS and no edited point
switch (area) {
case (FCT_Area_Insertion): {
rtengine::FlatCurve rtCurve(getPoints(), true, GRAPH_SIZE * s);
rtengine::FlatCurve rtCurve(getPoints(), true, GRAPH_SIZE);
std::vector<double>::iterator itx, ity, itlt, itrt;
int num = (int)curve.x.size();
@ -1364,8 +1322,7 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier
curve.rightTangent.at(closest_point) = 0.35;
curveIsDirty = true;
setDirty(true);
draw ();
queue_draw();
notifyListener ();
lit_point = closest_point;
@ -1407,8 +1364,7 @@ void MyFlatCurve::pipetteButton1Released(EditDataProvider *provider)
getCursorPosition(Gdk::EventType(Gdk::BUTTON_PRESS), false, px, graphY, Gdk::ModifierType(0));
getMouseOverArea();
setDirty(true);
draw ();
queue_draw();
//notifyListener ();
}
@ -1633,8 +1589,7 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY, bool pipetteDrag)
if (curve.x.at(lit_point) != prevPosX || curve.y.at(lit_point) != prevPosY) {
// we recompute the curve only if we have to
curveIsDirty = true;
setDirty(true);
draw ();
queue_draw();
notifyListener ();
}
}
@ -1842,7 +1797,6 @@ void MyFlatCurve::setPoints (const std::vector<double>& p)
}
curveIsDirty = true;
setDirty(true);
queue_draw ();
}
@ -1869,8 +1823,7 @@ void MyFlatCurve::setPos(double pos, int chanIdx)
}
curveIsDirty = true;
setDirty(true);
draw();
queue_draw();
notifyListener ();
}
@ -1880,8 +1833,7 @@ void MyFlatCurve::stopNumericalAdjustment()
edited_point = lit_point = -1;
area = FCT_Area_None;
coordinateAdjuster->stopNumericalAdjustment();
setDirty(true);
draw();
queue_draw();
}
}
@ -1904,8 +1856,7 @@ void MyFlatCurve::updateLocallabBackground(double ref)
return false;
}
mcih->clearPixmap();
mcih->myCurve->queue_draw();
mcih->clearPixmap();
--mcih->pending;
@ -1918,7 +1869,7 @@ void MyFlatCurve::setType (FlatCurveType t)
{
curve.type = t;
setDirty(true);
queue_draw();
}
void MyFlatCurve::reset(const std::vector<double> &resetCurve, double identityValue)
@ -1946,8 +1897,7 @@ void MyFlatCurve::reset(const std::vector<double> &resetCurve, double identityVa
break;
}
setDirty(true);
draw();
queue_draw();
}
void MyFlatCurve::defaultCurve (double iVal)

View File

@ -99,7 +99,7 @@ protected:
enum MouseOverAreas area;
double locallabRef; // Locallab reference value to display in the background
void draw ();
void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr);
void movePoint(bool moveX, bool moveY, bool pipetteDrag = false);
void defaultCurve (double iVal = 0.5);
void interpolate ();

View File

@ -112,64 +112,46 @@ void SHCSelector::on_realize()
add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
}
void SHCSelector::updateBackBuffer()
void SHCSelector::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr)
{
if (!get_realized() || !isDirty() || !get_width() || !get_height()) {
if (!get_realized() || !get_width() || !get_height()) {
return;
}
// This will create or update the size of the BackBuffer::surface
setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, get_width(), get_height(), true);
if (!surface) {
return;
}
Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
cr->set_source_rgba (0., 0., 0., 0.);
cr->set_operator (Cairo::OPERATOR_CLEAR);
cr->paint ();
// Setup drawing
cr->set_operator (Cairo::OPERATOR_OVER);
int w = get_width () - leftMargin - rightMargin;
int h = get_height ();
// Get drawing area size
const int w = get_width () - leftMargin - rightMargin;
const int h = get_height ();
const double s = RTScalable::scalePixelSize(1.);
// Compute slider parameters
wslider = static_cast<double>(std::max(h / 5, 10));
const double hwslider = wslider / 2.;
wslider = (double)std::max(h / 5, 10) * s;
double hwslider = wslider / 2.;
// clear bg
cr->set_source_rgba (0., 0., 0., 0.);
cr->set_operator (Cairo::OPERATOR_CLEAR);
cr->paint ();
cr->set_operator (Cairo::OPERATOR_OVER);
// set the box's colors
cr->set_line_width (1.0 * s);
// Set the box's colors
cr->set_line_width (1.0);
cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL);
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
int coloredBarHeight = (int)((double)h * 5.5 / 7. + 0.5);
int coloredBarHeight = static_cast<int>(static_cast<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 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s);
// that we're displaying here
coloredBar.expose(*this, cr);
// Gradient background
coloredBar.setColoredBarSize(leftMargin + 1, 1, w - 2, coloredBarHeight - 2);
coloredBar.updateColoredBar(cr);
} else {
style->render_background(cr, leftMargin + 1 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s);
// Style background
style->render_background(cr, leftMargin + 1, 1, w - 2, coloredBarHeight - 2);
}
// draw the box's borders
// Draw the box's borders
style->render_frame(cr, leftMargin, 0, w, coloredBarHeight);
// draw sliders
// Draw sliders
for (int i = 0; i < 3; i++) {
if (i == movingPosition) {
style->set_state(Gtk::STATE_FLAG_ACTIVE);
@ -180,11 +162,16 @@ void SHCSelector::updateBackBuffer()
style->set_state(Gtk::STATE_FLAG_NORMAL);
}
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->render_slider(cr,
static_cast<double>(leftMargin) + 1. + (static_cast<double>(w) - 2.) * positions[i] - static_cast<double>(hwslider),
static_cast<double>(vb),
wslider,
static_cast<double>(h) - static_cast<double>(vb),
Gtk::ORIENTATION_VERTICAL);
style->set_state(Gtk::STATE_FLAG_NORMAL);
}
// draw text for the slider that is being moved
// Draw text for the slider that is being moved
if (movingPosition >= 0) {
int i = movingPosition;
int offset;
@ -193,7 +180,7 @@ void SHCSelector::updateBackBuffer()
Glib::RefPtr<Pango::Context> context = get_pango_context () ;
Pango::FontDescription fontd(get_style_context()->get_font());
// update font
// Update font
fontd.set_weight (Pango::WEIGHT_NORMAL);
const double fontSize = static_cast<double>(h) * 0.8; // pt
@ -213,17 +200,17 @@ void SHCSelector::updateBackBuffer()
Glib::RefPtr<Pango::Layout> 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 * (int)s - hwslider : 1 * (int)s + hwslider;
offset = positions[i] > 0.5 ? -layout_width - 1 - hwslider : 1 + hwslider;
cr->set_source_rgb (0., 0., 0.);
cr->set_line_width(3. * s);
cr->set_line_width(3.);
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
cr->move_to ((double)leftMargin + (double)w * positions[i] + (double)offset, 0.);
cr->move_to (static_cast<double>(leftMargin) + static_cast<double>(w) * positions[i] + static_cast<double>(offset), 0.);
layout->add_to_cairo_context (cr);
cr->stroke_preserve();
cr->set_line_width(0.5 * s);
cr->set_line_width(0.5);
cr->set_source_rgb (1., 1., 1.);
cr->fill ();
}
@ -231,17 +218,9 @@ void SHCSelector::updateBackBuffer()
bool SHCSelector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
{
// on_realize & updateBackBuffer have to be called before
if (get_realized() && get_width() && get_height()) {
if (isDirty()) {
updateBackBuffer();
}
if (surface) {
copySurface(cr);
}
}
// Draw drawing area
// Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported
updateDrawingArea(cr);
return true;
}
@ -250,14 +229,12 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event)
{
// check if a slider is under the cursor
double w = double(get_width () - leftMargin - rightMargin);
const double w = static_cast<double>(get_width () - leftMargin - rightMargin);
movingPosition = -1;
const double s = RTScalable::scalePixelSize(1.);
for (int i = 0; i < 3; i++) {
double currPos = double(leftMargin) + 1. * s + (w - 2. * s) * positions[i];
double hwslider = wslider / 2.;
const double currPos = static_cast<double>(leftMargin) + 1. + (w - 2.) * positions[i];
const double hwslider = wslider / 2.;
if (event->x >= currPos - hwslider && event->x <= currPos + hwslider) {
movingPosition = i;
tmpX = event->x;
@ -299,8 +276,7 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event)
{
if (movingPosition >= 0) {
const double s = RTScalable::scalePixelSize(1.);
double innerw = double(get_width () - leftMargin - rightMargin) - 2. * s;
const double innerw = static_cast<double>(get_width () - leftMargin - rightMargin) - 2.;
positions[movingPosition] = tmpPos + (event->x - tmpX) / innerw;
if (positions[movingPosition] < 0) {
@ -323,7 +299,6 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event)
cl->shcChanged ();
}
setDirty(true);
queue_draw ();
}
@ -333,7 +308,6 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event)
void SHCSelector::styleChanged (const Glib::RefPtr<Gtk::StyleContext>& style)
{
setDirty(true);
queue_draw ();
}
@ -347,7 +321,6 @@ bool SHCSelector::reset () // : movingPosition(-1), cl(NULL) {
positions[0] = defaults[0];
positions[1] = defaults[1];
positions[2] = defaults[2];
setDirty(true);
queue_draw ();
return true;
}
@ -357,7 +330,6 @@ bool SHCSelector::reset () // : movingPosition(-1), cl(NULL) {
void SHCSelector::refresh()
{
setDirty(true);
Glib::RefPtr<Gdk::Window> win = get_window();
if (win) {
win->invalidate(true);

View File

@ -29,7 +29,7 @@ public:
virtual void shcChanged() = 0;
};
class SHCSelector final : public Gtk::DrawingArea, BackBuffer
class SHCSelector final : public Gtk::DrawingArea
{
protected:
@ -61,7 +61,7 @@ protected:
bool on_button_press_event (GdkEventButton* event) override;
bool on_button_release_event (GdkEventButton* event) override;
bool on_motion_notify_event (GdkEventMotion* event) override;
void updateBackBuffer();
void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr);
public:

View File

@ -148,7 +148,6 @@ void ThresholdSelector::initValues ()
set_name("ThresholdSelector");
set_can_focus(false);
set_app_paintable(true);
setDirty(true);
updateTooltip();
}
@ -198,7 +197,7 @@ void ThresholdSelector::setPositions (double bottom, double top)
setPositions(bottom, top, maxValBottom, maxValTop);
if (updatePolicy == RTUP_DYNAMIC) {
setDirty(true);
queue_draw();
}
}
@ -216,10 +215,6 @@ void ThresholdSelector::setPositions (double bottomLeft, double topLeft, double
positions[TS_TOPRIGHT] = topRight;
if (different) {
if (updatePolicy == RTUP_DYNAMIC) {
setDirty(true);
}
sig_val_changed.emit();
updateTooltip();
queue_draw ();
@ -246,75 +241,58 @@ void ThresholdSelector::setDefaults (double bottomLeft, double topLeft, double b
void ThresholdSelector::on_realize()
{
Gtk::DrawingArea::on_realize();
add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::LEAVE_NOTIFY_MASK);
}
void ThresholdSelector::updateBackBuffer()
void ThresholdSelector::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr)
{
if (!get_realized() || !isDirty() || !get_allocated_width() || !get_allocated_height()) {
// on_realize has to be called before
if (!get_realized() || !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_allocated_width(), get_allocated_height(), true);
// Get border padding
const Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
Gtk::Border padding = getPadding(style);
if (!surface) {
return;
}
Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
Glib::RefPtr<Gtk::StyleContext> 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 ();
// Setup drawing
cr->set_operator (Cairo::OPERATOR_OVER);
const double s = RTScalable::scalePixelSize(1.);
// Get widget size
const int w = get_allocated_width ();
const int h = get_allocated_height ();
double positions01[4];
int w = get_allocated_width ();
int h = get_allocated_height ();
// Compute slider parameters
const double wslider = sliderWidth; // constant must be an odd value
const double hwslider = wslider / 2.;
const double verticalSliderPadding = std::floor((static_cast<double>(h) - static_cast<double>(padding.get_top()) - static_cast<double>(padding.get_bottom())) * verticalSliderPaddingFactor + 0.5);
// Get threshold selector positions
const double positions01[4] = {to01(TS_BOTTOMLEFT), to01(TS_TOPLEFT), to01(TS_BOTTOMRIGHT), to01(TS_TOPRIGHT)};
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);
// Compute internal background position and size
const double innerBarX = static_cast<double>(padding.get_left()) + hwslider - 0.5;
const double innerBarY = verticalSliderPadding + 1. + static_cast<double>(padding.get_top());
const double innerBarW = static_cast<double>(w) - innerBarX - static_cast<double>(padding.get_right()) - hwslider - 0.5;
const double innerBarH = static_cast<double>(h) - innerBarY - verticalSliderPadding - 1. - static_cast<double>(padding.get_bottom());
positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT);
positions01[TS_TOPLEFT] = to01(TS_TOPLEFT);
positions01[TS_BOTTOMRIGHT] = to01(TS_BOTTOMRIGHT);
positions01[TS_TOPRIGHT] = to01(TS_TOPRIGHT);
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();
// Render background (style one or colored bar one)
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(innerBarX, innerBarY, innerBarW, innerBarH);
// that we're displaying here
coloredBar.expose(*this, cr);
coloredBar.setColoredBarSize(innerBarX, innerBarY, innerBarW, innerBarH);
coloredBar.updateColoredBar(cr);
} else {
style->render_background(cr, innerBarX, innerBarY, innerBarW, innerBarH);
}
// 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;
// Render curve
const double yStart = innerBarY + innerBarH - 1.;
const double yEnd = innerBarY + 1.;
const double xStart = innerBarX;
const double xEnd = innerBarX + innerBarW;
const double iw = xEnd - xStart;
const double ih = yEnd - yStart;
if (bgCurveProvider) {
@ -390,26 +368,27 @@ void ThresholdSelector::updateBackBuffer()
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
cr->set_line_join(Cairo::LINE_JOIN_BEVEL);
// Render surrounding curve (black)
if (is_sensitive()) {
// draw surrounding curve (black)
cr->set_source_rgb (0., 0., 0.);
cr->set_line_width (4. * s);
cr->set_line_width (4.);
cr->stroke_preserve();
}
// draw inner curve (white)
// Render 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 (2. * s);
cr->set_line_width (2.);
cr->stroke ();
// draw the box's borders
style->render_frame(cr, innerBarX - 1. * s, innerBarY - 1. * s, innerBarW + 2. * s, innerBarH + 2. * s);
// Render the box's borders
style->render_frame(cr, innerBarX - 1., innerBarY - 1., innerBarW + 2., innerBarH + 2.);
// draw sliders
// Render sliders
Gtk::StateFlags currState = style->get_state();
cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL);
@ -426,9 +405,9 @@ void ThresholdSelector::updateBackBuffer()
style->set_state(Gtk::STATE_FLAG_NORMAL);
}
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;
const double posX = xStart + iw * positions01[i];
const double arrowY = i == 0 || i == 2 ? yStart - 3. : yEnd + 3.;
const double baseY = i == 0 || i == 2 ? static_cast<double>(h) - static_cast<double>(padding.get_bottom()) - 0.5 : static_cast<double>(padding.get_top()) + 0.5;
style->render_slider(cr, posX - hwslider, i == 0 || i == 2 ? arrowY : baseY, wslider, i == 0 || i == 2 ? baseY - arrowY : arrowY - baseY, Gtk::ORIENTATION_HORIZONTAL);
}
@ -438,17 +417,9 @@ void ThresholdSelector::updateBackBuffer()
bool ThresholdSelector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
{
// on_realize & updateBackBuffer have to be called before
if (get_realized() && get_allocated_width() && get_allocated_height()) {
if (isDirty()) {
updateBackBuffer();
}
if (surface) {
copySurface(cr);
}
}
// Draw drawing area
// Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported
updateDrawingArea(cr);
return true;
}
@ -494,21 +465,19 @@ bool ThresholdSelector::on_leave_notify_event (GdkEventCrossing* event)
bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event)
{
const int w = get_allocated_width ();
const Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
const Gtk::Border padding = getPadding(style);
int w = get_allocated_width ();
Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
Gtk::Border padding = getPadding(style); // already scaled
const double wslider = sliderWidth; // constant must be an odd value
const double hwslider = wslider / 2.;
const double s = RTScalable::scalePixelSize(1.);
double wslider = sliderWidth * s; // constant must be an odd value
double hwslider = wslider / 2.;
const double innerBarX = static_cast<double>(padding.get_left()) + hwslider - 0.5;
const double innerBarW = static_cast<double>(w) - innerBarX - static_cast<double>(padding.get_right()) - hwslider - 0.5;
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;
const double xStart = innerBarX + 0.5;
const double xEnd = innerBarX + innerBarW - 0.5;
const double iw = xEnd - xStart;
findLitCursor(event->x, event->y);
@ -556,11 +525,6 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event)
// set the new reference value for the next move
tmpX = event->x;
// ask to redraw the background
if (updatePolicy == RTUP_DYNAMIC) {
setDirty(true);
}
// update the tooltip
updateTooltip();
@ -581,27 +545,26 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event)
void ThresholdSelector::findLitCursor(int posX, int posY)
{
int w = get_allocated_width ();
int h = get_allocated_height ();
Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
Gtk::Border padding = getPadding(style); // already scaled
const int w = get_allocated_width ();
const int h = get_allocated_height ();
const Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
const Gtk::Border padding = getPadding(style);
const double s = RTScalable::scalePixelSize(1.);
double wslider = sliderWidth * s; // constant must be an odd value
double hwslider = wslider / 2.;
const double wslider = sliderWidth; // constant must be an odd value
const 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;
const double innerBarX = static_cast<double>(padding.get_left()) + hwslider - 0.5;
const double innerBarW = static_cast<double>(w) - innerBarX - static_cast<double>(padding.get_right()) - hwslider - 0.5;
litCursor = TS_UNDEFINED;
if (posY >= 0 && posY <= h / 2) {
if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) {
if (posX >= static_cast<int>(innerBarX - hwslider) && posX <= static_cast<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 = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop;
const double cursorX = (static_cast<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;
@ -609,12 +572,12 @@ void ThresholdSelector::findLitCursor(int posX, int posY)
}
}
} else if (posY > h / 2 && posY < h) {
if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) {
if (posX >= static_cast<int>(innerBarX - hwslider) && posX <= static_cast<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 = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop;
double cursorX = (static_cast<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;
@ -728,10 +691,6 @@ void ThresholdSelector::reset ()
positions[2] = defPos[2];
positions[3] = defPos[3];
if (updatePolicy == RTUP_DYNAMIC) {
setDirty(true);
}
updateTooltip();
queue_draw ();
}

View File

@ -21,7 +21,6 @@
#include <iomanip>
#include "coloredbar.h"
#include "guiutils.h"
#include "../rtengine/procparams.h"
@ -61,7 +60,7 @@ public:
* have to provide through the ThresholdCurveProvider interface
*
*/
class ThresholdSelector : public Gtk::DrawingArea, public BackBuffer
class ThresholdSelector : public Gtk::DrawingArea
{
public:
@ -109,16 +108,20 @@ protected:
void findSecondaryMovedCursor(guint state);
void findBoundaries(double &min, double &max);
double to01(ThreshCursorId cursorId);
// Internal drawing functions
void updateTooltip();
void updateBackBuffer();
void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr);
// GtkDrawingArea override functions
void on_realize () override;
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
Gtk::SizeRequestMode get_request_mode_vfunc () const override;
void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const final;
void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const final;
void get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const final;
void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const final;
void on_realize () override;
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
bool on_button_press_event (GdkEventButton* event) override;
bool on_button_release_event (GdkEventButton* event) override;
bool on_motion_notify_event (GdkEventMotion* event) override;