1use {
2 crate::{
3 build_manager::{
4 build_manager::*,
5 build_protocol::*,
6 },
7 app::{AppData, AppAction},
8 makepad_widgets::*,
9 },
10 std::env,
11};
12
13live_design!{
14 use link::shaders::*;
15 use link::widgets::*;
16 use link::theme::*;
17
18 BuildItem = <View> {
19 width: Fill, height: Fit,
20 show_bg: true,
21
22 draw_bg: {
23 instance is_even: 0.0
24 instance active: 0.0
25 instance hover: 0.0
26 fn pixel(self) -> vec4 {
27 return mix(
28 mix(
29 THEME_COLOR_BG_EVEN,
30 THEME_COLOR_BG_ODD,
31 self.is_even
32 ),
33 THEME_COLOR_OUTSET_ACTIVE,
34 self.active
35 );
36 }
37 }
38 }
39
40 RunButton = <CheckBox> {
41 width: Fill,
42
43 margin: <THEME_MSPACE_H_1> {}
44 draw_bg: {
45 uniform size: 3.5;
46 uniform length: 3.0
47 uniform width: 1.0
48
49 fn pixel(self) -> vec4 {
50 let sdf = Sdf2d::viewport(self.pos * self.rect_size)
51 let left = 3;
52 let sz = self.size;
53 let c = vec2(left + sz, self.rect_size.y * 0.5 - 1);
54
55 sdf.box(
57 sz * 0.5,
58 sz * 2.25,
59 sz * 0.9,
60 sz * 3.0,
61 1.0
62 );
63
64 sdf.box(
65 sz * 1.75,
66 sz * 2.25,
67 sz * 0.9,
68 sz * 3.0,
69 1.0
70 );
71
72 sdf.fill(mix(THEME_COLOR_U_HIDDEN, mix(THEME_COLOR_W, THEME_COLOR_LABEL_OUTER_HOVER, self.hover), self.active));
73
74 sdf.rotate(self.active * 0.5 * PI + 0.5 * PI, c.x, c.y);
76 sdf.move_to(c.x - sz, c.y + sz);
77 sdf.line_to(c.x, c.y - sz);
78 sdf.line_to(c.x + sz, c.y + sz);
79 sdf.close_path();
80 sdf.fill(mix(mix(THEME_COLOR_U_4, THEME_COLOR_LABEL_OUTER_HOVER, self.hover), THEME_COLOR_U_HIDDEN, self.active));
81
82 return sdf.result
83 }
84 }
85 }
86
87 pub RunList = {{RunList}}{
88 width: Fill, height: Fill,
89
90 list = <FlatList> {
91 height: Fill, width: Fill,
92 flow: Down,
93 grab_key_focus: true,
94 drag_scrolling: false,
95
96 Target = <BuildItem> {
97 padding: 0,
98 check = <RunButton> { margin: {left: 23} }
99
100 }
145
146 Binary = <BuildItem> {
147 flow: Right
148
149 fold = <FoldButton> {
150 height: 25, width: 15,
151 margin: { left: (THEME_SPACE_2) }
152 animator: { active = { default: off } }
153 draw_bg: {
154 uniform size: 3.75;
155 instance active: 0.0
156
157 fn pixel(self) -> vec4 {
158 let sdf = Sdf2d::viewport(self.pos * self.rect_size)
159 let left = 2;
160 let sz = self.size;
161 let c = vec2(left + sz, self.rect_size.y * 0.5);
162
163 sdf.box(0.5, sz * 3.0, sz * 2.5, sz * 0.7, 1.0); sdf.fill_keep(mix((#6), #8, self.hover));
167 sdf.box(sz * 1.0, sz * 2.125, sz * 0.7, sz * 2.5, 1.0); sdf.fill_keep(mix(mix((#6), #8, self.hover), #fff0, self.active))
170
171 return sdf.result
172 }
173 }
174 }
175 check = <RunButton> {}
177 }
178
179 Empty = <BuildItem> {
180 height: Fit, width: Fill,
181 cursor: Default
182 }
183 }
184 }
185}
186
187#[derive(Clone, Debug, DefaultNone)]
188pub enum RunListAction{
189 Create(LiveId, String),
190 Destroy(LiveId),
191 None
192}
193
194#[derive(Clone, Debug, PartialEq, DefaultNone)]
195enum ActionData{
196 RunMain{binary_id: usize},
197 RunTarget{target:BuildTarget, binary_id:usize},
198 FoldBinary{binary_id:usize},
199 None
200}
201
202#[derive(Live, LiveHook, Widget)]
203struct RunList{
204 #[deref] view:View
205}
206
207impl RunList{
208 fn draw_run_list(&mut self, cx: &mut Cx2d, list:&mut FlatList, build_manager:&mut BuildManager){
209 let mut counter = 0u32;
210 for (binary_id, binary) in build_manager.binaries.iter().enumerate() {
211 let is_even = counter & 1 == 0;
212
213 let item_id = LiveId::from_str(&binary.name);
214 let item = list.item(cx, item_id, live_id!(Binary)).unwrap().as_view();
215 item.apply_over(cx, live!{
216 check = {text:(&binary.name)}
217 draw_bg: {is_even: (if is_even {1.0} else {0.0})}
218 });
219
220 item.fold_button(id!(fold)).set_action_data(ActionData::FoldBinary{binary_id});
221
222 let cb = item.check_box(id!(check));
223 cb.set_active(cx, build_manager.active.any_binary_active(&binary.name));
224 cb.set_action_data(ActionData::RunMain{binary_id});
225
226 item.draw_all(cx, &mut Scope::empty());
227 counter += 1;
228
229 if binary.open>0.001 {
230 for i in 0..BuildTarget::len() {
231 let is_even = counter & 1 == 0;
232 let item_id = item_id.bytes_append(&i.to_be_bytes());
233 let item = list.item(cx, item_id, live_id!(Target)).unwrap().as_view();
234 let height = 25.0 * binary.open;
235 item.apply_over(cx, live!{
236 height: (height)
237 draw_bg: {is_even: (if is_even {1.0} else {0.0})}
238 check = {text: (BuildTarget::from_id(i).name())}
239 });
240 let cb = item.check_box(id!(check));
241 cb.set_active(cx, build_manager.active.item_id_active(item_id));
242
243 cb.set_action_data(ActionData::RunTarget{target:BuildTarget::from_id(i), binary_id});
244 item.draw_all(cx, &mut Scope::empty());
245 counter += 1;
246 }
247 }
248 }
249 while list.space_left(cx)>0.0 {
250 let is_even = counter & 1 == 0;
251 let item_id = LiveId::from_str("empty").bytes_append(&counter.to_be_bytes());
252 let item = list.item(cx, item_id, live_id!(Empty)).unwrap().as_view();
253 let height = list.space_left(cx).min(20.0);
254 item.apply_over(cx, live!{
255 height: (height)
256 draw_bg: {is_even: (if is_even {1.0} else {0.0})}
257 });
258 item.draw_all(cx, &mut Scope::empty());
259 counter += 1;
260 }
261 }
262}
263
264impl WidgetMatchEvent for RunList{
265 fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, scope: &mut Scope){
266 let build_manager = &mut scope.data.get_mut::<AppData>().unwrap().build_manager;
267 let run_list = self.view.flat_list(id!(list));
268 for (_item_id, item) in run_list.items_with_actions(&actions) {
269 let fb = item.fold_button(id!(fold));
270 if let Some(v) = item.fold_button(id!(fold)).animating(&actions) {
271 if let ActionData::FoldBinary{binary_id} = fb.action_data().cast_ref(){
273 build_manager.binaries[*binary_id].open = v;
274 item.redraw(cx);
275 }
276 }
277
278 let cb = item.check_box(id!(check));
279 if let Some(change) = cb.changed(&actions) {
280 item.redraw(cx);
281 match cb.action_data().cast_ref(){
282 ActionData::RunTarget{target, binary_id}=>{
283 if change{
284 build_manager.start_active_build(cx, *binary_id, *target);
285 }
286 else{
287 build_manager.stop_active_build(cx, *binary_id, *target);
288 }
289 }
290 ActionData::RunMain{binary_id}=>{
291 for i in 0..if change{1}else{BuildTarget::len()} {
292 let target = BuildTarget::from_id(i);
293 if change{
294 build_manager.start_active_build(cx, *binary_id, target);
295 }
296 else{
297 build_manager.stop_active_build(cx, *binary_id, target);
298 }
299 cx.action(AppAction::ClearLog);
300 }
301 }
302 _=>()
303 }
304 }
305 }
306 }
307}
308
309impl Widget for RunList {
310
311 fn draw_walk(&mut self, cx: &mut Cx2d, scope:&mut Scope, walk:Walk)->DrawStep{
312 while let Some(item) = self.view.draw_walk(cx, scope, walk).step(){
313 if let Some(mut list) = item.as_flat_list().borrow_mut(){
314 self.draw_run_list(cx, &mut *list, &mut scope.data.get_mut::<AppData>().unwrap().build_manager)
315 }
316 }
317 DrawStep::done()
318 }
319
320 fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope){
321 self.widget_match_event(cx, event, scope);
322 self.view.handle_event(cx, event, scope);
323 }
324}
325
326impl BuildManager {
327
328}