Skip to content

Commit 05fc46b

Browse files
committed
ui: add Plate class
1 parent 7a501c4 commit 05fc46b

File tree

7 files changed

+216
-41
lines changed

7 files changed

+216
-41
lines changed

blocks/constellation.cpp

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,16 @@ int main(int argc, char* argv[]) {
141141
} },
142142
});
143143

144+
ui::Plate plate;
145+
144146
while (!wnd->closed()) {
145147
buffer_lock.lock();
146148
std::copy(buf.begin(), buf.end(), local_buf.begin());
147149
buffer_lock.unlock();
148150

149151
auto focused = wnd->focused();
150152

151-
wnd->update(nk_rgb_f(0.05, 0.07, 0.05), [&local_buf,&v=view,&grid,mouse,focused](NVGcontext* vg, int width, int height) {
152-
std::ostringstream fmt;
153-
fmt << std::defaultfloat;
154-
153+
wnd->update(nk_rgb_f(0.05, 0.07, 0.05), [&local_buf,&v=view,&grid,&plate,mouse,focused](NVGcontext* vg, int width, int height) {
155154
bool showCursor = focused && (mouse.x > 0 && mouse.x < width)
156155
&& (mouse.y > 0 && mouse.y < height);
157156

@@ -160,6 +159,8 @@ int main(int argc, char* argv[]) {
160159
grid.draw(vg, view);
161160

162161
// draw constellation
162+
nvgSave(vg);
163+
163164
view.apply(vg);
164165

165166
nvgFillColor(vg, nvgRGB(80, 208, 80));
@@ -170,10 +171,10 @@ int main(int argc, char* argv[]) {
170171
}
171172
nvgFill(vg);
172173

174+
nvgRestore(vg);
175+
173176
// draw cursor
174177
if (showCursor) {
175-
nvgResetTransform(vg);
176-
177178
nvgStrokeColor(vg, nvgRGBf(1.0f, 1.0f, 1.0f));
178179

179180
nvgBeginPath(vg);
@@ -191,33 +192,15 @@ int main(int argc, char* argv[]) {
191192

192193
std::string label = ui::format(coord.x, pixel_mag.x) +
193194
((coord.y < 0) ? "-" : "+") + "j" +
194-
ui::format(coord.y, pixel_mag.y);
195+
ui::format(std::abs(coord.y), pixel_mag.y);
195196

196197
bool left = (width - mouse.x < 100),
197198
bottom = (mouse.y < 50);
198199

199-
nvgTextAlign(vg, (left ? NVG_ALIGN_RIGHT : NVG_ALIGN_LEFT) |
200-
(bottom ? NVG_ALIGN_TOP : NVG_ALIGN_BOTTOM));
201-
202-
float bounds[4];
203-
nvgTextBounds(vg,
204-
mouse.x + (left ? -10 : 10), mouse.y + (bottom ? 10 : -10),
205-
label.c_str(), nullptr, bounds);
206-
float label_width = bounds[2] - bounds[0];
207-
float label_height = bounds[3] - bounds[1];
200+
int align = (left ? NVG_ALIGN_RIGHT : NVG_ALIGN_LEFT) |
201+
(bottom ? NVG_ALIGN_TOP : NVG_ALIGN_BOTTOM);
208202

209-
// Text background, for readability
210-
nvgFillColor(vg, nvgRGBAf(0.0f, 0.0f, 0.0f, 0.5f));
211-
nvgBeginPath(vg);
212-
nvgRoundedRect(vg,
213-
mouse.x + (left ? -15-label_width : 5), mouse.y + (bottom ? 5 : -15 - label_height),
214-
label_width + 10, label_height + 10, 3);
215-
nvgFill(vg);
216-
217-
nvgFillColor(vg, nvgRGBf(1.0f, 1.0f, 1.0f));
218-
nvgText(vg,
219-
mouse.x + (left ? -10 : 10), mouse.y + (bottom ? 10 : -10),
220-
label.c_str(), nullptr);
203+
plate.draw(vg, label, align, mouse);
221204
}
222205
}, [&view,&mouse](nk_context* ctx, int width, int height) {
223206
view.zoom(ctx->input.mouse.scroll_delta.y);

include/sdr/ui/plate.hpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* sdr - software-defined radio building blocks for unix pipes
3+
* Copyright (C) 2017 Fabio Massaioli
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#pragma once
20+
21+
#include "string_view.hpp"
22+
#include "view.hpp"
23+
24+
namespace sdr { namespace ui
25+
{
26+
27+
struct PlateStyle {
28+
float padding = 5.0f;
29+
float margin = 5.0f;
30+
NVGcolor fg = nvgRGBf(1.0f, 1.0f, 1.0f);
31+
NVGcolor bg = nvgRGBAf(0.0f, 0.0f, 0.0f, 0.5f);
32+
float radius = 3.0f;
33+
};
34+
35+
class Plate {
36+
public:
37+
Plate(int a = NVG_ALIGN_LEFT | NVG_ALIGN_TOP, Vec2 p = { 0.0f, 0.0f })
38+
: align(a), pos(p)
39+
{}
40+
41+
Plate(PlateStyle s,
42+
int a = NVG_ALIGN_LEFT | NVG_ALIGN_TOP, Vec2 p = { 0.0f, 0.0f })
43+
: style(s), align(a), pos(p)
44+
{}
45+
46+
Plate(StringView l,
47+
int a = NVG_ALIGN_LEFT | NVG_ALIGN_TOP, Vec2 p = { 0.0f, 0.0f })
48+
: label(l.to_string()), align(a), pos(p)
49+
{}
50+
51+
Plate(StringView l, PlateStyle s,
52+
int a = NVG_ALIGN_LEFT | NVG_ALIGN_TOP, Vec2 p = { 0.0f, 0.0f })
53+
: label(l.to_string()), style(s), align(a), pos(p)
54+
{}
55+
56+
// Use default values
57+
void draw(NVGcontext* vg) const {
58+
draw(vg, label, align, pos);
59+
}
60+
61+
// Change position
62+
void draw(NVGcontext* vg, Vec2 p) const {
63+
draw(vg, label, align, p);
64+
}
65+
66+
// Change alignment
67+
void draw(NVGcontext* vg, int a) const {
68+
draw(vg, label, a, pos);
69+
}
70+
71+
// Change alignment and position
72+
void draw(NVGcontext* vg, int a, Vec2 p) const {
73+
draw(vg, label, a, p);
74+
}
75+
76+
// Change label
77+
void draw(NVGcontext* vg, StringView l) const {
78+
draw(vg, l, align, pos);
79+
}
80+
81+
// Change label and position
82+
void draw(NVGcontext* vg, StringView l, Vec2 p) const {
83+
draw(vg, l, align, p);
84+
}
85+
86+
// Change label and alignment
87+
void draw(NVGcontext* vg, StringView l, int a) const {
88+
draw(vg, l, a, pos);
89+
}
90+
91+
// Draw plate
92+
void draw(NVGcontext* vg, StringView l, int a, Vec2 p) const;
93+
94+
private:
95+
std::string label;
96+
PlateStyle style;
97+
int align;
98+
Vec2 pos;
99+
};
100+
101+
} /* namespace ui */ } /* namespace sdr */

include/sdr/ui/string_view.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* sdr - software-defined radio building blocks for unix pipes
3+
* Copyright (C) 2017 Fabio Massaioli
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#pragma once
20+
21+
#include <experimental/string_view>
22+
23+
namespace sdr { namespace ui
24+
{
25+
26+
using StringView = std::experimental::string_view;
27+
28+
} /* namespace ui */ } /* namespace sdr */

include/sdr/ui/ui.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@
2020

2121
#include "format.hpp"
2222
#include "grid.hpp"
23+
#include "plate.hpp"
24+
#include "string_view.hpp"
2325
#include "view.hpp"
2426
#include "window.hpp"

lib/ui/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ui_library = shared_library('sdr-ui',
1818
'ui.cpp',
1919
'grid.cpp',
20+
'plate.cpp',
2021
dependencies: [
2122
font_res,
2223
glad_lib,

lib/ui/plate.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* sdr - software-defined radio building blocks for unix pipes
3+
* Copyright (C) 2017 Fabio Massaioli
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "align.hpp"
20+
#include "plate.hpp"
21+
22+
using namespace sdr::ui;
23+
24+
void Plate::draw(NVGcontext* vg, StringView l, int a, Vec2 p) const {
25+
nvgSave(vg);
26+
27+
auto halign = detail::halign(a),
28+
valign = detail::valign(a);
29+
30+
// Baseline alignment is not supported
31+
if (valign & NVG_ALIGN_BASELINE)
32+
valign = NVG_ALIGN_BOTTOM;
33+
34+
float label_x =
35+
(halign & NVG_ALIGN_LEFT) ? p.x + style.margin + style.padding :
36+
(halign & NVG_ALIGN_RIGHT) ? p.x - style.margin - style.padding : p.x;
37+
float label_y =
38+
(valign & NVG_ALIGN_TOP) ? p.y + style.margin + style.padding :
39+
(valign & NVG_ALIGN_BOTTOM) ? p.y - style.margin - style.padding : p.y;
40+
41+
float bounds[4];
42+
nvgTextBounds(vg, label_x, label_y, l.begin(), l.end(), bounds);
43+
float label_width = std::abs(bounds[2] - bounds[0]);
44+
float label_height = std::abs(bounds[3] - bounds[1]);
45+
46+
float plate_width = label_width + 2*style.padding;
47+
float plate_height = label_height + 2*style.padding;
48+
49+
float plate_x =
50+
(halign & NVG_ALIGN_LEFT) ? p.x + style.margin :
51+
(halign & NVG_ALIGN_RIGHT) ? p.x - style.margin - plate_width : p.x - (plate_width/2);
52+
float plate_y =
53+
(valign & NVG_ALIGN_TOP) ? p.y + style.margin :
54+
(valign & NVG_ALIGN_BOTTOM) ? p.y - style.margin - plate_height : p.y - (plate_height/2);
55+
56+
nvgFillColor(vg, style.bg);
57+
nvgBeginPath(vg);
58+
nvgRoundedRect(vg, plate_x, plate_y, plate_width, plate_height, style.radius);
59+
nvgFill(vg);
60+
61+
nvgFillColor(vg, style.fg);
62+
nvgTextAlign(vg, halign | valign);
63+
nvgText(vg, label_x, label_y, l.begin(), l.end());
64+
65+
nvgRestore(vg);
66+
}

lib/ui/ui_test.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <algorithm>
2424
#include <iostream>
2525
#include <limits>
26-
#include <sstream>
2726

2827
using namespace sdr;
2928

@@ -38,23 +37,21 @@ int main() {
3837
int avgCount = 5;
3938
float scale = 50.0f;
4039

41-
std::ostringstream formatter;
42-
4340
std::string fps = "FPS: 0";
4441
std::size_t frames = 0;
4542
double lastTime = 0;
4643

4744
bool mpressed = false;
4845
bool prevShowLine = false;
4946

47+
ui::Plate plate;
48+
5049
while (!wnd->closed()) {
5150
auto time = glfwGetTime();
5251
++frames;
5352

5453
if (time - lastTime >= 0.5) {
55-
formatter.str("");
56-
formatter << "FPS: " << frames * 2;
57-
fps = formatter.str();
54+
fps = "FPS: " + ui::format(frames * 2);
5855
frames = 0;
5956
lastTime += 0.5;
6057
}
@@ -67,7 +64,7 @@ int main() {
6764
my > 0 && my < wSize.second &&
6865
wnd->focused());
6966

70-
wnd->update([&formatter,avgCount,scale,fps,mx,my,showLine](NVGcontext* vg, int width, int height) {
67+
wnd->update([avgCount,scale,fps,&plate,mx,my,showLine](NVGcontext* vg, int width, int height) {
7168
nvgFillColor(vg, nvgRGBf(1.0f, 1.0f, 1.0f));
7269
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
7370
nvgText(vg, 10, 10, fps.c_str(), NULL);
@@ -84,12 +81,9 @@ int main() {
8481
nvgLineTo(vg, mx, height);
8582
nvgStroke(vg);
8683

87-
formatter.str("");
88-
formatter << mx;
89-
90-
nvgFillColor(vg, nvgRGBf(1.0f, 1.0f, 1.0f));
91-
nvgTextAlign(vg, ((width - mx < 100) ? NVG_ALIGN_RIGHT : NVG_ALIGN_LEFT) | NVG_ALIGN_MIDDLE);
92-
nvgText(vg, mx + ((width - mx < 100) ? -10 : 10), my, formatter.str().c_str(), NULL);
84+
plate.draw(vg, ui::format(mx),
85+
((width - mx < 100) ? NVG_ALIGN_RIGHT : NVG_ALIGN_LEFT) | NVG_ALIGN_MIDDLE,
86+
{ float(mx), float(my) });
9387
}
9488
}, [&avgCount,&scale,mx,prevShowLine,showLine,&mpressed](nk_context* ctx, int width, int height) {
9589
if (prevShowLine && showLine) {

0 commit comments

Comments
 (0)