Skip to content

Commit d9f02e6

Browse files
committed
Added tk::Range property
1 parent fbd8e57 commit d9f02e6

File tree

4 files changed

+342
-1
lines changed

4 files changed

+342
-1
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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_PROP_MULTI_RANGE_H_
23+
#define LSP_PLUG_IN_TK_PROP_MULTI_RANGE_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+
/**
34+
* Floating-point range property
35+
*/
36+
class Range: public MultiProperty
37+
{
38+
protected:
39+
enum property_t
40+
{
41+
P_VALUE,
42+
P_MIN,
43+
P_MAX,
44+
45+
P_COUNT
46+
};
47+
48+
enum flags_t
49+
{
50+
F_RANGE_LOCK = 1 << 0
51+
};
52+
53+
protected:
54+
static const prop::desc_t DESC[];
55+
56+
protected:
57+
atom_t vAtoms[P_COUNT]; // Atom bindings
58+
float fMin;
59+
float fMax;
60+
size_t nFlags;
61+
float_transform_t pTransform;
62+
mutable void *pTransformArg;
63+
64+
protected:
65+
virtual void push() override;
66+
virtual void commit(atom_t property) override;
67+
68+
float do_limit(float v) const;
69+
float transform(float v) const;
70+
71+
protected:
72+
explicit Range(prop::Listener *listener = NULL);
73+
Range(const Range &) = delete;
74+
Range(Range &&) = delete;
75+
virtual ~Range() override;
76+
77+
Range & operator = (const Range &) = delete;
78+
Range & operator = (Range &&) = delete;
79+
80+
public:
81+
inline void set_transform(float_transform_t func, void *arg = NULL) { pTransform = func; pTransformArg = arg; }
82+
inline void clear_transform() { set_transform(NULL, NULL); }
83+
84+
public:
85+
inline float min() const { return fMin; }
86+
inline float max() const { return fMax; }
87+
inline float range() const { return fMax - fMin; }
88+
inline float abs_range() const { return (fMax > fMin) ? fMax - fMin : fMin - fMax; }
89+
inline bool range_locked() const { return nFlags & F_RANGE_LOCK; }
90+
91+
float set_min(float v);
92+
float set_max(float v);
93+
void set(float min, float max);
94+
95+
float get_normalized(float value) const { return Property::normalized(value, fMin, fMax); }
96+
static inline float limit(float value, float min, float max) { return Property::limit(value, min, max); }
97+
inline float limit(float v) const { return Property::limit(v, fMin, fMax); }
98+
static inline bool matches(float v, float min, float max) { return Property::matches(v, min, max); }
99+
inline bool matches(float v) const { return Property::matches(v, fMin, fMax); }
100+
};
101+
102+
namespace prop
103+
{
104+
/**
105+
* Range property implementation
106+
*/
107+
class Range: public tk::Range
108+
{
109+
public:
110+
explicit Range(prop::Listener *listener = NULL): tk::Range(listener) {};
111+
Range(const Range &) = delete;
112+
Range(Range &&) = delete;
113+
114+
Range & operator = (const Range &) = delete;
115+
Range & operator = (Range &&) = delete;
116+
117+
public:
118+
bool lock_range(bool lock = true);
119+
inline bool unlock_range() { return lock_range(false); }
120+
float set_min(float v);
121+
float set_max(float v);
122+
void set(float min, float max);
123+
124+
/**
125+
* Bind property with specified name to the style of linked widget
126+
*/
127+
inline status_t bind(atom_t property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
128+
inline status_t bind(const char *property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
129+
inline status_t bind(const LSPString *property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
130+
131+
/**
132+
* Unbind property
133+
*/
134+
inline status_t unbind() { return tk::Range::unbind(vAtoms, DESC, &sListener); };
135+
};
136+
137+
} /* namespace prop */
138+
} /* namespace tk */
139+
} /* namespace lsp */
140+
141+
142+
#endif /* INCLUDE_LSP_PLUG_IN_TK_PROP_MULTI_RANGE_H_ */

include/lsp-plug.in/tk/tk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#include <lsp-plug.in/tk/prop/multi/Padding.h>
9494
#include <lsp-plug.in/tk/prop/multi/Point2D.h>
9595
#include <lsp-plug.in/tk/prop/multi/Position.h>
96+
#include <lsp-plug.in/tk/prop/multi/Range.h>
9697
#include <lsp-plug.in/tk/prop/multi/RangeFloat.h>
9798
#include <lsp-plug.in/tk/prop/multi/Rectangle.h>
9899
#include <lsp-plug.in/tk/prop/multi/Shortcut.h>

src/main/prop/multi/Range.cpp

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
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+
23+
#include <lsp-plug.in/tk/tk.h>
24+
#include <lsp-plug.in/stdlib/locale.h>
25+
#include <lsp-plug.in/stdlib/math.h>
26+
27+
namespace lsp
28+
{
29+
namespace tk
30+
{
31+
const prop::desc_t Range::DESC[] =
32+
{
33+
{ "", PT_STRING },
34+
{ ".min", PT_FLOAT },
35+
{ ".max", PT_FLOAT },
36+
{ NULL, PT_UNKNOWN }
37+
};
38+
39+
Range::Range(prop::Listener *listener):
40+
MultiProperty(vAtoms, P_COUNT, listener)
41+
{
42+
fMin = 0.0f;
43+
fMax = 1.0f;
44+
nFlags = 0;
45+
pTransform = NULL;
46+
pTransformArg = NULL;
47+
}
48+
49+
Range::~Range()
50+
{
51+
MultiProperty::unbind(vAtoms, DESC, &sListener);
52+
}
53+
54+
void Range::commit(atom_t property)
55+
{
56+
LSPString s;
57+
float v;
58+
if (!(nFlags & F_RANGE_LOCK))
59+
{
60+
if ((property == vAtoms[P_MIN]) && (pStyle->get_float(vAtoms[P_MIN], &v) == STATUS_OK))
61+
fMin = v;
62+
if ((property == vAtoms[P_MAX]) && (pStyle->get_float(vAtoms[P_MAX], &v) == STATUS_OK))
63+
fMax = v;
64+
}
65+
66+
// Compound property
67+
if ((property == vAtoms[P_VALUE]) && (pStyle->get_string(vAtoms[P_VALUE], &s) == STATUS_OK))
68+
{
69+
float v[2];
70+
size_t n = Property::parse_floats(v, 2, &s);
71+
switch (n)
72+
{
73+
case 1:
74+
fMin = v[0];
75+
fMax = v[0];
76+
break;
77+
case 2:
78+
fMin = v[0];
79+
fMax = v[1];
80+
break;
81+
default:
82+
break;
83+
}
84+
}
85+
}
86+
87+
void Range::push()
88+
{
89+
LSPString s;
90+
91+
// Simple components
92+
if (vAtoms[P_MIN] >= 0)
93+
pStyle->set_float(vAtoms[P_MIN], fMin);
94+
if (vAtoms[P_MAX] >= 0)
95+
pStyle->set_float(vAtoms[P_MAX], fMax);
96+
97+
// Compound properties
98+
SET_LOCALE_SCOPED(LC_NUMERIC, "C");
99+
s.fmt_ascii("%.10f %.10f", fMin, fMax);
100+
if (vAtoms[P_VALUE] >= 0)
101+
pStyle->set_string(vAtoms[P_VALUE], &s);
102+
}
103+
104+
float Range::set_min(float value)
105+
{
106+
float old = fMin;
107+
if ((nFlags & F_RANGE_LOCK) || (value == old))
108+
return old;
109+
110+
fMin = value;
111+
sync();
112+
return old;
113+
}
114+
115+
float Range::set_max(float value)
116+
{
117+
float old = fMax;
118+
if ((nFlags & F_RANGE_LOCK) || (value == old))
119+
return old;
120+
121+
fMax = value;
122+
sync();
123+
return old;
124+
}
125+
126+
void Range::set(float min, float max)
127+
{
128+
if (nFlags & F_RANGE_LOCK)
129+
return;
130+
if ((min == fMin) &&
131+
(max == fMax))
132+
return;
133+
134+
fMin = min;
135+
fMax = max;
136+
sync();
137+
}
138+
139+
float Range::transform(float v) const
140+
{
141+
return (pTransform != NULL) ? pTransform(v, pTransformArg) : v;
142+
}
143+
144+
float Range::do_limit(float value) const
145+
{
146+
value = transform(value);
147+
return Property::limit(value, fMin, fMax);
148+
}
149+
150+
namespace prop
151+
{
152+
bool Range::lock_range(bool lock)
153+
{
154+
bool prev = nFlags & F_RANGE_LOCK;
155+
nFlags = lsp_setflag(nFlags, F_RANGE_LOCK, lock);
156+
return prev;
157+
}
158+
159+
float Range::set_min(float value)
160+
{
161+
float old = fMin;
162+
if (value == old)
163+
return old;
164+
165+
fMin = value;
166+
sync();
167+
return old;
168+
}
169+
170+
float Range::set_max(float value)
171+
{
172+
float old = fMax;
173+
if (value == old)
174+
return old;
175+
176+
fMax = value;
177+
sync();
178+
return old;
179+
}
180+
181+
void Range::set(float min, float max)
182+
{
183+
if ((min == fMin) &&
184+
(max == fMax))
185+
return;
186+
187+
fMin = min;
188+
fMax = max;
189+
sync();
190+
}
191+
} /* namespace prop */
192+
} /* namespace tk */
193+
} /* namespace lsp */
194+
195+
196+
197+
198+

src/main/prop/multi/RangeFloat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ namespace lsp
283283
bool RangeFloat::lock_range(bool lock)
284284
{
285285
bool prev = nFlags & F_RANGE_LOCK;
286-
nFlags = lsp_setflag(nFlags, F_AUTO_LIMIT, lock);
286+
nFlags = lsp_setflag(nFlags, F_RANGE_LOCK, lock);
287287
return prev;
288288
}
289289

0 commit comments

Comments
 (0)