Diff of /src/style.kv [000000] .. [fcbb05]

Switch to unified view

a b/src/style.kv
1
#:kivy 1.10.0
2
#:import color src.color
3
#:import util src.util
4
5
<Widget>:
6
    font_name: 'Roboto-Bold'
7
    font_size: 16
8
9
<Spacer@Widget>:
10
    size_hint: 1, 1
11
12
<HSpacer@Widget>:
13
    size_hint: 1, None
14
15
<VSpacer@Widget>:
16
    size_hint: None, 1
17
    
18
<HDivider@Widget>:
19
    size_hint: 1, None
20
    height: 3
21
22
    canvas.before:
23
        Color:
24
            rgba: 0, 0, 0, .08
25
        Rectangle:
26
            pos: self.pos
27
            size: self.size
28
29
<LeftLabel@Label>:
30
    font_name: 'Roboto'
31
    size_hint: None, None
32
    color: .4, .4, .4, 1
33
    halign: 'left'
34
35
    on_texture_size:
36
        self.width = 40 + self.texture.width
37
        self.height = self.texture.height
38
39
<TextButton@Button>:
40
    background_normal: ''
41
    background_color: 0, 0, 0, 0
42
43
    size_hint: None, None
44
    bold: True
45
    color: color.B4 if self.state == 'normal' else color.B3
46
47
    halign: 'left'
48
49
    canvas.before:
50
        Color:
51
            rgba: (0, 0, 0, .01) if self.state != 'normal' else (0, 0, 0, 0)
52
        RoundedRectangle:
53
            size: self.size
54
            pos: self.pos
55
56
    on_texture_size:
57
        self.width = 40 + self.texture.width
58
        self.height = self.texture.height
59
60
61
<Card@BoxLayout>:
62
    size_hint: None, None
63
    
64
    orientation: 'vertical'
65
66
    background_color: 0, 0, 0, 0
67
    bg_color: 1, 1, 1, 1
68
69
    radius: 20
70
    canvas.before:
71
        Rectangle:
72
            size: self.size[0] + 2 * self.radius, self.size[1] + 2 * self.radius
73
            pos: self.pos[0] - self.radius, self.pos[1] - 1.5 * self.radius
74
            texture: color.createBoxShadow(self.size[0] + self.radius, self.size[1] + self.radius, 0.8 * self.radius, 0.4)
75
76
        Color:
77
            rgba: self.bg_color
78
        Rectangle:
79
            size: self.size
80
            pos: self.pos
81
82
<Chip>:
83
    size_hint: None, None
84
    height: self.minimum_height
85
    width: self.minimum_width
86
87
    radius: 5
88
89
    selected: True
90
    text: ''
91
92
    canvas.before:
93
        Rectangle:
94
            size: self.size[0] + 2 * self.radius, self.size[1] + 2 * self.radius
95
            pos: self.pos[0] - self.radius, self.pos[1] - 1.5 * self.radius
96
            texture: color.createBoxShadow(self.size[0] + self.radius, self.size[1] + self.radius, self.radius, 0.3)
97
        Color:
98
            rgb: (.85, .85, .85) if self.selected else (.95, .95, .95)
99
        RoundedRectangle:
100
            size: self.size
101
            pos: self.pos
102
            radius: [4]
103
104
<ChipInput>:
105
    padding: [10, 0, 5, 0]
106
    spacing: 0
107
108
    hint_text: ''
109
    TextInput:
110
        id: input
111
        background: ''
112
        background_color: 0, 0, 0, 0
113
114
        multiline: False
115
116
        font_name: 'Roboto'
117
        size_hint: None, None
118
        size: 80, self.minimum_height - 2
119
120
        hint_text: self.hint_text
121
122
        on_text_validate:
123
            root.submit()
124
        on_text:
125
            self.width = max(80, 20 + self._lines_labels[0].size[0] if self._lines_labels else 0)            
126
        canvas.before:
127
            Color:
128
                rgb: .4, .4, .4
129
130
<ChipInputAdder>:
131
    padding: [10, 0, 5, 0]
132
    spacing: 0
133
134
    hint_text: ''
135
136
    TextInput:
137
        id: input
138
        background: ''
139
        background_color: 0, 0, 0, 0
140
141
        multiline: False
142
143
        font_name: 'Roboto'
144
        size_hint: None, None
145
        size: 80, self.minimum_height - 2
146
147
        hint_text: self.hint_text
148
149
        on_text_validate:
150
            root.submit()
151
        on_text:
152
            self.width = max(80, 20 + self._lines_labels[0].size[0] if self._lines_labels else 0)            
153
        canvas.before:
154
            Color:
155
                rgb: .4, .4, .4
156
157
    Button:
158
        size_hint: None, 1
159
        width: self.height
160
161
        background_normal: ''
162
        background_color: 0, 0, 0, 0
163
164
        canvas.before:
165
            Color:
166
                rgba: (.6, .6, .6, 1) if self.state == 'normal' else (.5, .5, .5, 1)
167
            Line:
168
                points: [self.pos[0] + self.height * .3, self.pos[1] + self.height * .5, self.pos[0] + self.height * .7, self.pos[1] + self.height * .5]
169
                width: self.height / 20
170
                cap: 'square'
171
            Line:
172
                points: [self.pos[0] + self.height * .5, self.pos[1] + self.height * .3, self.pos[0] + self.height * .5, self.pos[1] + self.height * .7]
173
                width: self.height / 20
174
                cap: 'square'
175
        on_press:
176
            root.submit()
177
178
<ChipRemovable>:
179
    selected: False
180
181
    padding: [10, 5, 5, 5]
182
    spacing: 10
183
184
    Label:
185
        font_name: 'Roboto'
186
        size_hint: None, None
187
        color: .4, .4, .4, 1
188
        halign: 'left'
189
190
        text: root.text
191
192
        on_texture_size:
193
            self.size = self.texture.size
194
195
    Button:
196
        id: btn_remove
197
198
        size_hint: None, 1
199
        width: self.height
200
201
        background_normal: ''
202
        background_color: 0, 0, 0, 0
203
204
        canvas.before:
205
            Color:
206
                rgba: (.6, .6, .6, 1) if self.state == 'normal' else (.5, .5, .5, 1)
207
            Line:
208
                points: [self.pos[0] + self.height * .3, self.pos[1] + self.height * .3, self.pos[0] + self.height * .7, self.pos[1] + self.height * .7]
209
                width: self.height / 20
210
            Line:
211
                points: [self.pos[0] + self.height * .3, self.pos[1] + self.height * .7, self.pos[0] + self.height * .7, self.pos[1] + self.height * .3]
212
                width: self.height / 20
213
        
214
        on_press:
215
            root.remove()
216
217
218
<Body@Card>:
219
    orientation: 'vertical'
220
    size_hint: 1, None
221
    pos_hint: { 'center_x': .5, 'center_y': .5 }
222
    
223
    padding: 20
224
    spacing: 20
225
226
<HPage@ScrollView>:
227
    do_scroll_x: False
228
    do_scroll_y: True
229
<HPageBox@BoxLayout>:
230
    orientation: 'vertical'
231
    size_hint: 1, None
232
    height: self.minimum_height
233
    padding: 20
234
<HPageBody@Body>:
235
    height: self.minimum_height
236
<HTitle@Label>:
237
    size_hint: 1, None
238
    height: 40
239
    color: .4, .4, .4, 1
240
    font_name: 'RobotoMono-Regular'
241
<HStack@StackLayout>:
242
    size_hint: 1, None
243
    height: self.minimum_height
244
    spacing: 10
245
246
247
<PopupFileLoader>:
248
    size_hint: None, None
249
    size: 500, 500
250
251
    title: ''
252
    title_color: .4, .4, .4, 1
253
254
    background: ''
255
    background_color: 0, 0, 0, 0
256
    separator_height: 0
257
258
    radius: 10
259
    file_path: None
260
261
    canvas.before:
262
        Color:
263
            rgba: 1, 1, 1, 1
264
        Rectangle:
265
            size: self.size[0] + 2 * self.radius, self.size[1] + 2 * self.radius
266
            pos: self.pos[0] - self.radius, self.pos[1] - 2 * self.radius
267
            texture: color.createBoxShadow(self.size[0] + self.radius, self.size[1] + self.radius, self.radius, 0.4)
268
269
    BoxLayout:
270
        orientation: 'vertical'
271
        FileChooserListView:
272
            id: file_chooser
273
            color: 0, 0, 0, 1
274
 
275
            dirselect: True
276
            path: util.samples_dir
277
 
278
            on_selection:
279
                root.selectFile(args[1])
280
            on_submit:
281
                root.submitFile()
282
        BoxLayout:
283
            size_hint: 1, None
284
            height: self.minimum_height + 10
285
286
            TextButton:
287
                text: 'SELECT'
288
                on_press:
289
                    root.submitFile()
290
            TextButton:
291
                text: 'CLOSE'
292
                on_press:
293
                    root.dismiss()
294
295
<FileChooserListView>:
296
    layout: layout
297
    FileChooserListLayout:
298
        id: layout
299
        controller: root
300
301
[FileListEntry@FloatLayout+TreeViewNode]:
302
    locked: False
303
    entries: []
304
    path: ctx.path
305
    is_selected: self.path in ctx.controller().selection
306
307
    orientation: 'horizontal'
308
    size_hint_y: None
309
    height: '48dp' if dp(1) > 1 else '24dp'
310
    is_leaf: not ctx.isdir or ctx.name.endswith('..' + ctx.sep) or self.locked
311
    on_touch_down: self.collide_point(*args[1].pos) and ctx.controller().entry_touched(self, args[1])
312
    on_touch_up: self.collide_point(*args[1].pos) and ctx.controller().entry_released(self, args[1])
313
    BoxLayout:
314
        pos: root.pos
315
        size_hint_x: None
316
        width: root.width - dp(10)
317
318
        Label:
319
            color: .4, .4, .4, 1
320
            id: filename
321
            text_size: self.width, None
322
            halign: 'left'
323
            shorten: True
324
            text: ctx.name
325
        Label:
326
            color: .4, .4, .4, 1
327
            text_size: self.width, None
328
            size_hint_x: None
329
            halign: 'right'
330
            text: '{}'.format(ctx.get_nice_size())
331
332
333
<ScreenCard@Card>:
334
    width: min(600, self.parent.width - 40)
335
336
    padding: 20
337
    spacing: 8
338
339
<StartScreenLabel@Label>:
340
    size_hint: None, None
341
    bold: True
342
    color: .4, .4, .4, 1
343
344
    halign: 'left'
345
346
    on_texture_size:
347
        self.width = 40 + (self.texture.width if self.text else 0)
348
        self.height = self.texture.height
349
350
<SpaceStart>:
351
    HPage:
352
        HPageBox:
353
            HPageBody:
354
                pos_hint: { 'center_x': .5, 'center_y': .5 }
355
356
                size_hint: None, None
357
                width: min(900, 0.8 * root.width)
358
                height: max(0.9 * root.height, self.minimum_height)
359
360
                HTitle:
361
                    font_size: 40
362
                    text: 'APOS'
363
                HTitle:
364
                    font_name: 'Roboto'
365
                    color: color.B3
366
                    font_size: 20
367
                    bold: True
368
                    text: 'Advanced Pathology OS'
369
370
                ScreenCard:
371
                    height: 130
372
                    StartScreenLabel:
373
                        text: 'START'
374
                        
375
                    HSpacer:
376
                        height: 3
377
                    TextButton:
378
                        text: 'Create slide'
379
                        on_press:
380
                            app.root.ids.workspace.transition.direction = 'left'
381
                            app.root.ids.workspace.current = 'screen_createslide'
382
                    TextButton:
383
                        text: 'Analyze slide'
384
                        on_press:
385
                            app.root.ids.workspace.transition.direction = 'left'
386
                            app.root.ids.workspace.current = 'screen_analyze'
387
                    Spacer:
388
389
                ScreenCard:
390
                    height: 130
391
                    StartScreenLabel:
392
                        text: 'TRAIN'
393
                    HSpacer:
394
                        height: 3
395
                    TextButton:
396
                        text: 'Create disease filter'
397
                        on_press:
398
                            app.root.ids.workspace.transition.direction = 'right'
399
                            app.root.ids.workspace.current = 'screen_train'
400
                    TextButton:
401
                        text: 'Categorize training data'
402
                        on_press:
403
                            app.root.ids.workspace.transition.direction = 'right'
404
                            app.root.ids.workspace.current = 'screen_categorize'
405
                    Spacer:
406
                
407
                ScreenCard:
408
                    height: 100
409
                
410
                    StartScreenLabel:
411
                        text: 'MISCELLANEOUS'
412
                    HSpacer:
413
                        height: 3
414
                    TextButton: 
415
                        text: 'System Info'
416
                        on_press:
417
                            app.root.ids.workspace.transition.direction = 'up'
418
                            app.root.ids.workspace.current = 'screen_credits'
419
                    Spacer:
420
421
                Spacer:
422
423
                LeftLabel:
424
                    font_size: 13
425
                    font_name: 'RobotoMono-Regular'
426
                    text: util.app_creators
427
428
429
430
<ReturnToMain@TextButton>:
431
    text: 'BACK'
432
    dir: 'right'
433
434
    on_press:
435
        app.root.ids.workspace.transition.direction = self.dir
436
        app.root.ids.workspace.current = 'screen_start'
437
438
<SpaceCreateSlide>:
439
    HPage:
440
        HPageBox:
441
            HPageBody:
442
                TextButton:
443
                    text: 'BACK'
444
                    on_press:
445
                        app.root.ids.workspace.current = 'screen_start'
446
                        app.root.ids.workspace.transition.direction = 'right'
447
448
                HTitle:
449
                    text: 'Create Slide'
450
                HDivider:
451
452
                ImagePlot:
453
                    size: 600, 600
454
                    id: plot
455
                
456
                HDivider:
457
458
                HStack:
459
                    LeftLabel:
460
                        text: 'IP address'
461
                    ChipInput:
462
                        hint_text: 'Ip Address'
463
                        callback: root.set_ip
464
                
465
                HStack:
466
                    TextButton:
467
                        id: btn_start
468
                        text: 'Start Webcam'
469
                        on_press:
470
                            root.toggle_webcam()
471
                    TextButton:
472
                        text: 'Capture Image'
473
                        on_press:
474
                            root.capture()
475
<FilterApply>:
476
    size_hint: None, None
477
    size: 400, 80
478
479
    radius: 8
480
    padding: 5
481
482
    text: ''
483
484
    canvas.before:
485
        Color:
486
            rgba: 1, 1, 1, 1
487
        Rectangle:
488
            size: self.size[0] + 2 * self.radius, self.size[1] + 2 * self.radius
489
            pos: self.pos[0] - self.radius, self.pos[1] - 1.5 * self.radius
490
            texture: color.createBoxShadow(self.size[0] + self.radius, self.size[1] + self.radius, 0.8 * self.radius, 0.3)
491
        
492
        Color:
493
            rgba: 1, 1, 1, 1
494
        Rectangle:
495
            size: self.size
496
            pos: self.pos
497
498
    LeftLabel:
499
        font_name: 'RobotoMono-Regular'
500
501
        color: .4, .4, .4, 1
502
        text: root.text
503
    
504
    HSpacer:
505
        height: 10
506
    HStack:
507
        TextButton:
508
            id: btn_train
509
            text: 'Analyze'
510
            on_press:
511
                root.analysis_callback()
512
        TextButton:
513
            id: btn_reset
514
            text: 'Reset'
515
            on_press:
516
                root.reset()
517
 
518
519
520
<SpaceAnalyze>:
521
    HPage:
522
        HPageBox:
523
            HPageBody:
524
                TextButton:
525
                    text: 'BACK'
526
                        
527
                    on_press:
528
                        app.root.ids.workspace.transition.direction = 'right'
529
                        app.root.ids.workspace.current = 'screen_start'
530
531
                HTitle:
532
                    text: 'Analyze Slide'
533
534
                HDivider:
535
536
                HStack:
537
                    ImageLoader:
538
                        size: 450, 450    
539
                        id: slide
540
                    ImagePlot:
541
                        size: 450, 450    
542
                        id: sub_sample
543
544
                TextButton:
545
                    text: 'Select Slide'
546
                    on_press:
547
                        root.ids.slide.popup_selectImage()
548
549
                HDivider:
550
551
                LeftLabel:
552
                    font_name: 'RobotoMono-Regular'
553
                    text: 'REPORT'
554
                    bold: True
555
                LeftLabel:
556
                    font_name: 'RobotoMono-Regular'
557
                    id: info
558
                    text: ''
559
    
560
                HDivider:
561
562
                TextButton:
563
                    text: 'Reload Filters'
564
                    on_press:
565
                        root.loadFilters()
566
                HStack:
567
                    id: filter_list
568
569
<FilterTrain>:
570
    size_hint: None, None
571
    size: 600, 400
572
573
    radius: 8
574
    padding: 5
575
576
    text: ''
577
578
    canvas.before:
579
        Color:
580
            rgba: 1, 1, 1, 1
581
        Rectangle:
582
            size: self.size[0] + 2 * self.radius, self.size[1] + 2 * self.radius
583
            pos: self.pos[0] - self.radius, self.pos[1] - 1.5 * self.radius
584
            texture: color.createBoxShadow(self.size[0] + self.radius, self.size[1] + self.radius, 0.8 * self.radius, 0.3)
585
        
586
        Color:
587
            rgba: 1, 1, 1, 1
588
        Rectangle:
589
            size: self.size
590
            pos: self.pos
591
592
    LeftLabel:
593
        font_name: 'RobotoMono-Regular'
594
595
        color: .4, .4, .4, 1
596
        text: root.text
597
598
    HSpacer:
599
        height: 10
600
    HStack:
601
        TextButton:
602
            id: btn_train
603
            text: 'Train'
604
            on_press:
605
                root.train()
606
                root.ids.btn_save.text = 'Save'
607
        TextButton:
608
            id: btn_save
609
            text: ''
610
            on_press:
611
                text: 'Saving ...'
612
                root.save()
613
        
614
<SpaceTrain>:
615
    HPage:
616
        HPageBox:
617
            HPageBody:
618
                ReturnToMain:
619
                    dir: 'left'
620
621
                HTitle:
622
                    text: 'Create Filter'
623
            
624
                HDivider:
625
            
626
                HStack:
627
                    ImagePlot:
628
                        id: plot
629
630
                HStack:
631
                    TextButton:
632
                        text: 'Load Filters'
633
                        on_press:
634
                            root.load_filters()
635
                
636
                HDivider:
637
                HStack:
638
                    id: filter_editor
639
640
<SpaceFixedBody@Body>:
641
    size_hint: .9, .8
642
    size_hint_max: 1000, 800
643
    size_hint_min: 500, 500
644
645
646
647
<SpaceCategorize>:
648
    slide_img: None
649
    
650
    HPage:
651
        HPageBox:
652
            HPageBody: 
653
                TextButton:
654
                    text: 'BACK'
655
                    dir: 'right'
656
657
                    on_press:
658
                        app.root.ids.workspace.transition.direction = self.dir
659
                        app.root.ids.workspace.current = 'screen_start'
660
661
                HTitle:
662
                    text: 'Categorize'
663
664
                StackLayout:
665
                    size_hint: 1, None
666
                    width: self.minimum_width
667
                    height: self.minimum_height
668
                    spacing: 10
669
670
                    ImageLoader:
671
                        size: 350, 350
672
                        id: slide
673
                    
674
                    ImageLoader:
675
                        size: 350, 350
676
                        id: sub_sample
677
678
<SpaceCredits>:
679
    SpaceFixedBody:
680
        ReturnToMain:
681
            dir: 'down'
682
        Label:
683
            color: .4, .4, .4, 1
684
            text: util.app_credits
685
            font_name: 'RobotoMono-Regular'
686
            size_hint: 1, .5
687
688
<MainWindow>:
689
    title: 'MicroLab - DeepStain'
690
    WorkSpace:
691
        id: workspace