Skip to content

Commit 75dc7d5

Browse files
committed
feat(fixtures): always show current value of fixtures in table
1 parent 8f42e85 commit 75dc7d5

File tree

13 files changed

+182
-134
lines changed

13 files changed

+182
-134
lines changed

crates/api/protos/programmer.proto

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ message ProgrammerState {
2727
uint32 wings = 9;
2828
repeated EffectProgrammerState effects = 10;
2929
bool offline = 11;
30+
repeated FixtureValue fixture_values = 12;
31+
}
32+
33+
message FixtureValue {
34+
mizer.fixtures.FixtureId fixture = 1;
35+
optional double intensity = 2;
36+
optional mizer.fixtures.ColorMixerChannel color = 3;
37+
optional double pan = 4;
38+
optional double tilt = 5;
3039
}
3140

3241
message FixtureSelection {

crates/components/fixtures/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ impl FixtureStates {
147147
pub struct FixtureState {
148148
pub brightness: Option<f64>,
149149
pub color: Option<Color>,
150+
pub pan: Option<f64>,
151+
pub tilt: Option<f64>,
150152
}
151153

152154
#[derive(Debug, Clone, Copy, Default)]

crates/components/fixtures/src/processor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ impl Processor for FixtureProcessor {
7575
fn get_state(fixture: &impl IFixture) -> FixtureState {
7676
let mut fixture_state = FixtureState::default();
7777
fixture_state.brightness = fixture.read_control(FixtureFaderControl::Intensity);
78+
fixture_state.pan = fixture.read_control(FixtureFaderControl::Pan);
79+
fixture_state.tilt = fixture.read_control(FixtureFaderControl::Tilt);
7880
let red = fixture.read_control(FixtureFaderControl::ColorMixer(ColorChannel::Red));
7981
let green = fixture.read_control(FixtureFaderControl::ColorMixer(ColorChannel::Green));
8082
let blue = fixture.read_control(FixtureFaderControl::ColorMixer(ColorChannel::Blue));
83+
8184
fixture_state.color = red
8285
.zip(green)
8386
.zip(blue)

crates/ui/ffi/src/apis/fixture.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use crate::types::{drop_pointer, FFIFromPointer};
1+
use crate::types::{drop_pointer, Array, FFIFromPointer};
22
use mizer_fixtures::{FixtureId, FixtureState, FixtureStates};
33
use std::sync::Arc;
4+
use crate::apis::programmer::{FFIColorValue, FFIFixtureId};
45

56
pub struct FixturesRef(pub FixtureStates);
67

@@ -26,6 +27,39 @@ pub extern "C" fn read_fixture_state(
2627
state.map(|state| (*state).into()).unwrap_or_default()
2728
}
2829

30+
#[no_mangle]
31+
pub extern "C" fn read_fixture_states(
32+
ptr: *const FixturesRef
33+
) -> FFIFixtureStates {
34+
let ffi = Arc::from_pointer(ptr);
35+
36+
let state = ffi.0.read();
37+
let fixture_values = state
38+
.iter()
39+
.map(|(id, state)| {
40+
let id = (*id).into();
41+
42+
FFIFixtureValues {
43+
fixture_id: id,
44+
has_intensity: state.brightness.is_some().into(),
45+
intensity: state.brightness.unwrap_or_default(),
46+
has_color: state.color.is_some().into(),
47+
color: FFIColorValue::from(state.color.unwrap_or_default()),
48+
has_pan: state.pan.is_some().into(),
49+
pan: state.pan.unwrap_or_default(),
50+
has_tilt: state.tilt.is_some().into(),
51+
tilt: state.tilt.unwrap_or_default(),
52+
}
53+
})
54+
.collect();
55+
56+
std::mem::forget(ffi);
57+
58+
FFIFixtureStates {
59+
fixture_values,
60+
}
61+
}
62+
2963
#[no_mangle]
3064
pub extern "C" fn drop_fixture_pointer(ptr: *const FixturesRef) {
3165
drop_pointer(ptr);
@@ -56,3 +90,21 @@ impl From<FixtureState> for FFIFixtureState {
5690
}
5791
}
5892
}
93+
94+
#[repr(C)]
95+
pub struct FFIFixtureStates {
96+
pub fixture_values: Array<FFIFixtureValues>,
97+
}
98+
99+
#[repr(C)]
100+
pub struct FFIFixtureValues {
101+
pub fixture_id: FFIFixtureId,
102+
pub has_intensity: u8,
103+
pub intensity: f64,
104+
pub has_color: u8,
105+
pub color: FFIColorValue,
106+
pub has_pan: u8,
107+
pub pan: f64,
108+
pub has_tilt: u8,
109+
pub tilt: f64,
110+
}

crates/ui/ffi/src/apis/programmer.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use crate::types::{drop_pointer, Array, FFIFromPointer};
22
use mizer_fixtures::definition::FixtureControlValue;
3-
use mizer_fixtures::programmer::{
4-
PresetId, ProgrammedEffect, ProgrammerChannel, ProgrammerControlValue, ProgrammerState,
5-
ProgrammerView,
6-
};
3+
use mizer_fixtures::programmer::{Color, PresetId, ProgrammedEffect, ProgrammerChannel, ProgrammerControlValue, ProgrammerState, ProgrammerView};
74
use mizer_fixtures::FixtureId;
85
use parking_lot::Mutex;
96
use std::collections::HashMap;
@@ -286,6 +283,16 @@ pub struct FFIColorValue {
286283
pub blue: f64,
287284
}
288285

286+
impl From<Color> for FFIColorValue {
287+
fn from((red, green, blue): Color) -> Self {
288+
Self {
289+
red,
290+
green,
291+
blue
292+
}
293+
}
294+
}
295+
289296
#[repr(C)]
290297
#[derive(Clone, Copy)]
291298
pub struct FFIGenericValue {

crates/ui/lib/api/plugin/ffi/plans.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:ffi' as ffi;
22

33
import 'package:flutter/widgets.dart' as widgets;
4+
import 'package:mizer/api/plugin/ffi/programmer.dart';
45
import 'package:mizer/protos/fixtures.pb.dart';
56
import 'package:mizer/protos/layouts.pb.dart';
67

@@ -29,6 +30,21 @@ class FixtureState {
2930
}
3031
}
3132

33+
class FixturesState {
34+
final Map<FixtureId, FixtureValues> fixtureStates;
35+
36+
FixturesState({this.fixtureStates = const {}});
37+
}
38+
39+
class FixtureValues {
40+
final double? intensity;
41+
final Color? color;
42+
final double? pan;
43+
final double? tilt;
44+
45+
FixtureValues({this.intensity, this.color, this.pan, this.tilt});
46+
}
47+
3248
class FixturesRefPointer extends FFIPointer<FixturesRef> {
3349
final FFIBindings _bindings;
3450

@@ -52,6 +68,26 @@ class FixturesRefPointer extends FFIPointer<FixturesRef> {
5268
);
5369
}
5470

71+
FixturesState readStates() {
72+
FFIFixtureStates states = this._bindings.read_fixture_states(ptr);
73+
var fixtures = new List.generate(states.fixture_values.len, (index) => states.fixture_values.array.elementAt(index).ref);
74+
75+
Map<FixtureId, FixtureValues> fixtureStates = {};
76+
77+
fixtures.forEach((fixture) {
78+
fixtureStates[fixture.fixture_id.toFixtureId()] = FixtureValues(
79+
intensity: fixture.has_intensity == 1 ? fixture.intensity : null,
80+
color: fixture.has_color == 1
81+
? Color(red: fixture.color.red, green: fixture.color.green, blue: fixture.color.blue)
82+
: null,
83+
pan: fixture.has_pan == 1 ? fixture.pan : null,
84+
tilt: fixture.has_tilt == 1 ? fixture.tilt : null
85+
);
86+
});
87+
88+
return FixturesState(fixtureStates: fixtureStates);
89+
}
90+
5591
@override
5692
void disposePointer(ffi.Pointer<FixturesRef> _ptr) {
5793
this._bindings.drop_fixture_pointer(_ptr);

crates/ui/lib/api/plugin/ffi/programmer.dart

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,7 @@ class ProgrammerStatePointer extends FFIPointer<Programmer> {
5454
List<FixtureId> _readFixtureSelection(Array_FFIFixtureId result) {
5555
var fixtures = new List.generate(result.len, (index) => result.array.elementAt(index).ref);
5656

57-
return fixtures.map((id) {
58-
if (id.sub_fixture_id != 0) {
59-
return FixtureId(
60-
subFixture: SubFixtureId(fixtureId: id.fixture_id, childId: id.sub_fixture_id));
61-
}
62-
return FixtureId(fixture: id.fixture_id);
63-
}).toList();
57+
return fixtures.map((id) => id.toFixtureId()).toList();
6458
}
6559

6660
List<int> _readGroupSelection(Array_u32 result) {
@@ -142,3 +136,13 @@ class ProgrammerStatePointer extends FFIPointer<Programmer> {
142136
this._bindings.drop_programmer_pointer(_ptr);
143137
}
144138
}
139+
140+
extension FFI on FFIFixtureId {
141+
FixtureId toFixtureId() {
142+
if (this.sub_fixture_id != 0) {
143+
return FixtureId(
144+
subFixture: SubFixtureId(fixtureId: this.fixture_id, childId: this.sub_fixture_id));
145+
}
146+
return FixtureId(fixture: this.fixture_id);
147+
}
148+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:flutter/scheduler.dart';
2+
import 'package:flutter/widgets.dart';
3+
import 'package:mizer/api/contracts/plans.dart';
4+
import 'package:mizer/api/plugin/ffi/plans.dart';
5+
import 'package:mizer/protos/fixtures.pb.dart';
6+
import 'package:provider/provider.dart';
7+
8+
@optionalTypeArgs
9+
mixin FixtureValuesMixin<T extends StatefulWidget> on State<T>, TickerProvider {
10+
FixturesRefPointer? _fixturesPointer;
11+
Ticker? _fixtureValuesTicker;
12+
FixturesState _fixturesState = FixturesState();
13+
14+
@override
15+
void initState() {
16+
super.initState();
17+
var plansApi = context.read<PlansApi>();
18+
plansApi.getFixturesPointer().then((pointer) {
19+
_fixturesPointer = pointer;
20+
_fixtureValuesTicker = this.createTicker((elapsed) {
21+
setState(() {
22+
_fixturesState = _fixturesPointer!.readStates();
23+
});
24+
});
25+
_fixtureValuesTicker!.start();
26+
});
27+
}
28+
29+
@override
30+
void dispose() {
31+
_fixturesPointer?.dispose();
32+
_fixtureValuesTicker?.stop(canceled: true);
33+
super.dispose();
34+
}
35+
36+
Map<FixtureId, FixtureValues> get fixtureValues {
37+
return this._fixturesState.fixtureStates;
38+
}
39+
}
Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
import 'package:collection/collection.dart';
21
import 'package:flutter/widgets.dart';
3-
import 'package:mizer/protos/fixtures.pb.dart';
4-
import 'package:mizer/protos/programmer.pb.dart';
5-
import 'package:mizer/state/presets_bloc.dart';
6-
import 'package:provider/provider.dart';
72

83
class ColorIndicator extends StatelessWidget {
9-
final Iterable<ProgrammerChannel>? fixtureState;
4+
final Color? color;
105

11-
const ColorIndicator({super.key, this.fixtureState});
6+
const ColorIndicator({super.key, this.color});
127

138
@override
149
Widget build(BuildContext context) {
15-
var color = this.getColor(context);
1610
if (color == null) {
1711
return Container();
1812
}
@@ -25,38 +19,4 @@ class ColorIndicator extends StatelessWidget {
2519
),
2620
);
2721
}
28-
29-
Color? getColor(BuildContext context) {
30-
var programmerChannel =
31-
fixtureState?.firstWhereOrNull((element) => element.control == FixtureControl.COLOR_MIXER);
32-
if (programmerChannel == null) {
33-
return null;
34-
}
35-
if (programmerChannel.hasPreset()) {
36-
PresetsBloc bloc = context.read();
37-
var preset = bloc.state.getPreset(programmerChannel.preset);
38-
if (preset == null) {
39-
return null;
40-
}
41-
return _convertPresetColor(preset.color);
42-
}
43-
44-
return _convertColor(programmerChannel.color);
45-
}
46-
47-
Color _convertColor(ColorMixerChannel color) {
48-
int red = (color.red * 255).round();
49-
int green = (color.green * 255).round();
50-
int blue = (color.blue * 255).round();
51-
52-
return Color.fromARGB(255, red, green, blue);
53-
}
54-
55-
Color _convertPresetColor(Preset_Color color) {
56-
int red = (color.red * 255).round();
57-
int green = (color.green * 255).round();
58-
int blue = (color.blue * 255).round();
59-
60-
return Color.fromARGB(255, red, green, blue);
61-
}
6222
}

crates/ui/lib/views/fixtures/fader_indicator.dart

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,22 @@
1-
import 'package:collection/collection.dart';
21
import 'package:flutter/material.dart';
3-
import 'package:mizer/api/contracts/programmer.dart';
4-
import 'package:mizer/protos/fixtures.pbenum.dart';
5-
import 'package:mizer/state/presets_bloc.dart';
6-
import 'package:provider/provider.dart';
72

83
class IntensityIndicator extends StatelessWidget {
94
final Widget child;
10-
final Iterable<ProgrammerChannel>? fixtureState;
5+
final double? value;
116

12-
const IntensityIndicator({super.key, required this.child, this.fixtureState});
7+
const IntensityIndicator({super.key, required this.child, this.value});
138

149
@override
1510
Widget build(BuildContext context) {
16-
var value = this.getValue(context);
1711
return Row(
1812
mainAxisSize: MainAxisSize.min,
1913
children: [
20-
if (value != null) CustomPaint(size: Size.fromWidth(8), painter: FaderIndicatorPainter(value)),
14+
if (value != null) CustomPaint(size: Size.fromWidth(8), painter: FaderIndicatorPainter(value!)),
2115
Expanded(child: SizedBox(width: 2)),
2216
child,
2317
]
2418
);
2519
}
26-
27-
double? getValue(BuildContext context) {
28-
var programmerChannel = fixtureState?.firstWhereOrNull((element) => element.control == FixtureControl.INTENSITY);
29-
if (programmerChannel == null) {
30-
return null;
31-
}
32-
if (programmerChannel.hasPreset()) {
33-
PresetsBloc bloc = context.read();
34-
var preset = bloc.state.getPreset(programmerChannel.preset);
35-
if (preset == null) {
36-
return null;
37-
}
38-
return preset.fader;
39-
}
40-
return programmerChannel.fader;
41-
}
4220
}
4321

4422
class FaderIndicatorPainter extends CustomPainter {

0 commit comments

Comments
 (0)