|
| 1 | +/* |
| 2 | + * Copyright (C) 2025 Linux Studio Plugins Project <https://lsp-plug.in/> |
| 3 | + * (C) 2025 Vladimir Sadovnikov <[email protected]> |
| 4 | + * |
| 5 | + * This file is part of lsp-tk-lib |
| 6 | + * Created on: 23 сент. 2025 г. |
| 7 | + * |
| 8 | + * lsp-tk-lib is free software: you can redistribute it and/or modify |
| 9 | + * it under the terms of the GNU Lesser General Public License as published by |
| 10 | + * the Free Software Foundation, either version 3 of the License, or |
| 11 | + * any later version. |
| 12 | + * |
| 13 | + * lsp-tk-lib is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + * GNU Lesser General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Lesser General Public License |
| 19 | + * along with lsp-tk-lib. If not, see <https://www.gnu.org/licenses/>. |
| 20 | + */ |
| 21 | + |
| 22 | +#ifndef LSP_PLUG_IN_TK_WIDGETS_SIMPLE_RANGESLIDER_H_ |
| 23 | +#define LSP_PLUG_IN_TK_WIDGETS_SIMPLE_RANGESLIDER_H_ |
| 24 | + |
| 25 | +#ifndef LSP_PLUG_IN_TK_IMPL |
| 26 | + #error "use <lsp-plug.in/tk/tk.h>" |
| 27 | +#endif /* LSP_PLUG_IN_TK_IMPL */ |
| 28 | + |
| 29 | +namespace lsp |
| 30 | +{ |
| 31 | + namespace tk |
| 32 | + { |
| 33 | + // Style definition |
| 34 | + namespace style |
| 35 | + { |
| 36 | + typedef struct RangeSliderColors |
| 37 | + { |
| 38 | + prop::Color sBtnColor; |
| 39 | + prop::Color sBtnBorderColor; |
| 40 | + prop::Color sScaleColor; |
| 41 | + prop::Color sScaleBorderColor; |
| 42 | + prop::Color sBalanceColor; |
| 43 | + |
| 44 | + void listener(tk::prop::Listener *listener); |
| 45 | + bool property_changed(Property *prop); |
| 46 | + } RangeSliderColors; |
| 47 | + |
| 48 | + enum RangeSliderColorState |
| 49 | + { |
| 50 | + RSLIDER_NORMAL = 0, |
| 51 | + RSLIDER_INACTIVE = 1 << 0, |
| 52 | + |
| 53 | + RSLIDER_TOTAL = 1 << 1 |
| 54 | + }; |
| 55 | + |
| 56 | + LSP_TK_STYLE_DEF_BEGIN(RangeSlider, Widget) |
| 57 | + RangeSliderColors vColors[RSLIDER_TOTAL]; |
| 58 | + |
| 59 | + prop::SizeRange sSizeRange; |
| 60 | + prop::Range sLimits; |
| 61 | + prop::Range sValues; |
| 62 | + prop::Float sDistance; |
| 63 | + prop::StepFloat sStep; |
| 64 | + prop::SizeRange sBtnWidth; |
| 65 | + prop::Float sBtnAspect; |
| 66 | + prop::Integer sAngle; |
| 67 | + prop::Integer sScaleWidth; |
| 68 | + prop::Integer sScaleBorder; |
| 69 | + prop::Integer sScaleRadius; |
| 70 | + prop::Boolean sScaleGradient; |
| 71 | + prop::Integer sBtnBorder; |
| 72 | + prop::Integer sBtnRadius; |
| 73 | + prop::Boolean sBtnGradient; |
| 74 | + prop::Pointer sBtnPointer; |
| 75 | + prop::Float sScaleBrightness; |
| 76 | + prop::Boolean sBalanceColorCustom; |
| 77 | + prop::Boolean sInvertMouseVScroll; |
| 78 | + LSP_TK_STYLE_DEF_END |
| 79 | + } |
| 80 | + |
| 81 | + /** |
| 82 | + * RangeSlider widget: a slider with two handles |
| 83 | + */ |
| 84 | + class RangeSlider: public Widget |
| 85 | + { |
| 86 | + public: |
| 87 | + static const w_class_t metadata; |
| 88 | + |
| 89 | + public: |
| 90 | + enum change_flags_t |
| 91 | + { |
| 92 | + CHANGE_MIN = 1 << 0, |
| 93 | + CHANGE_MAX = 1 << 1, |
| 94 | + CHANGE_BOTH = CHANGE_MIN | CHANGE_MAX |
| 95 | + }; |
| 96 | + |
| 97 | + protected: |
| 98 | + enum flags_t |
| 99 | + { |
| 100 | + F_BUTTON_MAX = 1 << 0, |
| 101 | + F_IGNORE = 1 << 1, |
| 102 | + F_PRECISION = 1 << 2, |
| 103 | + F_MOVER = 1 << 3 |
| 104 | + }; |
| 105 | + |
| 106 | + enum rslider_flags_t |
| 107 | + { |
| 108 | + RSLIDER_0 = style::RSLIDER_NORMAL, |
| 109 | + RSLIDER_1 = style::RSLIDER_INACTIVE, |
| 110 | + RSLIDER_TOTAL = style::RSLIDER_TOTAL |
| 111 | + }; |
| 112 | + |
| 113 | + protected: |
| 114 | + ssize_t nLastV; |
| 115 | + uint32_t nButtons; |
| 116 | + uint32_t nXFlags; |
| 117 | + float fButtonRange; |
| 118 | + float fLastValue; |
| 119 | + float fCurrValue; |
| 120 | + ws::rectangle_t vButtons[2]; |
| 121 | + ws::rectangle_t sHole; |
| 122 | + |
| 123 | + style::RangeSliderColors vColors[RSLIDER_TOTAL]; |
| 124 | + prop::SizeRange sSizeRange; |
| 125 | + prop::Range sLimits; |
| 126 | + prop::Range sValues; |
| 127 | + prop::Float sDistance; |
| 128 | + prop::StepFloat sStep; |
| 129 | + prop::SizeRange sBtnWidth; |
| 130 | + prop::Float sBtnAspect; |
| 131 | + prop::Integer sAngle; |
| 132 | + prop::Integer sScaleWidth; |
| 133 | + prop::Integer sScaleBorder; |
| 134 | + prop::Integer sScaleRadius; |
| 135 | + prop::Boolean sScaleGradient; |
| 136 | + prop::Integer sBtnBorder; |
| 137 | + prop::Integer sBtnRadius; |
| 138 | + prop::Boolean sBtnGradient; |
| 139 | + prop::Pointer sBtnPointer; |
| 140 | + prop::Float sScaleBrightness; |
| 141 | + prop::Boolean sBalanceColorCustom; |
| 142 | + prop::Boolean sInvertMouseVScroll; |
| 143 | + |
| 144 | + protected: |
| 145 | + void update_value(float min, float max, size_t flags); |
| 146 | + void add_values(float delta); |
| 147 | + void sync_button_pos(); |
| 148 | + style::RangeSliderColors *select_colors(); |
| 149 | + ws::rectangle_t *find_button(const ws::event_t *e); |
| 150 | + |
| 151 | + protected: |
| 152 | + static status_t slot_begin_edit(Widget *sender, void *ptr, void *data); |
| 153 | + static status_t slot_on_change(Widget *sender, void *ptr, void *data); |
| 154 | + static status_t slot_end_edit(Widget *sender, void *ptr, void *data); |
| 155 | + |
| 156 | + protected: |
| 157 | + virtual void size_request(ws::size_limit_t *r) override; |
| 158 | + virtual void property_changed(Property *prop) override; |
| 159 | + virtual void realize(const ws::rectangle_t *r) override; |
| 160 | + |
| 161 | + public: |
| 162 | + explicit RangeSlider(Display *dpy); |
| 163 | + RangeSlider(const RangeSlider &) = delete; |
| 164 | + RangeSlider(RangeSlider &&) = delete; |
| 165 | + virtual ~RangeSlider() override; |
| 166 | + RangeSlider & operator = (const RangeSlider &) = delete; |
| 167 | + RangeSlider & operator = (RangeSlider &&) = delete; |
| 168 | + |
| 169 | + virtual status_t init() override; |
| 170 | + |
| 171 | + public: |
| 172 | + LSP_TK_PROPERTY(Color, button_color, &vColors[RSLIDER_0].sBtnColor); |
| 173 | + LSP_TK_PROPERTY(Color, button_border_color, &vColors[RSLIDER_0].sBtnBorderColor); |
| 174 | + LSP_TK_PROPERTY(Color, scale_color, &vColors[RSLIDER_0].sScaleColor); |
| 175 | + LSP_TK_PROPERTY(Color, scale_border_color, &vColors[RSLIDER_0].sScaleBorderColor); |
| 176 | + LSP_TK_PROPERTY(Color, balance_color, &vColors[RSLIDER_0].sBalanceColor); |
| 177 | + LSP_TK_PROPERTY(Color, inactive_button_color, &vColors[RSLIDER_1].sBtnColor); |
| 178 | + LSP_TK_PROPERTY(Color, inactive_button_border_color, &vColors[RSLIDER_1].sBtnBorderColor); |
| 179 | + LSP_TK_PROPERTY(Color, inactive_scale_color, &vColors[RSLIDER_1].sScaleColor); |
| 180 | + LSP_TK_PROPERTY(Color, inactive_scale_border_color, &vColors[RSLIDER_1].sScaleBorderColor); |
| 181 | + LSP_TK_PROPERTY(Color, inactive_balance_color, &vColors[RSLIDER_1].sBalanceColor); |
| 182 | + |
| 183 | + LSP_TK_PROPERTY(SizeRange, size, &sSizeRange); |
| 184 | + LSP_TK_PROPERTY(Range, limits, &sLimits); |
| 185 | + LSP_TK_PROPERTY(Range, values, &sValues); |
| 186 | + LSP_TK_PROPERTY(Float, distance, &sDistance); |
| 187 | + LSP_TK_PROPERTY(StepFloat, step, &sStep); |
| 188 | + LSP_TK_PROPERTY(SizeRange, button_width, &sBtnWidth); |
| 189 | + LSP_TK_PROPERTY(Float, button_aspect, &sBtnAspect); |
| 190 | + LSP_TK_PROPERTY(Pointer, button_pointer, &sBtnPointer); |
| 191 | + LSP_TK_PROPERTY(Integer, angle, &sAngle); |
| 192 | + LSP_TK_PROPERTY(Integer, scale_width, &sScaleWidth); |
| 193 | + LSP_TK_PROPERTY(Integer, scale_border, &sScaleBorder); |
| 194 | + LSP_TK_PROPERTY(Integer, scale_radius, &sScaleRadius); |
| 195 | + LSP_TK_PROPERTY(Boolean, scale_gradient, &sScaleGradient); |
| 196 | + LSP_TK_PROPERTY(Integer, button_border, &sBtnBorder); |
| 197 | + LSP_TK_PROPERTY(Integer, button_radius, &sBtnRadius); |
| 198 | + LSP_TK_PROPERTY(Boolean, button_gradient, &sBtnGradient); |
| 199 | + LSP_TK_PROPERTY(Float, scale_brightness, &sScaleBrightness); |
| 200 | + LSP_TK_PROPERTY(Boolean, balance_color_custom, &sBalanceColorCustom); |
| 201 | + LSP_TK_PROPERTY(Boolean, invert_mouse_vscroll, &sInvertMouseVScroll); |
| 202 | + |
| 203 | + public: |
| 204 | + virtual status_t on_mouse_down(const ws::event_t *e) override; |
| 205 | + virtual status_t on_mouse_up(const ws::event_t *e) override; |
| 206 | + virtual status_t on_mouse_move(const ws::event_t *e) override; |
| 207 | + virtual status_t on_mouse_scroll(const ws::event_t *e) override; |
| 208 | + virtual status_t on_mouse_pointer(pointer_event_t *e) override; |
| 209 | + virtual void draw(ws::ISurface *s, bool force) override; |
| 210 | + |
| 211 | + public: |
| 212 | + virtual status_t on_begin_edit(); |
| 213 | + virtual status_t on_change(size_t flags); |
| 214 | + virtual status_t on_end_edit(); |
| 215 | + |
| 216 | + }; |
| 217 | + |
| 218 | + } /* namespace tk */ |
| 219 | +} /* namespace lsp */ |
| 220 | + |
| 221 | +#endif /* LSP_PLUG_IN_TK_WIDGETS_SIMPLE_RANGESLIDER_H_ */ |
0 commit comments