summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/ink-color-wheel.h
blob: 57af89640ba94e0f4f4de56c2f41ad2078c18065 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * @file
 * HSLuv color wheel widget, based on the web implementation at
 * https://www.hsluv.org
 *
 * Authors:
 *   Tavmjong Bah
 *   Massinissa Derriche <massinissa.derriche@gmail.com>
 *
 * Copyright (C) 2018, 2021 Authors
 *
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#ifndef INK_COLORWHEEL_H
#define INK_COLORWHEEL_H

#include <gtkmm.h>

namespace Inkscape {
namespace UI {
namespace Widget {

struct PickerGeometry;

/**
 * @class ColorWheel
 */
class ColorWheel : public Gtk::DrawingArea
{
public:
    ColorWheel();

    virtual void setRgb(double r, double g, double b, bool overrideHue = true);
    virtual void getRgb(double *r, double *g, double *b) const;
    virtual void getRgbV(double *rgb) const;
    virtual guint32 getRgb() const;

    void setHue(double h);
    void setSaturation(double s);
    virtual void setLightness(double l);
    void getValues(double *a, double *b, double *c) const;

    bool isAdjusting() const { return _adjusting; }

protected:
    virtual void _set_from_xy(double const x, double const y);

    double _values[3];
    bool _adjusting;

private:
    // Callbacks
    bool on_key_release_event(GdkEventKey* key_event) override;

    // Signals
public:
    sigc::signal<void> signal_color_changed();

protected:
    sigc::signal<void> _signal_color_changed;
};

/**
 * @class ColorWheelHSL
 */
class ColorWheelHSL : public ColorWheel
{
public:
    void setRgb(double r, double g, double b, bool overrideHue = true) override;
    void getRgb(double *r, double *g, double *b) const override;
    void getRgbV(double *rgb) const override;
    guint32 getRgb() const override;

    void getHsl(double *h, double *s, double *l) const;

protected:
    bool on_draw(const::Cairo::RefPtr<::Cairo::Context>& cr) override;
    bool on_focus(Gtk::DirectionType direction) override;

private:
    void _set_from_xy(double const x, double const y) override;
    bool _is_in_ring(double x, double y);
    bool _is_in_triangle(double x, double y);
    void _update_triangle_color(double x, double y);
    void _update_ring_color(double x, double y);
    void _triangle_corners(double& x0, double& y0, double& x1, double& y1, double& x2,
            double& y2);

    enum class DragMode {
        NONE,
        HUE,
        SATURATION_VALUE
    };

    double _ring_width = 0.2;
    DragMode _mode = DragMode::NONE;
    bool _focus_on_ring = true;

    // Callbacks
    bool on_button_press_event(GdkEventButton* event) override;
    bool on_button_release_event(GdkEventButton* event) override;
    bool on_motion_notify_event(GdkEventMotion* event) override;
    bool on_key_press_event(GdkEventKey* key_event) override;
};

/**
 * @class ColorWheelHSLuv
 */
class ColorWheelHSLuv : public ColorWheel
{
public:
    ColorWheelHSLuv();
    ~ColorWheelHSLuv() override;

    void setRgb(double r, double g, double b, bool overrideHue = true) override;
    void getRgb(double *r, double *g, double *b) const override;
    void getRgbV(double *rgb) const override;
    guint32 getRgb() const override;

    void setHsluv(double h, double s, double l);
    void setLightness(double l) override;

    void getHsluv(double *h, double *s, double *l) const;

protected:
    bool on_draw(const::Cairo::RefPtr<::Cairo::Context>& cr) override;

private:
    void _set_from_xy(double const x, double const y) override;
    void _update_polygon();

    // Callbacks
    bool on_button_press_event(GdkEventButton* event) override;
    bool on_button_release_event(GdkEventButton* event) override;
    bool on_motion_notify_event(GdkEventMotion* event) override;
    bool on_key_press_event(GdkEventKey* key_event) override;

    double _scale;
    PickerGeometry *_picker_geometry;
    std::vector<guint32> _buffer_polygon;
    Cairo::RefPtr<::Cairo::ImageSurface> _surface_polygon;
    int _cache_width, _cache_height;
    int _square_size;
};

} // namespace Widget
} // namespace UI
} // namespace Inkscape

#endif // INK_COLORWHEEL_HSLUV_H