@@ -42,93 +42,115 @@ class _SoundFileModalState extends State<SoundFileModal> {
4242
4343 @override
4444 Widget build (BuildContext context) {
45- final surfaceVariant = Theme .of (
46- context,
47- ).colorScheme.surfaceContainerHighest;
45+ final media = MediaQuery .of (context);
46+ final isDense = media.size.height < 500 ;
47+ final smallGap = isDense ? 12.0 : 16.0 ;
48+ final largeGap = isDense ? 20.0 : 32.0 ;
49+
4850 return Dialog (
4951 shape: RoundedRectangleBorder (borderRadius: BorderRadius .circular (24 )),
50- child: Padding (
51- padding: const EdgeInsets .all (24 ),
52- child: Form (
53- key: _formKey,
54- child: SingleChildScrollView (
55- child: Column (
56- mainAxisSize: MainAxisSize .min,
57- crossAxisAlignment: CrossAxisAlignment .start,
58- children: [
59- Text (
60- widget.create ? 'Create Sound' : 'Edit Sound' ,
61- style: Theme .of (context).textTheme.titleLarge,
62- ),
63- const SizedBox (height: 24 ),
64- const StringInputSection (),
65- const SizedBox (height: 16 ),
66- VolumeSection (
67- initialPitch: _pitch,
68- initialVolume: _volume,
69- onPitchFinalized: (v) => setState (() => _pitch = v),
70- onVolumeFinalized: (v) => setState (() => _volume = v),
71- ),
72- const SizedBox (height: 16 ),
73- IntegerFieldsSection (
74- weight: _weight,
75- attenuation: _attenuationDistance,
76- onWeightChanged: (v) => setState (() => _weight = v),
77- onAttenuationChanged: (v) =>
78- setState (() => _attenuationDistance = v),
79- ),
80- const SizedBox (height: 16 ),
81- // Section 3: Switches
82- SwitchesSection (
83- streamValue: _stream,
84- onStreamChanged: (v) => setState (() => _stream = v),
85- preloadValue: _preload,
86- onPreloadChanged: (v) => setState (() => _preload = v),
87- backgroundColor: surfaceVariant, // Pass the color
88- ),
89- const SizedBox (height: 16 ),
90- // Section 4: Type dropdown
91- BaseSection (
92- child: DropdownButtonFormField <String >(
93- initialValue: _type,
94- decoration: const InputDecoration (
95- labelText: 'Type' ,
96- border: OutlineInputBorder (),
52+ child: ConstrainedBox (
53+ constraints: const BoxConstraints (
54+ minWidth: 400 ,
55+ ),
56+ child: Padding (
57+ padding: const EdgeInsets .all (24 ),
58+ child: Form (
59+ key: _formKey,
60+ child: SingleChildScrollView (
61+ child: Column (
62+ mainAxisSize: MainAxisSize .min,
63+ crossAxisAlignment: CrossAxisAlignment .start,
64+ children: [
65+ Text (
66+ widget.create ? 'Create Sound' : 'Edit Sound' ,
67+ style: Theme .of (context).textTheme.titleLarge,
68+ ),
69+ const SizedBox (height: 24 ),
70+ const StringInputSection (),
71+ const SizedBox (height: 16 ),
72+ VolumeSection (
73+ initialPitch: _pitch,
74+ initialVolume: _volume,
75+ onPitchFinalized: (v) => setState (() => _pitch = v),
76+ onVolumeFinalized: (v) => setState (() => _volume = v),
77+ ),
78+ SizedBox (height: smallGap),
79+ IntegerFieldsSection (
80+ weight: _weight,
81+ attenuation: _attenuationDistance,
82+ onWeightChanged: (v) => setState (() => _weight = v),
83+ onAttenuationChanged: (v) =>
84+ setState (() => _attenuationDistance = v),
85+ dense: isDense,
86+ ),
87+ SizedBox (height: smallGap),
88+ // Combined Section: Switches + Type dropdown
89+ BaseSection (
90+ title: 'Options' ,
91+ child: Column (
92+ mainAxisSize: MainAxisSize .min,
93+ crossAxisAlignment: CrossAxisAlignment .stretch,
94+ children: [
95+ LayoutBuilder (
96+ builder: (context, constraints) {
97+ final horizontal = constraints.maxWidth >= 420 ;
98+ return SwitchesSection (
99+ streamValue: _stream,
100+ onStreamChanged: (v) => setState (() => _stream = v),
101+ preloadValue: _preload,
102+ onPreloadChanged: (v) => setState (() => _preload = v),
103+ wrapInBaseSection: false ,
104+ vertical: ! horizontal,
105+ );
106+ },
107+ ),
108+ SizedBox (height: smallGap),
109+ const Divider (height: 1 ),
110+ SizedBox (height: smallGap),
111+ DropdownButtonFormField <String >(
112+ initialValue: _type,
113+ decoration: const InputDecoration (
114+ labelText: 'Type' ,
115+ border: OutlineInputBorder (),
116+ ),
117+ items: const [
118+ DropdownMenuItem (value: 'file' , child: Text ('File' )),
119+ DropdownMenuItem (value: 'event' , child: Text ('Event' )),
120+ ],
121+ onChanged: (v) => setState (() => _type = v ?? 'file' ),
122+ ),
123+ ],
97124 ),
98- items: const [
99- DropdownMenuItem (value: 'file' , child: Text ('File' )),
100- DropdownMenuItem (value: 'event' , child: Text ('Event' )),
125+ ),
126+ SizedBox (height: largeGap),
127+ Row (
128+ mainAxisAlignment: MainAxisAlignment .end,
129+ children: [
130+ CancelButton (callback: () => Navigator .pop (context)),
131+ const SizedBox (width: 12 ),
132+ FilledButton (
133+ onPressed: () {
134+ if (_formKey.currentState? .validate () ?? false ) {
135+ widget.onSave? .call (
136+ name: _name,
137+ volume: _volume,
138+ pitch: _pitch,
139+ weight: _weight,
140+ stream: _stream,
141+ attenuationDistance: _attenuationDistance,
142+ preload: _preload,
143+ type: _type,
144+ );
145+ Navigator .pop (context);
146+ }
147+ },
148+ child: const Text ('Save' ),
149+ ),
101150 ],
102- onChanged: (v) => setState (() => _type = v ?? 'file' ),
103151 ),
104- ),
105- const SizedBox (height: 32 ),
106- Row (
107- mainAxisAlignment: MainAxisAlignment .end,
108- children: [
109- CancelButton (callback: () => Navigator .pop (context)),
110- const SizedBox (width: 12 ),
111- FilledButton (
112- onPressed: () {
113- if (_formKey.currentState? .validate () ?? false ) {
114- widget.onSave? .call (
115- name: _name,
116- volume: _volume,
117- pitch: _pitch,
118- weight: _weight,
119- stream: _stream,
120- attenuationDistance: _attenuationDistance,
121- preload: _preload,
122- type: _type,
123- );
124- Navigator .pop (context);
125- }
126- },
127- child: const Text ('Save' ),
128- ),
129- ],
130- ),
131- ],
152+ ],
153+ ),
132154 ),
133155 ),
134156 ),
0 commit comments