1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 11 окт. 2019 г.
7  *
8  * lsp-plugins 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-plugins 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-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef UI_TK_LSPSCROLLBOX_H_
23 #define UI_TK_LSPSCROLLBOX_H_
24 
25 namespace lsp
26 {
27     namespace tk
28     {
29         class LSPScrollBox: public LSPWidgetContainer
30         {
31             public:
32                 static const w_class_t    metadata;
33 
34             protected:
35                 typedef struct cell_t
36                 {
37                     size_request_t      r;      // Required space
38                     realize_t           a;      // Allocated space
39                     realize_t           s;      // Really used space
40                     padding_t           p;      // Padding
41                     LSPWidget          *pWidget;
42                 } cell_t;
43 
44                 typedef struct allocation_t
45                 {
46                     ssize_t             aw;     // Area width
47                     ssize_t             ah;     // Area height
48                     bool                hs;     // horizontal scroll enabled
49                     bool                vs;     // Vertical scroll enabled
50                     size_request_t      r;      // Actual size request
51                 } allocation_t;
52 
53                 enum box_flags_t
54                 {
55                     BF_PROPORTIONAL     = 1 << 0,
56                     BF_HSCROLL          = 1 << 1,
57                     BF_VSCROLL          = 1 << 2
58                 };
59 
60             protected:
61                 cstorage<cell_t>    vItems;
62                 size_t              nSpacing;
63                 bool                bProportional;
64                 bool                bHSBypass;
65                 bool                bVSBypass;
66                 orientation_t       enOrientation;
67                 scrolling_t         enHScroll;
68                 scrolling_t         enVScroll;
69                 ssize_t             nAreaX;
70                 ssize_t             nAreaY;
71 
72                 LSPSizeConstraints  sConstraints;
73                 LSPScrollBar        sHBar;
74                 LSPScrollBar        sVBar;
75 
76             protected:
77                 static status_t     slot_on_scroll(LSPWidget *sender, void *ptr, void *data);
78 
79             protected:
80                 static inline bool  hidden_widget(const cell_t *w);
81                 size_t              visible_items();
82                 virtual LSPWidget  *find_widget(ssize_t x, ssize_t y);
83                 void                do_destroy();
84                 virtual void        estimate_allocation(allocation_t *alloc, const realize_t *realize);
85                 void                realize_children();
86 
87             public:
88                 explicit LSPScrollBox(LSPDisplay *dpy, bool horizontal = true);
89                 virtual ~LSPScrollBox();
90 
91                 virtual status_t init();
92 
93                 /** Destroy widget
94                  *
95                  */
96                 virtual void destroy();
97 
98             //---------------------------------------------------------------------------------
99             // Properties
100             public:
101 
102                 /** Get cell spacing
103                  *
104                  * @return cell spacing
105                  */
spacing()106                 inline size_t       spacing() const { return nSpacing; }
107 
108                 /** Get proportional flag
109                  *
110                  * @return proportional flag
111                  */
proportional()112                 inline bool         proportional() const { return bProportional; }
113 
114                 /** Check that orientation of the box is horizontal
115                  *
116                  * @return true if orientation of the box is horizontal
117                  */
horizontal()118                 inline bool         horizontal() const { return enOrientation == O_HORIZONTAL; }
119 
120                 /** Check that orientation of the box is vertical
121                  *
122                  * @return true if orientation of the box is vertical
123                  */
vertical()124                 inline bool         vertical() const { return enOrientation == O_VERTICAL; }
125 
126                 /**
127                  * Get size constraints
128                  * @return size constraints
129                  */
constraints()130                 inline LSPSizeConstraints  *constraints()   { return &sConstraints; }
131 
132                 /** Get box orientation
133                  *
134                  * @return box orientation
135                  */
orientation()136                 inline orientation_t    orientation() const { return enOrientation; }
137 
vscroll()138                 inline scrolling_t      vscroll() const         { return enVScroll; }
vscroll_bypass()139                 inline float            vscroll_bypass() const  { return bVSBypass; }
vscroll_pos()140                 inline float            vscroll_pos() const     { return sVBar.value(); }
vscroll_min()141                 inline float            vscroll_min() const     { return sVBar.min_value(); }
vscroll_max()142                 inline float            vscroll_max() const     { return sVBar.max_value(); }
vscroll_on()143                 inline float            vscroll_on() const      { return sVBar.visible(); }
144 
hscroll()145                 inline scrolling_t      hscroll() const         { return enHScroll; }
hscroll_bypass()146                 inline float            hscroll_bypass() const  { return bHSBypass; }
hscroll_pos()147                 inline float            hscroll_pos() const     { return sHBar.value(); }
hscroll_min()148                 inline float            hscroll_min() const     { return sHBar.min_value(); }
hscroll_max()149                 inline float            hscroll_max() const     { return sHBar.max_value(); }
hscroll_on()150                 inline bool             hscroll_on() const      { return sHBar.visible(); }
151 
152             //---------------------------------------------------------------------------------
153             // Manipulation
154             public:
155                 /** Set box spacing
156                  *
157                  * @param value box spacing
158                  */
159                 void        set_spacing(size_t value);
160 
161                 /** Set proportional flag
162                  *
163                  * @param value proportional flag
164                  */
165                 void        set_proportional(bool value);
166 
167                 /** Set orientation of the box
168                  *
169                  * @param value orientation
170                  */
171                 void        set_orientation(orientation_t value);
172 
173                 /**
174                  * Set vertical scrolling mode
175                  * @param mode scrolling mode
176                  */
177                 void        set_vscroll(scrolling_t mode);
178 
179                 /**
180                  * Set vertical scrolling
181                  * @param value the vertical scrolling value in pixels
182                  */
set_vscroll_pos(float value)183                 void        set_vscroll_pos(float value) { sVBar.set_value(value); }
184 
185                 /**
186                  * Set bypass of vertical scrolling events
187                  * @param value vertical scrolling events bypass
188                  */
189                 void        set_vscroll_bypass(bool bypass = true) { bVSBypass = bypass; }
190 
191                 /**
192                  * Set horizontal scrolling mode
193                  * @param mode scrolling mode
194                  */
195                 void        set_hscroll(scrolling_t mode);
196 
197                 /**
198                  * Set horizontal scrolling
199                  * @param value horizontal scrolling value in pixels
200                  */
set_hscroll_pos(float value)201                 void        set_hscroll_pos(float value) { sHBar.set_value(value); }
202 
203                 /**
204                  * Set bypass of horizontal scrolling events
205                  * @param value horizontal scrolling events bypass
206                  */
207                 void        set_hscroll_bypass(bool bypass = true) { bHSBypass = bypass; }
208 
209                 /** Set horizontal orientation
210                  *
211                  * @param value horizontal orientation flag
212                  */
213                 inline void         set_horizontal(bool value = true)   { set_orientation((value) ? O_HORIZONTAL : O_VERTICAL); }
214 
215                 /** Set vertical orientation
216                  *
217                  * @param value vertical orientation flag
218                  */
219                 inline void         set_vertical(bool value = true)     { set_orientation((value) ? O_VERTICAL : O_HORIZONTAL); }
220 
221                 /** render widget
222                  *
223                  * @param s surface
224                  * @param force force flag
225                  */
226                 virtual void render(ISurface *s, bool force);
227 
228                 /** Add widget
229                  *
230                  * @param widget widget to add
231                  * @return status of operation
232                  */
233                 virtual status_t add(LSPWidget *widget);
234 
235                 /** Remove widget
236                  *
237                  * @param child widget to remove
238                  * @return status of operation
239                  */
240                 virtual status_t remove(LSPWidget *child);
241 
242                 /** Remove all widgets
243                  *
244                  * @return status of operation
245                  */
246                 virtual status_t    remove_all();
247 
248                 /** Realize the widget
249                  *
250                  * @param r realization structure
251                  */
252                 virtual void realize(const realize_t *r);
253 
254                 /** Size request of the widget
255                  *
256                  * @param r size request
257                  */
258                 virtual void size_request(size_request_t *r);
259 
260                 virtual status_t    handle_event(const ws_event_t *e);
261         };
262 
263     } /* namespace tk */
264 } /* namespace lsp */
265 
266 #endif /* UI_TK_LSPSCROLLABLEBOX_H_ */
267