tangled
alpha
login
or
join now
hjvt.dev
/
pcmg
0
fork
atom
PC Music Generator - a Virtual Modular Synthesizer
0
fork
atom
overview
issues
pulls
pipelines
Theming
Ivan Chinenov
2 years ago
91e9922c
90f48557
+204
-54
13 changed files
expand all
collapse all
unified
split
empty.yml
prefab_modules
gigas1.yml
moogsimple.yml
simpleout.yml
rack
src
graph
modules.rs
visuals.rs
widget_description.rs
widgets
connector
ports.rs
knob.rs
widgets.rs
rack-designer
src
app
state.rs
app.rs
src
pcmg_ui
module_adder.rs
+32
empty.yml
reviewed
···
1
1
+
uuid: fb3e046d-c883-4c5f-b36e-3d5c6c8fbe26
2
2
+
name: ''
3
3
+
theme:
4
4
+
highlight_color:
5
5
+
- 255
6
6
+
- 255
7
7
+
- 255
8
8
+
- 255
9
9
+
midtone_color:
10
10
+
- 160
11
11
+
- 160
12
12
+
- 160
13
13
+
- 255
14
14
+
lowlight_color:
15
15
+
- 96
16
16
+
- 96
17
17
+
- 96
18
18
+
- 255
19
19
+
accent_color:
20
20
+
- 255
21
21
+
- 215
22
22
+
- 0
23
23
+
- 255
24
24
+
text_color:
25
25
+
- 160
26
26
+
- 160
27
27
+
- 160
28
28
+
- 255
29
29
+
size: U1
30
30
+
visuals: {}
31
31
+
devices: {}
32
32
+
connections: {}
+27
prefab_modules/gigas1.yml
reviewed
···
1
1
size: Q1
2
2
uuid: 911f4d08-18ff-4f85-a7e7-70244fab87b4
3
3
+
name: Gigas1
4
4
+
theme:
5
5
+
highlight_color:
6
6
+
- 255
7
7
+
- 255
8
8
+
- 255
9
9
+
- 255
10
10
+
midtone_color:
11
11
+
- 160
12
12
+
- 160
13
13
+
- 160
14
14
+
- 255
15
15
+
lowlight_color:
16
16
+
- 96
17
17
+
- 96
18
18
+
- 96
19
19
+
- 255
20
20
+
accent_color:
21
21
+
- 255
22
22
+
- 215
23
23
+
- 0
24
24
+
- 255
25
25
+
text_color:
26
26
+
- 160
27
27
+
- 160
28
28
+
- 160
29
29
+
- 255
3
30
visuals:
4
31
0:
5
32
uuid: 0f96dbae-aa7e-4316-a956-e1467ae07780
+27
prefab_modules/moogsimple.yml
reviewed
···
1
1
size: U1
2
2
uuid: 5066f806-2fb2-4cfe-b70d-dcd7d7c4ed38
3
3
+
name: Moogsimple
4
4
+
theme:
5
5
+
highlight_color:
6
6
+
- 255
7
7
+
- 255
8
8
+
- 255
9
9
+
- 255
10
10
+
midtone_color:
11
11
+
- 160
12
12
+
- 160
13
13
+
- 160
14
14
+
- 255
15
15
+
lowlight_color:
16
16
+
- 96
17
17
+
- 96
18
18
+
- 96
19
19
+
- 255
20
20
+
accent_color:
21
21
+
- 255
22
22
+
- 215
23
23
+
- 0
24
24
+
- 255
25
25
+
text_color:
26
26
+
- 160
27
27
+
- 160
28
28
+
- 160
29
29
+
- 255
3
30
visuals:
4
31
0:
5
32
uuid: 8093ddaf-9403-48c8-98e7-a3595cd8080a
+27
prefab_modules/simpleout.yml
reviewed
···
1
1
size: U1
2
2
uuid: 4761ac0d-f7ce-4bb0-84ba-8f707e92962c
3
3
+
name: simpleout
4
4
+
theme:
5
5
+
highlight_color:
6
6
+
- 255
7
7
+
- 255
8
8
+
- 255
9
9
+
- 255
10
10
+
midtone_color:
11
11
+
- 160
12
12
+
- 160
13
13
+
- 160
14
14
+
- 255
15
15
+
lowlight_color:
16
16
+
- 96
17
17
+
- 96
18
18
+
- 96
19
19
+
- 255
20
20
+
accent_color:
21
21
+
- 255
22
22
+
- 215
23
23
+
- 0
24
24
+
- 255
25
25
+
text_color:
26
26
+
- 160
27
27
+
- 160
28
28
+
- 160
29
29
+
- 255
3
30
visuals:
4
31
0:
5
32
uuid: 8093ddaf-9403-48c8-98e7-a3595cd8080a
+42
-11
rack-designer/src/app.rs
reviewed
···
30
30
devices::description::Param,
31
31
pos_drag_value,
32
32
two_drag_value,
33
33
-
visuals::templates::WidgetTemplate,
33
33
+
visuals::{
34
34
+
templates::WidgetTemplate,
35
35
+
VisualTheme,
36
36
+
},
34
37
widget_description::{
35
38
ModuleDescription,
36
39
WidgetKind,
···
163
166
.resizable(false)
164
167
.min_width(256.)
165
168
.show(ctx, |ui| {
169
169
+
ui.collapsing("Theme", |ui| {
170
170
+
ui.horizontal(|ui| {
171
171
+
ui.label("Accent");
172
172
+
ui.color_edit_button_srgba(&mut state.module.theme.accent_color);
173
173
+
});
174
174
+
ui.horizontal(|ui| {
175
175
+
ui.label("Highlight");
176
176
+
ui.color_edit_button_srgba(&mut state.module.theme.highlight_color);
177
177
+
});
178
178
+
ui.horizontal(|ui| {
179
179
+
ui.label("Lowlight");
180
180
+
ui.color_edit_button_srgba(&mut state.module.theme.lowlight_color);
181
181
+
});
182
182
+
ui.horizontal(|ui| {
183
183
+
ui.label("Midtone");
184
184
+
ui.color_edit_button_srgba(&mut state.module.theme.midtone_color);
185
185
+
});
186
186
+
ui.horizontal(|ui| {
187
187
+
ui.label("Text");
188
188
+
ui.color_edit_button_srgba(&mut state.module.theme.text_color);
189
189
+
});
190
190
+
});
191
191
+
166
192
ScrollArea::vertical().id_source("widgets").show(ui, |ui| {
167
193
widgets_editor(ui, &mut state, loader);
168
194
});
···
206
232
CentralPanel::default().show(ctx, |ui| {
207
233
let r = ui.available_rect_before_wrap();
208
234
paint_module_bg(ui.painter(), r.center(), current.module.size);
209
209
-
paint_module_widgets(ui, r.center(), ¤t.module.visuals);
235
235
+
paint_module_widgets(
236
236
+
ui,
237
237
+
r.center(),
238
238
+
¤t.module.visuals,
239
239
+
current.module.theme,
240
240
+
);
210
241
});
211
242
next_state
212
243
}
···
366
397
);
367
398
}
368
399
369
369
-
fn paint_module_widgets(ui: &mut Ui, center: Pos2, visuals: &BTreeMap<usize, WidgetTemplate>) {
370
370
-
visuals.values().for_each(|visual| {
371
371
-
visual.preview(
372
372
-
ui,
373
373
-
center + visual.position.to_vec2(),
374
374
-
Default::default(),
375
375
-
0.0,
376
376
-
)
377
377
-
});
400
400
+
fn paint_module_widgets(
401
401
+
ui: &mut Ui,
402
402
+
center: Pos2,
403
403
+
visuals: &BTreeMap<usize, WidgetTemplate>,
404
404
+
theme: VisualTheme,
405
405
+
) {
406
406
+
visuals
407
407
+
.values()
408
408
+
.for_each(|visual| visual.preview(ui, center + visual.position.to_vec2(), theme, 0.0));
378
409
}
+6
-1
rack-designer/src/app/state.rs
reviewed
···
1
1
-
use rack::widget_description::ModuleDescription;
1
1
+
use rack::{
2
2
+
visuals::VisualTheme,
3
3
+
widget_description::ModuleDescription,
4
4
+
};
2
5
3
6
use rack::container::sizing::ModuleSize;
4
7
use uuid::Uuid;
···
74
77
device_adder: None,
75
78
module: ModuleDescription {
76
79
uuid: Uuid::new_v4(),
80
80
+
name: String::new(),
81
81
+
theme: VisualTheme::default(),
77
82
size,
78
83
visuals: Default::default(),
79
84
devices: Default::default(),
+11
-3
rack/src/graph/modules.rs
reviewed
···
24
24
Param,
25
25
},
26
26
graph::Graph,
27
27
-
visuals::templates::WidgetTemplate,
27
27
+
visuals::{
28
28
+
templates::WidgetTemplate,
29
29
+
VisualTheme,
30
30
+
},
28
31
widget_description::ModuleDescription,
29
32
widgets::{
30
33
SlotWidget,
···
46
49
pub size: ModuleSize,
47
50
pub devices: Vec<DeviceId>,
48
51
pub visuals: SlotMap<VisualId, SlotWidget>,
52
52
+
theme: VisualTheme,
49
53
pub values: SecondaryMap<VisualId, Connector>,
50
54
/// Maps inputs to their visuals
51
55
pub ins: SecondaryMap<InputId, VisualId>,
···
71
75
graph: &mut Graph,
72
76
size: ModuleSize,
73
77
visual_descs: BTreeMap<usize, WidgetTemplate>,
78
78
+
theme: VisualTheme,
74
79
devices: BTreeMap<usize, DeviceKind>,
75
80
mut connections: BTreeMap<(usize, usize), usize>,
76
81
) -> ModuleId {
···
120
125
size,
121
126
devices,
122
127
visuals,
128
128
+
theme,
123
129
values,
124
130
ins,
125
131
outs,
···
129
135
pub fn insert_from_description(graph: &mut Graph, description: ModuleDescription) -> ModuleId {
130
136
let ModuleDescription {
131
137
uuid: _,
138
138
+
name: _,
139
139
+
theme,
132
140
size,
133
141
visuals,
134
142
devices,
135
143
connections,
136
144
} = description;
137
137
-
Self::insert_new(graph, size, visuals, devices, connections)
145
145
+
Self::insert_new(graph, size, visuals, theme, devices, connections)
138
146
}
139
147
140
148
fn ui_for(&mut self, position: Pos2, ui: &mut Ui) -> ModuleResponse {
···
143
151
for (vid, w) in visuals.iter_mut() {
144
152
let pos = w.pos() + position.to_vec2();
145
153
ui.put(Rect::from_min_size(pos, w.size()), |ui: &mut Ui| {
146
146
-
let InnerResponse { inner, response } = w.show(ui);
154
154
+
let InnerResponse { inner, response } = w.show(ui, self.theme);
147
155
if let Some(connected_plug) = self.values.get(vid).copied() {
148
156
match inner {
149
157
WidgetResponse::None => {}
+6
-6
rack/src/visuals.rs
reviewed
···
210
210
Text(Pos2, String, FontFamily),
211
211
}
212
212
213
213
-
#[derive(Serialize, Deserialize, Clone, Copy)]
213
213
+
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
214
214
pub struct VisualTheme {
215
215
-
highlight_color: Color32,
216
216
-
midtone_color: Color32,
217
217
-
lowlight_color: Color32,
218
218
-
accent_color: Color32,
219
219
-
text_color: Color32,
215
215
+
pub highlight_color: Color32,
216
216
+
pub midtone_color: Color32,
217
217
+
pub lowlight_color: Color32,
218
218
+
pub accent_color: Color32,
219
219
+
pub text_color: Color32,
220
220
}
221
221
222
222
impl Default for VisualTheme {
+6
-1
rack/src/widget_description.rs
reviewed
···
9
9
use crate::{
10
10
container::sizing::ModuleSize,
11
11
devices::description::DeviceKind,
12
12
-
visuals::templates::WidgetTemplate,
12
12
+
visuals::{
13
13
+
templates::WidgetTemplate,
14
14
+
VisualTheme,
15
15
+
},
13
16
widgets::KnobRange,
14
17
Uuidentified,
15
18
};
···
17
20
#[derive(Debug, Serialize, Deserialize, Clone)]
18
21
pub struct ModuleDescription {
19
22
pub uuid: Uuid,
23
23
+
pub name: String,
24
24
+
pub theme: VisualTheme,
20
25
pub size: ModuleSize,
21
26
pub visuals: BTreeMap<usize, WidgetTemplate>,
22
27
pub devices: BTreeMap<usize, DeviceKind>,
+7
-4
rack/src/widgets.rs
reviewed
···
11
11
use std::ops::RangeInclusive;
12
12
13
13
use crate::{
14
14
-
visuals::templates::WidgetTemplate,
14
14
+
visuals::{
15
15
+
templates::WidgetTemplate,
16
16
+
VisualTheme,
17
17
+
},
15
18
Tooltipable,
16
19
};
17
20
···
94
97
}
95
98
}
96
99
97
97
-
pub fn show(&mut self, ui: &mut Ui) -> InnerResponse<WidgetResponse> {
100
100
+
pub fn show(&mut self, ui: &mut Ui, theme: VisualTheme) -> InnerResponse<WidgetResponse> {
98
101
match self {
99
99
-
SlotWidget::Knob(k) => k.show(ui),
102
102
+
SlotWidget::Knob(k) => k.show(ui, theme),
100
103
SlotWidget::Fader(_f) => todo!(),
101
101
-
SlotWidget::Port(p) => p.show(ui),
104
104
+
SlotWidget::Port(p) => p.show(ui, theme),
102
105
}
103
106
}
104
107
+3
-2
rack/src/widgets/connector/ports.rs
reviewed
···
2
2
visuals::{
3
3
templates::WidgetTemplate,
4
4
VisualComponent,
5
5
+
VisualTheme,
5
6
},
6
7
widget_description::WidgetKind,
7
8
widgets::WidgetResponse,
···
24
25
}
25
26
26
27
impl Port {
27
27
-
pub fn show(&mut self, ui: &mut Ui) -> InnerResponse<WidgetResponse> {
28
28
+
pub fn show(&mut self, ui: &mut Ui, theme: VisualTheme) -> InnerResponse<WidgetResponse> {
28
29
let (rect, response) = ui.allocate_exact_size(self.size, Sense::click());
29
30
30
31
ui.painter().debug_rect(rect, Color32::DEBUG_COLOR, "");
31
32
let center = rect.center();
32
33
if ui.is_rect_visible(rect) {
33
34
for visual in &self.visuals {
34
34
-
visual.show(ui, center, Default::default());
35
35
+
visual.show(ui, center, theme);
35
36
}
36
37
}
37
38
let inner = if response.clicked_by(PointerButton::Primary) {
+7
-6
rack/src/widgets/knob.rs
reviewed
···
18
18
visuals::{
19
19
templates::WidgetTemplate,
20
20
VisualComponent,
21
21
+
VisualTheme,
21
22
},
22
23
widget_description::{
23
24
KnobKind,
···
88
89
ui.allocate_response(self.size, Sense::click_and_drag())
89
90
}
90
91
91
91
-
fn update(&mut self, ui: &mut Ui) -> Response {
92
92
+
fn update(&mut self, ui: &mut Ui, theme: VisualTheme) -> Response {
92
93
let old_value = self.value;
93
94
let old_angle = self.angle;
94
95
···
115
116
self.angle = angle;
116
117
}
117
118
118
118
-
self.draw(ui, &res);
119
119
+
self.draw(ui, &res, theme);
119
120
120
121
res.changed = self.value != old_value;
121
122
122
123
res
123
124
}
124
125
125
125
-
fn draw(&mut self, ui: &mut Ui, res: &Response) {
126
126
+
fn draw(&mut self, ui: &mut Ui, res: &Response, theme: VisualTheme) {
126
127
let rect = res.rect;
127
128
let center = rect.center();
128
129
ui.painter().debug_rect(rect, Color32::GOLD, "");
129
130
130
131
if ui.is_rect_visible(rect) {
131
132
for visual in &self.visuals {
132
132
-
visual.show_with_value(ui, center, Default::default(), self.angle)
133
133
+
visual.show_with_value(ui, center, theme, self.angle)
133
134
}
134
135
}
135
136
}
136
137
137
137
-
pub fn show(&mut self, ui: &mut Ui) -> InnerResponse<WidgetResponse> {
138
138
-
let response = self.update(ui);
138
138
+
pub fn show(&mut self, ui: &mut Ui, theme: VisualTheme) -> InnerResponse<WidgetResponse> {
139
139
+
let response = self.update(ui, theme);
139
140
let wr = if response.changed() {
140
141
WidgetResponse::Changed
141
142
} else {
+3
-20
src/pcmg_ui/module_adder.rs
reviewed
···
5
5
Sense,
6
6
Window,
7
7
};
8
8
-
use rack::{
9
9
-
visuals::VisualTheme,
10
10
-
widget_description::ModuleDescription,
11
11
-
};
8
8
+
use rack::widget_description::ModuleDescription;
12
9
use uuid::Uuid;
13
10
14
11
pub struct ModuleAdder {
···
31
28
ui.horizontal(|ui| {
32
29
ui.vertical(|ui| {
33
30
for (uuid, module) in self.modules.iter() {
34
34
-
ui.selectable_value(&mut self.selection, Some(*uuid), uuid.to_string());
35
35
-
let (r, _) = ui.allocate_exact_size(module.size.size(), Sense::hover());
36
36
-
for vis in module.visuals.values() {
37
37
-
vis.preview(
38
38
-
ui,
39
39
-
r.center() + vis.position.to_vec2(),
40
40
-
VisualTheme::default(),
41
41
-
0.0,
42
42
-
)
43
43
-
}
31
31
+
ui.selectable_value(&mut self.selection, Some(*uuid), &module.name);
44
32
}
45
33
closing = ui.button("Add").clicked();
46
34
});
···
49
37
let m = &self.modules[&uuid];
50
38
let (r, _) = ui.allocate_exact_size(m.size.size(), Sense::hover());
51
39
for w in m.visuals.values() {
52
52
-
w.preview(
53
53
-
ui,
54
54
-
r.center() + w.position.to_vec2(),
55
55
-
Default::default(),
56
56
-
0.0,
57
57
-
);
40
40
+
w.preview(ui, r.center() + w.position.to_vec2(), m.theme, 0.0);
58
41
}
59
42
}
60
43
});