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: 2 июл. 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 #include <ui/ctl/ctl.h>
23 
24 namespace lsp
25 {
26     namespace ctl
27     {
28         const ctl_class_t CtlProgressBar::metadata = { "CtlProgressBar", &CtlWidget::metadata };
29 
CtlProgressBar(CtlRegistry * src,LSPProgressBar * widget)30         CtlProgressBar::CtlProgressBar(CtlRegistry *src, LSPProgressBar *widget):
31             CtlWidget(src, widget)
32         {
33             pClass          = &metadata;
34             pPort           = NULL;
35             nXFlags         = 0;
36             sFormat.set_native("%.2f%%");
37         }
38 
~CtlProgressBar()39         CtlProgressBar::~CtlProgressBar()
40         {
41         }
42 
init()43         void CtlProgressBar::init()
44         {
45             CtlWidget::init();
46 
47             sMin.init(pRegistry, this);
48             sMax.init(pRegistry, this);
49             sValue.init(pRegistry, this);
50 
51             // Initialize color controllers
52             LSPProgressBar *bar = widget_cast<LSPProgressBar>(pWidget);
53             if (bar != NULL)
54             {
55                 sColor.init_hsl(pRegistry, bar, bar->color(), A_COLOR, A_HUE_ID, A_SAT_ID, A_LIGHT_ID);
56                 sScaleColor.init_hsl(pRegistry, bar, bar->sel_color(), A_SCALE_COLOR, A_SCALE_HUE_ID, A_SCALE_SAT_ID, A_SCALE_LIGHT_ID);
57                 sScaleColor.map_static_hsl(A_SCALE_HUE, -1, -1);
58             }
59         }
60 
set(widget_attribute_t att,const char * value)61         void CtlProgressBar::set(widget_attribute_t att, const char *value)
62         {
63             LSPProgressBar *bar = widget_cast<LSPProgressBar>(pWidget);
64 
65             switch (att)
66             {
67                 case A_WIDTH:
68                     if (bar != NULL)
69                         PARSE_INT(value, bar->set_min_width(__));
70                     break;
71                 case A_HEIGHT:
72                     if (bar != NULL)
73                         PARSE_INT(value, bar->set_min_height(__));
74                     break;
75                 case A_MIN:
76                     BIND_EXPR(sMin, value);
77                     nXFlags |= XF_MIN;
78                     break;
79                 case A_MAX:
80                     BIND_EXPR(sMax, value);
81                     nXFlags |= XF_MAX;
82                     break;
83                 case A_VALUE:
84                     BIND_EXPR(sValue, value);
85                     nXFlags |= XF_VALUE;
86                     break;
87                 case A_ID:
88                     BIND_PORT(pRegistry, pPort, value);
89                     break;
90                 case A_FORMAT:
91                     sFormat.set_utf8(value);
92                     break;
93 
94                 default:
95                     sColor.set(att, value);
96                     sScaleColor.set(att, value);
97                     CtlWidget::set(att, value);
98                     break;
99             }
100         }
101 
sync_state(CtlPort * port,bool force)102         void CtlProgressBar::sync_state(CtlPort *port, bool force)
103         {
104             LSPProgressBar *bar = widget_cast<LSPProgressBar>(pWidget);
105             if (bar == NULL)
106                 return;
107 
108             if ((nXFlags & XF_MIN) && (sMin.valid()))
109             {
110                 if (bar->set_min_value(sMin.evaluate()))
111                     force   = true;
112             }
113             if ((nXFlags & XF_MAX) && (sMax.valid()))
114             {
115                 if (bar->set_max_value(sMax.evaluate()))
116                     force   = true;
117             }
118 
119             if ((nXFlags & XF_VALUE) && (sValue.valid()))
120             {
121                 if (bar->set_value(sValue.evaluate()))
122                     force   = true;
123             }
124             else if ((port == pPort) && (pPort != NULL))
125             {
126                 const port_t *meta = pPort->metadata();
127                 if ((!(nXFlags & XF_MIN)) && (meta->flags & F_LOWER))
128                     bar->set_min_value(meta->min);
129                 if ((!(nXFlags & XF_MAX)) && (meta->flags & F_UPPER))
130                     bar->set_max_value(meta->max);
131 
132                 if (bar->set_value(pPort->get_value()))
133                     force   = true;
134             }
135 
136             // Need to update text?
137             if (force)
138             {
139                 LSPString text;
140                 if (text.fmt_utf8(sFormat.get_utf8(), bar->get_value()))
141                     bar->set_text(&text);
142             }
143         }
144 
notify(CtlPort * port)145         void CtlProgressBar::notify(CtlPort *port)
146         {
147             sync_state(port, false);
148             CtlWidget::notify(port);
149         }
150 
end()151         void CtlProgressBar::end()
152         {
153             if (pPort != NULL)
154                 sync_metadata(pPort);
155 
156             sync_state(pPort, true);
157 
158             CtlWidget::end();
159         }
160 
sync_metadata(CtlPort * port)161         void CtlProgressBar::sync_metadata(CtlPort *port)
162         {
163             LSPProgressBar *bar = widget_cast<LSPProgressBar>(pWidget);
164 
165             if ((bar != NULL) && (port != NULL) && (pPort == port))
166             {
167                 const port_t *meta = pPort->metadata();
168                 if (meta != NULL)
169                 {
170                     if ((meta->flags & F_LOWER) && (!((nXFlags & XF_MIN) && (sMin.valid()))))
171                         bar->set_min_value(meta->min);
172                     if ((meta->flags & F_UPPER) && (!((nXFlags & XF_MAX) && (sMax.valid()))))
173                         bar->set_min_value(meta->min);
174                 }
175             }
176 
177             CtlWidget::sync_metadata(port);
178         }
179 
180     } /* namespace ctl */
181 } /* namespace lsp */
182