Skip to content

Commit 01bbc7a

Browse files
committed
Release 1.0.30
* Implemented new tk::RangeSlider widget. * Implemented new tk::PianoKeys widget. * Implemented new tk::Embed widget for embedding into graph widget. * Fixed use after free for several scenarios when destroying the display. * Updated module versions in dependencies.
2 parents 03d1677 + 4383af7 commit 01bbc7a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+5089
-170
lines changed

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
* RECENT CHANGES
33
*******************************************************************************
44

5+
=== 1.0.30 ===
6+
* Implemented new tk::RangeSlider widget.
7+
* Implemented new tk::PianoKeys widget.
8+
* Implemented new tk::Embed widget for embedding into graph widget.
9+
* Fixed use after free for several scenarios when destroying the display.
10+
* Updated module versions in dependencies.
11+
512
=== 1.0.29 ===
613
* Added text clipping function for tk::Label.
714
* Implemented AudioEnvelope widget and it's integration into AudioSample.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ The full list of provided widgets:
5555
* Graph - widget for rendering 2D graphical data (graphs and plots).
5656
* GraphAxis - axis on a graph widget.
5757
* GraphDot - dot on a graph widget.
58+
* GraphEmbed - special widget to embed widgets into graph widget, acts like Align but uses axis coordinates.
5859
* GraphFrameBuffer - frame buffer for drawing on the graph widget.
5960
* GraphLineSegment - grap line segment defined by two points.
6061
* GraphMarker - marker on the graph widget.
@@ -75,6 +76,7 @@ The full list of provided widgets:
7576
* MenuItem - menu item widget used by Menu widget.
7677
* ProgressBar - widget for displaying progress of some long lasting process.
7778
* RadioButton - rounded single on/off toggle.
79+
* RangeSlider - the slider with two tips that allows to set the range of values.
7880
* ScrollBar - single scroll bar.
7981
* Separator - separator widget to visually separate space allocated in widget containers.
8082
* Void - void widget which can be used for filling empty area.
@@ -88,6 +90,7 @@ The full list of provided widgets:
8890
* Fraction - music fraction with numerator and denominator.
8991
* LedMeter - led level/peak meter with multiple channels.
9092
* LedMeterChannel - single-channel level/peak meter.
93+
* PianoKeys - a piano key layout with ability to press keys and select key range.
9194

9295
## Styling system
9396

include/lsp-plug.in/tk/prop/collection/ColorRanges.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ namespace lsp
175175
* Unbind property
176176
*/
177177
inline status_t unbind() { return tk::ColorRanges::unbind(&sListener); };
178-
178+
inline void listener(prop::Listener *listener) { pListener = listener; }
179179
};
180180

181181
} /* namespace prop */
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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+
inline bool inversed() const { return fMin > fMax; }
91+
92+
float set_min(float v);
93+
float set_max(float v);
94+
void set(float min, float max);
95+
96+
float get_normalized(float value) const { return Property::normalized(value, fMin, fMax); }
97+
static inline float limit(float value, float min, float max) { return Property::limit(value, min, max); }
98+
inline float limit(float v) const { return Property::limit(v, fMin, fMax); }
99+
static inline bool matches(float v, float min, float max) { return Property::matches(v, min, max); }
100+
inline bool matches(float v) const { return Property::matches(v, fMin, fMax); }
101+
};
102+
103+
namespace prop
104+
{
105+
/**
106+
* Range property implementation
107+
*/
108+
class Range: public tk::Range
109+
{
110+
public:
111+
explicit Range(prop::Listener *listener = NULL): tk::Range(listener) {};
112+
Range(const Range &) = delete;
113+
Range(Range &&) = delete;
114+
115+
Range & operator = (const Range &) = delete;
116+
Range & operator = (Range &&) = delete;
117+
118+
public:
119+
bool lock_range(bool lock = true);
120+
inline bool unlock_range() { return lock_range(false); }
121+
float set_min(float v);
122+
float set_max(float v);
123+
void set(float min, float max);
124+
125+
/**
126+
* Bind property with specified name to the style of linked widget
127+
*/
128+
inline status_t bind(atom_t property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
129+
inline status_t bind(const char *property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
130+
inline status_t bind(const LSPString *property, Style *style) { return tk::Range::bind(property, style, vAtoms, DESC, &sListener); }
131+
132+
/**
133+
* Unbind property
134+
*/
135+
inline status_t unbind() { return tk::Range::unbind(vAtoms, DESC, &sListener); };
136+
};
137+
138+
} /* namespace prop */
139+
} /* namespace tk */
140+
} /* namespace lsp */
141+
142+
143+
#endif /* INCLUDE_LSP_PLUG_IN_TK_PROP_MULTI_RANGE_H_ */

include/lsp-plug.in/tk/prop/multi/SizeConstraints.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ namespace lsp
144144
static void scale(ws::size_limit_t *dst, float scale);
145145

146146
static bool match(const ws::rectangle_t *r, const ws::size_limit_t *sr);
147+
148+
static void transpose(ws::size_limit_t *r);
149+
static void transpose(ws::size_limit_t *dst, const ws::size_limit_t *src);
150+
static void transpose(ws::rectangle_t *r);
151+
static void transpose(ws::rectangle_t *dst, const ws::rectangle_t *src);
147152
};
148153

149154
namespace prop
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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: 27 сент. 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_SPECIFIC_NOTESTATE_H_
23+
#define LSP_PLUG_IN_TK_PROP_SPECIFIC_NOTESTATE_H_
24+
25+
#ifndef LSP_PLUG_IN_TK_IMPL
26+
#error "use <lsp-plug.in/tk/tk.h>"
27+
#endif
28+
29+
namespace lsp
30+
{
31+
namespace tk
32+
{
33+
class NoteState: public SimpleProperty
34+
{
35+
protected:
36+
static constexpr size_t NOTES_TOTAL = 128;
37+
static constexpr size_t NUM_BINS = NOTES_TOTAL / sizeof(umword_t);
38+
static constexpr size_t NUM_CHARS = NOTES_TOTAL / 4; // 4 bits per character
39+
static constexpr size_t NUM_BIN_CHARS = NUM_CHARS / NUM_BINS;
40+
static constexpr size_t BITS_PER_BIN = sizeof(umword_t) * 8;
41+
42+
static constexpr umword_t ALL_ZERO = umword_t(0);
43+
static constexpr umword_t ALL_ONES = ~umword_t(0);
44+
static constexpr umword_t ONE = umword_t(1);
45+
46+
protected:
47+
umword_t nState[NUM_BINS]; // State of all possible MIDI notes
48+
49+
protected:
50+
virtual void commit(atom_t property) override;
51+
virtual void push() override;
52+
53+
protected:
54+
static void deserialize(umword_t *dst, const char *src);
55+
static void deserialize(umword_t *dst, const lsp_wchar_t *src, size_t count);
56+
static void serialize(char *dst, const umword_t *src);
57+
58+
public:
59+
explicit NoteState(prop::Listener *listener);
60+
NoteState(const NoteState &) = delete;
61+
NoteState(NoteState &&) = delete;
62+
virtual ~NoteState() override;
63+
64+
NoteState & operator = (const NoteState &) = delete;
65+
NoteState & operator = (NoteState &&) = delete;
66+
67+
public:
68+
bool clear(size_t index);
69+
void clear_range(size_t first, size_t last);
70+
void clear_count(size_t first, size_t last);
71+
void clear_all();
72+
bool reset(size_t index);
73+
74+
bool set(size_t index);
75+
bool set(size_t index, bool on);
76+
void set_range(size_t first, size_t last);
77+
void set_count(size_t first, size_t last);
78+
void set_all();
79+
80+
bool toggle(size_t index);
81+
void toggle_range(size_t first, size_t last);
82+
void toggle_count(size_t first, size_t last);
83+
void toggle_all();
84+
85+
void set_state(const char *state);
86+
void set_state(const LSPString *state);
87+
bool get(size_t index) const;
88+
89+
bool all_set() const;
90+
bool all_unset() const;
91+
92+
void swap(NoteState *dst);
93+
void swap(NoteState &dst);
94+
};
95+
96+
namespace prop
97+
{
98+
class NoteState: public tk::NoteState
99+
{
100+
public:
101+
explicit inline NoteState(prop::Listener *listener = NULL): tk::NoteState(listener) {}
102+
NoteState(const NoteState &) = delete;
103+
NoteState(NoteState &&) = delete;
104+
105+
NoteState & operator = (const NoteState &) = delete;
106+
NoteState & operator = (NoteState &&) = delete;
107+
108+
public:
109+
inline status_t bind(atom_t property, Style *style) { return SimpleProperty::bind(property, style, PT_STRING, &sListener); }
110+
inline status_t bind(const char *property, Style *style) { return SimpleProperty::bind(property, style, PT_STRING, &sListener); }
111+
inline status_t bind(const LSPString *property, Style *style) { return SimpleProperty::bind(property, style, PT_STRING, &sListener); }
112+
113+
};
114+
115+
} /* namespace prop */
116+
} /* namespace tk */
117+
} /* namespace lsp */
118+
119+
120+
121+
122+
#endif /* LSP_PLUG_IN_TK_PROP_SPECIFIC_NOTESTATE_H_ */

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ namespace lsp
136136
Schema(Schema &&) = delete;
137137
virtual ~Schema();
138138

139+
void destroy();
140+
139141
Schema & operator = (const Schema &) = delete;
140142
Schema & operator = (Schema &&) = delete;
141143

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

Lines changed: 5 additions & 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>
@@ -117,6 +118,7 @@
117118
// Specific properties
118119
#include <lsp-plug.in/tk/prop/specific/GraphMeshData.h>
119120
#include <lsp-plug.in/tk/prop/specific/GraphFrameData.h>
121+
#include <lsp-plug.in/tk/prop/specific/NoteState.h>
120122

121123
// Styles and schemas
122124
#include <lsp-plug.in/tk/style/StyleSheet.h>
@@ -162,6 +164,7 @@
162164
#include <lsp-plug.in/tk/widgets/simple/MenuItem.h>
163165
#include <lsp-plug.in/tk/widgets/simple/ProgressBar.h>
164166
#include <lsp-plug.in/tk/widgets/simple/RadioButton.h>
167+
#include <lsp-plug.in/tk/widgets/simple/RangeSlider.h>
165168
#include <lsp-plug.in/tk/widgets/simple/ScrollBar.h>
166169
#include <lsp-plug.in/tk/widgets/simple/Separator.h>
167170
#include <lsp-plug.in/tk/widgets/simple/TabItem.h>
@@ -195,6 +198,7 @@
195198
#include <lsp-plug.in/tk/widgets/specific/Fraction.h>
196199
#include <lsp-plug.in/tk/widgets/specific/LedMeter.h>
197200
#include <lsp-plug.in/tk/widgets/specific/LedMeterChannel.h>
201+
#include <lsp-plug.in/tk/widgets/specific/PianoKeys.h>
198202

199203
// 3D rendering
200204
#include <lsp-plug.in/tk/widgets/3d/Area3D.h>
@@ -204,6 +208,7 @@
204208
#include <lsp-plug.in/tk/widgets/graph/Graph.h>
205209
#include <lsp-plug.in/tk/widgets/graph/GraphAxis.h>
206210
#include <lsp-plug.in/tk/widgets/graph/GraphDot.h>
211+
#include <lsp-plug.in/tk/widgets/graph/GraphEmbed.h>
207212
#include <lsp-plug.in/tk/widgets/graph/GraphFrameBuffer.h>
208213
#include <lsp-plug.in/tk/widgets/graph/GraphLineSegment.h>
209214
#include <lsp-plug.in/tk/widgets/graph/GraphMarker.h>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
#define LSP_TK_LIB_MAJOR 1
2626
#define LSP_TK_LIB_MINOR 0
27-
#define LSP_TK_LIB_MICRO 29
27+
#define LSP_TK_LIB_MICRO 30
2828

2929
#if defined(LSP_TK_LIB_PUBLISHER)
3030
#define LSP_TK_LIB_PUBLIC LSP_EXPORT_MODIFIER

0 commit comments

Comments
 (0)