LCDGFX LCD display driver  1.2.0
Lightweight graphics library for SSD1306, SSD1325, SSD1327, SSD1331, SSD1351, SH1106, SH1107, IL9163, ST7735, ST7789, ILI9341, PCD8544 displays over I2C/SPI
slider.h
Go to the documentation of this file.
1 /*
2  MIT License
3 
4  Copyright (c) 2025, Alexey Dynda
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 */
28 #ifndef _LCDGFX_SLIDER_H_
29 #define _LCDGFX_SLIDER_H_
30 
31 #include "nano_gfx_types.h"
32 #include "canvas/point.h"
33 #include "canvas/rect.h"
34 
44 {
45  Horizontal,
46  Vertical,
47 };
48 
57 {
58 public:
69  LcdGfxSlider(const NanoRect &rect, int16_t minValue, int16_t maxValue, int16_t value, int16_t step = 1,
70  LcdGfxSliderOrientation orientation = LcdGfxSliderOrientation::Horizontal);
71 
77  template <typename D> void show(D &d)
78  {
79  uint16_t color = d.getColor();
80  if ( m_orientation == LcdGfxSliderOrientation::Horizontal )
81  {
82  // Find a page (8-row band) strictly between the top and bottom
83  // border rows. The 3 fillRects (black-left, knob, black-right)
84  // all live in this single page — full-byte writes per column —
85  // so the border lines (in other pages) are never touched.
86  const lcdint_t kPage = 8;
87  lcdint_t bandTop = (m_rect.p1.y + kPage) & ~(kPage - 1);
88  lcdint_t bandBot = (m_rect.p2.y & ~(kPage - 1)) - 1;
89  if ( bandBot < bandTop || bandBot >= m_rect.p2.y )
90  {
91  bandTop = m_rect.p1.y + 1;
92  bandBot = m_rect.p2.y - 1;
93  }
94  lcdint_t innerLeft = m_rect.p1.x + 1;
95  lcdint_t innerRight = m_rect.p2.x - 1;
96  lcdint_t innerW = innerRight - innerLeft - 2;
97  if ( innerW < 1 ) innerW = 1;
98  lcdint_t span = m_max - m_min;
99  lcdint_t knobX = innerLeft + 1 + (span > 0 ? (lcdint_t)(((int32_t)(m_value - m_min) * innerW) / span) : 0);
100  lcdint_t knobW = bandBot - bandTop + 1;
101  lcdint_t knobL = knobX - knobW / 2;
102  lcdint_t knobR = knobL + knobW - 1;
103  if ( knobL < innerLeft ) { knobL = innerLeft; knobR = knobL + knobW - 1; }
104  if ( knobR > innerRight ) { knobR = innerRight; knobL = knobR - knobW + 1; if ( knobL < innerLeft ) knobL = innerLeft; }
105 
106  d.setColor(0x0000);
107  if ( knobL > innerLeft )
108  {
109  d.fillRect(innerLeft, bandTop, knobL - 1, bandBot);
110  }
111  if ( knobR < innerRight )
112  {
113  d.fillRect(knobR + 1, bandTop, innerRight, bandBot);
114  }
115  d.setColor(color);
116  d.fillRect(knobL, bandTop, knobR, bandBot);
117  }
118  else
119  {
120  lcdint_t innerLeft = m_rect.p1.x + 1;
121  lcdint_t innerRight = m_rect.p2.x - 1;
122  lcdint_t innerTop = m_rect.p1.y + 1;
123  lcdint_t innerBot = m_rect.p2.y - 1;
124  lcdint_t innerH = innerBot - innerTop - 2;
125  if ( innerH < 1 ) innerH = 1;
126  lcdint_t span = m_max - m_min;
127  lcdint_t knobY = innerTop + 1 + (span > 0 ? (lcdint_t)(((int32_t)(m_value - m_min) * innerH) / span) : 0);
128  lcdint_t knobW = innerRight - innerLeft + 1;
129  lcdint_t knobH = knobW;
130  if ( knobH < 4 ) knobH = 4;
131  lcdint_t knobT = knobY - knobH / 2;
132  lcdint_t knobB = knobT + knobH - 1;
133  if ( knobT < innerTop ) { knobT = innerTop; knobB = knobT + knobH - 1; }
134  if ( knobB > innerBot ) { knobB = innerBot; knobT = knobB - knobH + 1; if ( knobT < innerTop ) knobT = innerTop; }
135 
136  d.setColor(0x0000);
137  if ( knobT > innerTop )
138  {
139  d.fillRect(innerLeft, innerTop, innerRight, knobT - 1);
140  }
141  if ( knobB < innerBot )
142  {
143  d.fillRect(innerLeft, knobB + 1, innerRight, innerBot);
144  }
145  d.setColor(color);
146  d.fillRect(innerLeft, knobT, innerRight, knobB);
147  }
148  d.drawRect(m_rect);
149  }
150 
154  void up();
155 
159  void down();
160 
164  void setValue(int16_t value);
165 
169  int16_t value() const
170  {
171  return m_value;
172  }
173 
177  int16_t minValue() const
178  {
179  return m_min;
180  }
181 
185  int16_t maxValue() const
186  {
187  return m_max;
188  }
189 
193  const NanoRect &getRect() const
194  {
195  return m_rect;
196  }
197 
198 private:
199  NanoRect m_rect;
200  int16_t m_min;
201  int16_t m_max;
202  int16_t m_value;
203  int16_t m_step;
204  LcdGfxSliderOrientation m_orientation;
205 };
206 
211 #endif
int16_t minValue() const
Returns the configured minimum.
Definition: slider.h:177
void show(D &d)
Renders the slider on the display.
Definition: slider.h:77
NanoRect structure describes rectangle area.
Definition: rect.h:42
Point class.
const NanoRect & getRect() const
Returns the rectangle area used by the slider.
Definition: slider.h:193
int8_t lcdint_t
internal int type, used by the library.
Definition: canvas_types.h:77
Rectangle class.
Basic structures of nano gfx library.
int16_t value() const
Returns the current value.
Definition: slider.h:169
int16_t maxValue() const
Returns the configured maximum.
Definition: slider.h:185
LcdGfxSliderOrientation
Orientation of the slider track.
Definition: slider.h:43
Class implements a value slider widget for lcdgfx library.
Definition: slider.h:56