1 /* 2 * This file is part of RawTherapee. 3 * 4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com> 5 * 6 * RawTherapee is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * RawTherapee is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with RawTherapee. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 #pragma once 20 21 #include <gtkmm.h> 22 23 #include <glibmm/ustring.h> 24 25 #include <cairomm/cairomm.h> 26 27 #include "guiutils.h" 28 #include "pointermotionlistener.h" 29 30 #include "../rtengine/LUT.h" 31 #include "../rtengine/noncopyable.h" 32 33 class HistogramArea; 34 35 struct HistogramAreaIdleHelper { 36 HistogramArea* harea; 37 bool destroyed; 38 int pending; 39 }; 40 41 class HistogramRGBArea; 42 struct HistogramRGBAreaIdleHelper { 43 HistogramRGBArea* harea; 44 bool destroyed; 45 int pending; 46 }; 47 48 class HistogramScaling 49 { 50 public: 51 double factor; HistogramScaling()52 HistogramScaling() : factor(10.0) {} 53 double log (double vsize, double val); 54 }; 55 56 class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable 57 { 58 private: 59 typedef const double (*TMatrix)[3]; 60 61 IdleRegister idle_register; 62 63 protected: 64 int val; 65 int r; 66 int g; 67 int b; 68 69 bool valid; 70 71 bool needRed; 72 bool needGreen; 73 bool needBlue; 74 bool needLuma; 75 bool needChroma; 76 bool rawMode; 77 bool showMode; 78 bool barDisplayed; 79 80 Gtk::Grid* parent; 81 82 HistogramRGBAreaIdleHelper* harih; 83 84 public: 85 HistogramRGBArea(); 86 ~HistogramRGBArea() override; 87 88 void updateBackBuffer (int r, int g, int b, const Glib::ustring &profile = "", const Glib::ustring &profileW = ""); 89 bool getShow (); setParent(Gtk::Grid * p)90 void setParent (Gtk::Grid* p) 91 { 92 parent = p; 93 }; 94 95 void update (int val, int rh, int gh, int bh); 96 void updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, bool show); 97 98 void on_realize() override; 99 bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; 100 bool on_button_press_event (GdkEventButton* event) override; 101 void factorChanged (double newFactor); 102 103 private: 104 Gtk::SizeRequestMode get_request_mode_vfunc () const override; 105 void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; 106 void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; 107 void get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const override; 108 void get_preferred_width_for_height_vfunc (int h, int &minimum_width, int &natural_width) const override; 109 110 }; 111 112 class DrawModeListener 113 { 114 public: 115 virtual ~DrawModeListener() = default; 116 virtual void toggleButtonMode() = 0; 117 }; 118 119 class HistogramArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable 120 { 121 public: 122 typedef sigc::signal<void, double> type_signal_factor_changed; 123 124 private: 125 IdleRegister idle_register; 126 type_signal_factor_changed sigFactorChanged; 127 128 protected: 129 LUTu rhist, ghist, bhist, lhist, chist; 130 LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused? 131 132 bool valid; 133 int drawMode; 134 DrawModeListener *myDrawModeListener; 135 int oldwidth, oldheight; 136 137 bool needRed, needGreen, needBlue, needLuma, needChroma; 138 bool rawMode; 139 bool isPressed; 140 double movingPosition; 141 142 HistogramAreaIdleHelper* haih; 143 144 public: 145 explicit HistogramArea(DrawModeListener *fml = nullptr); 146 ~HistogramArea() override; 147 148 void updateBackBuffer (); 149 void update( 150 const LUTu& histRed, 151 const LUTu& histGreen, 152 const LUTu& histBlue, 153 const LUTu& histLuma, 154 const LUTu& histChroma, 155 const LUTu& histRedRaw, 156 const LUTu& histGreenRaw, 157 const LUTu& histBlueRaw 158 ); 159 void updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode); 160 void on_realize() override; 161 bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; 162 bool on_button_press_event (GdkEventButton* event) override; 163 bool on_button_release_event (GdkEventButton* event) override; 164 bool on_motion_notify_event (GdkEventMotion* event) override; 165 type_signal_factor_changed signal_factor_changed(); 166 167 private: 168 void drawCurve(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int vsize); 169 void drawMarks(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi); 170 Gtk::SizeRequestMode get_request_mode_vfunc () const override; 171 void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; 172 void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; 173 void get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const override; 174 void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; 175 }; 176 177 class HistogramPanel : public Gtk::Grid, public PointerMotionListener, public DrawModeListener, public rtengine::NonCopyable 178 { 179 180 protected: 181 182 Gtk::Grid* gfxGrid; 183 Gtk::Grid* buttonGrid; 184 HistogramArea* histogramArea; 185 HistogramRGBArea* histogramRGBArea; 186 Gtk::ToggleButton* showRed; 187 Gtk::ToggleButton* showGreen; 188 Gtk::ToggleButton* showBlue; 189 Gtk::ToggleButton* showValue; 190 Gtk::ToggleButton* showRAW; 191 Gtk::ToggleButton* showBAR; 192 Gtk::ToggleButton* showChro; 193 Gtk::Button* showMode; 194 195 Gtk::Image *redImage; 196 Gtk::Image *greenImage; 197 Gtk::Image *blueImage; 198 Gtk::Image *valueImage; 199 Gtk::Image *rawImage; 200 Gtk::Image *barImage; 201 Gtk::Image *chroImage; 202 203 Gtk::Image *redImage_g; 204 Gtk::Image *greenImage_g; 205 Gtk::Image *blueImage_g; 206 Gtk::Image *valueImage_g; 207 Gtk::Image *rawImage_g; 208 Gtk::Image *barImage_g; 209 Gtk::Image *chroImage_g; 210 211 Gtk::Image *mode0Image; 212 Gtk::Image *mode1Image; 213 Gtk::Image *mode2Image; 214 215 sigc::connection rconn; 216 void setHistInvalid (); 217 218 public: 219 220 HistogramPanel (); 221 ~HistogramPanel () override; 222 histogramChanged(const LUTu & histRed,const LUTu & histGreen,const LUTu & histBlue,const LUTu & histLuma,const LUTu & histChroma,const LUTu & histRedRaw,const LUTu & histGreenRaw,const LUTu & histBlueRaw)223 void histogramChanged( 224 const LUTu& histRed, 225 const LUTu& histGreen, 226 const LUTu& histBlue, 227 const LUTu& histLuma, 228 const LUTu& histChroma, 229 const LUTu& histRedRaw, 230 const LUTu& histGreenRaw, 231 const LUTu& histBlueRaw) 232 { 233 histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw); 234 } 235 // pointermotionlistener interface 236 void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) override; 237 238 // TODO should be protected 239 void setHistRGBInvalid (); 240 241 void reorder (Gtk::PositionType position); 242 void red_toggled (); 243 void green_toggled (); 244 void blue_toggled (); 245 void value_toggled (); 246 void raw_toggled (); 247 void chro_toggled (); 248 void bar_toggled (); 249 void mode_released (); 250 void rgbv_toggled (); 251 void resized (Gtk::Allocation& req); 252 253 // drawModeListener interface 254 void toggleButtonMode () override; 255 }; 256