mirror of
https://github.com/Cian-H/Melter.git
synced 2026-08-08 14:43:25 +01:00
First functioning version of app!
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
from kivy.event import EventDispatcher
|
||||
from kivy.properties import BooleanProperty
|
||||
from kivy.uix.textinput import TextInput
|
||||
from io import StringIO
|
||||
|
||||
|
||||
# This variation of StringIO communicates back to parent observer
|
||||
class ObservableStringIO(StringIO):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if "observer" in kwargs:
|
||||
self.observer = kwargs.pop("observer")
|
||||
super(ObservableStringIO, self).__init__(*args, **kwargs)
|
||||
|
||||
def write(self, *args, **kwargs):
|
||||
# Just need to flip trigger on write. Specific value doesnt matter
|
||||
self.observer.trigger = not self.observer.trigger
|
||||
super(ObservableStringIO, self).write(*args, **kwargs)
|
||||
|
||||
|
||||
# This StringIO wrapper object outputs string from io to target on every write
|
||||
class StringIO_toString_Observer(EventDispatcher):
|
||||
trigger = BooleanProperty()
|
||||
|
||||
def __init__(self, target, **kwargs):
|
||||
self.io_buffer = ObservableStringIO(observer=self)
|
||||
self.trigger = False # <- val doesnt matter as long a bool
|
||||
self.target = target
|
||||
self.target.text = str(self.io_buffer.getvalue())
|
||||
super(StringIO_toString_Observer, self).__init__(**kwargs)
|
||||
|
||||
def on_trigger(self, instance, value):
|
||||
self.target.text = str(self.io_buffer.getvalue())
|
||||
|
||||
|
||||
# This console output widget can output io streams if redirected to its
|
||||
# io_buffer property
|
||||
class ConsoleOutput(TextInput):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Define and apply default kwargs
|
||||
defaultkwargs = {"readonly": True,
|
||||
"background_color": (0, 0, 0, 1),
|
||||
"foreground_color": (1, 1, 1, 1)}
|
||||
kwargs = {k: (v if k not in kwargs else kwargs[k])
|
||||
for k, v in defaultkwargs.items()}
|
||||
# Then call super
|
||||
super(ConsoleOutput, self).__init__(*args, **kwargs)
|
||||
# Then add observer and ref to io_buffer for ease-of-use
|
||||
self.observer = StringIO_toString_Observer(self)
|
||||
self.io_buffer = self.observer.io_buffer
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# *_* coding: utf-8 *_*
|
||||
|
||||
# Kivy module imports
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.dropdown import DropDown
|
||||
|
||||
|
||||
class DropdownButton(Button):
|
||||
def __init__(self, option_list=None, **kwargs):
|
||||
# ensure "text" kwarg isnt present
|
||||
if "test" in kwargs:
|
||||
kwargs.pop("test")
|
||||
|
||||
# Add default args if they're not specifically assigned
|
||||
self.defaultkwargs = \
|
||||
{"background_color": [x*0.75 for x in self.background_color],
|
||||
}
|
||||
|
||||
for keyword, arg in self.defaultkwargs.items():
|
||||
if keyword not in kwargs:
|
||||
kwargs[keyword] = arg
|
||||
|
||||
self.kwargs = kwargs
|
||||
super(DropdownButton, self).__init__(**self.kwargs)
|
||||
|
||||
# Create lambdas for callbacks
|
||||
self.__bind_button = lambda btn: self.dropdown_list.select(btn.text)
|
||||
self.__update_label = lambda instance, x: setattr(self, "text", x)
|
||||
|
||||
if option_list is not None:
|
||||
self.populate_dropdown(option_list)
|
||||
|
||||
def populate_dropdown(self, option_list):
|
||||
kwargs = self.kwargs.copy()
|
||||
kwargs["size_hint_y"] = None
|
||||
if "height" not in kwargs:
|
||||
kwargs["height"] = 50
|
||||
if "__no_builder" in kwargs:
|
||||
kwargs.pop("__no_builder")
|
||||
|
||||
self.dropdown_list = None
|
||||
self.dropdown_list = DropDown()
|
||||
|
||||
for x in option_list:
|
||||
button = Button(text=x, **kwargs)
|
||||
# button = Button(text=x, size_hint_y=None, height=50)
|
||||
button.bind(on_release=self.__bind_button)
|
||||
self.dropdown_list.add_widget(button)
|
||||
|
||||
self.bind(on_release=self.dropdown_list.open)
|
||||
self.dropdown_list.bind(on_select=self.__update_label)
|
||||
@@ -0,0 +1,29 @@
|
||||
# file_chooser_popup.kv
|
||||
#:kivy 2.0
|
||||
#:import path os.path.expanduser
|
||||
|
||||
<FileChooserPopup>:
|
||||
title: "Choose a data folder"
|
||||
size_hint: .9, .9
|
||||
auto_dismiss: False
|
||||
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
FileChooser:
|
||||
id: filechooser
|
||||
path: path("~")
|
||||
dirselect: True
|
||||
FileChooserIconLayout
|
||||
|
||||
BoxLayout:
|
||||
size_hint: (1, 0.1)
|
||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||
spacing: 20
|
||||
Button:
|
||||
text: "Cancel"
|
||||
on_release: root.dismiss()
|
||||
Button:
|
||||
text: "Load"
|
||||
on_release: root.load(filechooser.selection)
|
||||
id: ldbtn
|
||||
disabled: True if filechooser.selection==[] else False
|
||||
@@ -0,0 +1,63 @@
|
||||
# input_output_chooser.kv
|
||||
#:kivy 2.0
|
||||
|
||||
# Widget:
|
||||
<InputOutputChooser>:
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
# First item is the input file directory chooser in stacked layout
|
||||
StackLayout:
|
||||
orientation: "lr-tb"
|
||||
size_hint_y: None
|
||||
size_hint_x: 1.
|
||||
height: 30
|
||||
spacing: 5
|
||||
|
||||
BoxLayout:
|
||||
size_hint_x: 1.
|
||||
# Containing a description of what the field points to
|
||||
Label:
|
||||
halign: "right"
|
||||
text: "Layer data directory:"
|
||||
size_hint_x: None
|
||||
width: 160
|
||||
# A textbox for filepath entry
|
||||
TextInput:
|
||||
id: in_path
|
||||
readonly: True
|
||||
hint_text: "Read pyrometry data from..."
|
||||
# A button that opens the file chooser popup
|
||||
Button:
|
||||
text: "Choose Folder"
|
||||
size_hint_x: None
|
||||
width: 120
|
||||
on_press: root.open_chooser("in_path")
|
||||
|
||||
# Second item is the output file directory chooser in stacked layout
|
||||
StackLayout:
|
||||
orientation: "lr-tb"
|
||||
size_hint_y: None
|
||||
size_hint_x: 1.
|
||||
height: 30
|
||||
spacing: 5
|
||||
|
||||
BoxLayout:
|
||||
size_hint_x: 1.
|
||||
# Containing a description of what the field points to
|
||||
Label:
|
||||
halign: "right"
|
||||
text: "Output directory:"
|
||||
size_hint_x: None
|
||||
width: 160
|
||||
# A textbox for filepath entry
|
||||
TextInput:
|
||||
id: out_path
|
||||
readonly: True
|
||||
hint_text: "Output figures to..."
|
||||
# A button that opens the file chooser popup
|
||||
Button:
|
||||
text: "Choose Folder"
|
||||
size_hint_x: None
|
||||
width: 120
|
||||
on_press:
|
||||
root.open_chooser("out_path")
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
# *_* coding: utf-8 *_*
|
||||
|
||||
# Kivy module imports
|
||||
from kivy.lang.builder import Builder
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.properties import ObjectProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
# Other python module imports
|
||||
from types import SimpleNamespace
|
||||
|
||||
Builder.load_file("Templates/file_chooser_popup.kv")
|
||||
|
||||
|
||||
# Create classes for loaded kv files
|
||||
# This class contains the popup for choosing files
|
||||
class FileChooserPopup(Popup):
|
||||
load = ObjectProperty()
|
||||
|
||||
|
||||
class InputOutputChooser(BoxLayout):
|
||||
load = ObjectProperty()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InputOutputChooser, self).__init__(*args, **kwargs)
|
||||
starting_cache = {"popups": {}, # A dict to contain all popup objects
|
||||
"shared_io_choosers": False,
|
||||
"parent_app": False}
|
||||
self.cache = SimpleNamespace(**starting_cache)
|
||||
|
||||
# The functions "open" and "load" are used to load the file chooser popup
|
||||
def open_chooser(self, pathattr: str):
|
||||
# Wrapper function to allow for multiple different choosers
|
||||
def load_chooser_wrapper(selection):
|
||||
return self.load_chooser(pathattr, selection)
|
||||
|
||||
self.cache.popups[pathattr] = \
|
||||
FileChooserPopup(load=load_chooser_wrapper)
|
||||
self.cache.popups[pathattr].open()
|
||||
|
||||
def load_chooser(self, pathattr: str, selection):
|
||||
path_string = str(selection[0])
|
||||
setattr(self, pathattr, path_string)
|
||||
self.cache.popups[pathattr].dismiss()
|
||||
|
||||
# check for non-empty list i.e. file selected
|
||||
if pathattr in self.__dict__:
|
||||
# set own details based on selection
|
||||
id = getattr(self.ids, pathattr)
|
||||
id.text = getattr(self, pathattr)
|
||||
# set parameters for shared and parent if present
|
||||
if self.cache.shared_io_choosers:
|
||||
for chooser in self.cache.shared_io_choosers:
|
||||
id = getattr(chooser.ids, pathattr)
|
||||
id.text = getattr(self, pathattr)
|
||||
if self.cache.parent_app:
|
||||
setattr(self.cache.parent_app.cache, pathattr, path_string)
|
||||
@@ -0,0 +1,735 @@
|
||||
# melter_desktop.kv
|
||||
#:kivy 2.0
|
||||
#:include Templates/input_output_chooser.kv
|
||||
#:import InputOutputChooser Templates.input_output_chooser.InputOutputChooser
|
||||
#:import DropdownButton Templates.dropdown_button.DropdownButton
|
||||
#:import ConsoleOutput Templates.console_output.ConsoleOutput
|
||||
|
||||
|
||||
<Main>:
|
||||
name: "main_screen"
|
||||
id: main_screen
|
||||
TabbedPanel:
|
||||
id: test
|
||||
title: "Melter"
|
||||
do_default_tab: False
|
||||
# First tab is for loading data
|
||||
TabbedPanelItem:
|
||||
id: loading_tab
|
||||
text: "Data Loading"
|
||||
# UI made up of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_dataloading
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for loading data
|
||||
GridLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.8
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
cols: 1
|
||||
# This is the button and progress bar for loading data
|
||||
StackLayout:
|
||||
size_hint_y: 0.15
|
||||
orientation: "lr-tb"
|
||||
Button:
|
||||
size_hint_x: 0.25
|
||||
text: "Load Pyrometry Data"
|
||||
on_press: root.load_data()
|
||||
ProgressBar:
|
||||
id: read_layers_progbar
|
||||
size_hint_x: 0.75
|
||||
value: 0
|
||||
# A button that applies the calibration curve
|
||||
Button:
|
||||
text: "Apply Calibration Curve"
|
||||
size_hint_x: 0.25
|
||||
width: 120
|
||||
on_press: root.apply_calibration_curve()
|
||||
StackLayout:
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.5
|
||||
cols: 1
|
||||
rows: 2
|
||||
# Containing a description of what the field points to
|
||||
Label:
|
||||
halign: "right"
|
||||
text: "Calibration Curve"
|
||||
width: 160
|
||||
# A textbox for cal curve equation entry
|
||||
TextInput:
|
||||
halign: "center"
|
||||
valign: "center"
|
||||
id: calibration_curve
|
||||
readonly: False
|
||||
hint_text: "y = x"
|
||||
ProgressBar:
|
||||
id: cal_curve_progbar
|
||||
size_hint_x: 0.5
|
||||
value: 0
|
||||
# This label displays current status of data processing
|
||||
Label:
|
||||
id: dataloading_display
|
||||
text: "No data loaded!"
|
||||
halign: "center"
|
||||
valign: "center"
|
||||
|
||||
# Second tab is for detecting & separating samples
|
||||
TabbedPanelItem:
|
||||
id: detection_tab
|
||||
text: "Sample\nDetection"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_sampledetection
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for per sample data
|
||||
GridLayout:
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.75
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
cols: 1
|
||||
# Below is a tabbed panel for different thresholding methods
|
||||
TabbedPanel:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 0.25
|
||||
do_default_tab: False
|
||||
tab_pos: "left_top"
|
||||
tab_width: self.height
|
||||
# This is a messy solution, but uses a nested TabbedPanel
|
||||
# to label the threshold functions. Would prefer better
|
||||
# method. Maybe some kind of tooltip?
|
||||
TabbedPanelItem:
|
||||
text: "Thresholding\nTechniques"
|
||||
TabbedPanel:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 1.0
|
||||
do_default_tab: False
|
||||
tab_pos: "left_top"
|
||||
tab_width: self.height / 2
|
||||
# First tab is options for speed based thresholding
|
||||
TabbedPanelItem:
|
||||
text: "Speed"
|
||||
id: avgspeed_thresh_panel
|
||||
# Create a panel to hold items
|
||||
StackLayout:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 1.0
|
||||
orientation: "lr-tb"
|
||||
# Top panel contains buttons
|
||||
#:set avgspeed_toprowheight 30.
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - avgspeed_toprowheight) / 2
|
||||
# Here is the main options, held in center by spacers
|
||||
Label:
|
||||
text: "Thresholding percent:"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: None
|
||||
height: avgspeed_toprowheight
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: avgspeed_thresh_thresh_percent
|
||||
hint_text: "x < (% of max speed)"
|
||||
size_hint_y: None
|
||||
height: avgspeed_toprowheight
|
||||
size_hint_x: 0.25
|
||||
Label:
|
||||
text: "Rolling average:"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: None
|
||||
height: avgspeed_toprowheight
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: avgspeed_thresh_avgof
|
||||
hint_text: "n"
|
||||
size_hint_y: None
|
||||
height: avgspeed_toprowheight
|
||||
size_hint_x: 0.25
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - avgspeed_toprowheight) / 2
|
||||
# This button and progress bar trigger and track the
|
||||
# thresholding of data
|
||||
Button:
|
||||
text: "Threshold by rolling\naverage of speed"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.5
|
||||
on_press: root.avgspeed_threshold()
|
||||
ProgressBar:
|
||||
id: avgspeed_threshold_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.5
|
||||
value: 0
|
||||
|
||||
# Second tab is for tepmerature based thresholding
|
||||
TabbedPanelItem:
|
||||
text: "Temp"
|
||||
id: avgtemp_thresh_panel
|
||||
StackLayout:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 1.0
|
||||
orientation: "lr-tb"
|
||||
# Top panel contains buttons
|
||||
#:set avgtemp_toprowheight 30.
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - avgtemp_toprowheight) / 2
|
||||
# Here is the main options, held in center by spacers
|
||||
Label:
|
||||
text: "Keep points where: Temperature "
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: None
|
||||
height: avgtemp_toprowheight
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
DropdownButton:
|
||||
id: avgtemp_thresh_function_dropdown
|
||||
text: ">"
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: None
|
||||
height: avgtemp_toprowheight
|
||||
TextInput:
|
||||
id: avgtemp_thresh_thresh_percent
|
||||
hint_text: "x"
|
||||
size_hint_y: None
|
||||
height: avgtemp_toprowheight
|
||||
size_hint_x: 0.1
|
||||
Label:
|
||||
text: "% of maximum"
|
||||
size_hint_x: 0.3
|
||||
size_hint_y: None
|
||||
height: avgtemp_toprowheight
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - avgtemp_toprowheight) / 2
|
||||
# This button and progress bar trigger and track the
|
||||
# thresholding of data
|
||||
Button:
|
||||
text: "Threshold by\naverage temperature"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.5
|
||||
on_press: root.avgtemp_threshold()
|
||||
ProgressBar:
|
||||
id: avgtemp_threshold_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.5
|
||||
value: 0
|
||||
# The next piece contains controls for KMeans sample separation
|
||||
StackLayout:
|
||||
#:set kmeans_toprowheight 30.
|
||||
id: kmeans_panel
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 0.25
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - kmeans_toprowheight) / 2
|
||||
Label:
|
||||
text: "Number of Samples: "
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: None
|
||||
height: kmeans_toprowheight
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: kmeans_nsamples
|
||||
hint_text: "n"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: None
|
||||
height: kmeans_toprowheight
|
||||
# This label is a spacer
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: None
|
||||
height: ((self.parent.height / 2) - kmeans_toprowheight) / 2
|
||||
# This button and progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Separate Samples"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.5
|
||||
on_press: root.separate_samples()
|
||||
ProgressBar:
|
||||
id: kmeans_separate_samples_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.5
|
||||
value: 0
|
||||
|
||||
# The box below will display console output from kmeans
|
||||
ScrollView:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 0.5
|
||||
ConsoleOutput:
|
||||
id: kmeans_separate_console_output
|
||||
size_hint_x: 1.0
|
||||
|
||||
# Third tab is for generating whole buildplate figures
|
||||
TabbedPanelItem:
|
||||
id: plate_vis_tab
|
||||
text: "Buildplate\nVisualization"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_buildplate
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for buildplate plotting
|
||||
StackLayout:
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.8
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
orientation: "lr-tb"
|
||||
#:set row_y_hint 0.15
|
||||
#:set num_functions 3
|
||||
#:set spacer_y_hint ((1-(row_y_hint*num_functions*2))/(num_functions-1))
|
||||
|
||||
# First function on this panel (layers_to_figures) begins here
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: layers_to_figures_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
# Checkboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: layers_to_figures_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: layers_to_figures_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: layers_to_figures_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: layers_to_figures_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 2d\nbuidplate figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.layers_to_figures()
|
||||
ProgressBar:
|
||||
id: layers_to_figures_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
|
||||
# This spacer clearly separates panels for functions
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: spacer_y_hint
|
||||
|
||||
# Second function on this panel (layers_to_3dplot) begins here
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: layers_to_3dplot_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
# Checboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: layers_to_3dplot_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: layers_to_3dplot_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 3d\nbuidplate figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.layers_to_3dplot()
|
||||
ProgressBar:
|
||||
id: layers_to_3dplot_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
|
||||
# This spacer clearly separates panels for functions
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: spacer_y_hint
|
||||
|
||||
# Second function on this panel (layers_to_3dplot) begins here
|
||||
# First part of this panel will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "lr-tb"
|
||||
size_hint_x: 1.00
|
||||
size_hint_y: row_y_hint
|
||||
# Checkboxes for toggling plot colouring and colourbars
|
||||
# and downsampling factor input
|
||||
#:set one_third 1/3
|
||||
Label:
|
||||
text: "Downsampling: "
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: layers_to_3dplot_interactive_downsampling
|
||||
hint_text: "1"
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_interactive_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_interactive_sliceable
|
||||
active: True
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Sliceable model"
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: layers_to_3dplot_interactive_plotparams
|
||||
size_hint_x: 1.
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate interactive 3d\nbuidplate figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.layers_to_3dplot_interactive()
|
||||
ProgressBar:
|
||||
id: layers_to_3dplot_interactive_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
|
||||
# Fourth tab is for generating figures
|
||||
TabbedPanelItem:
|
||||
id: sample_vis_tab
|
||||
text: "Per Sample\nVisualization"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_persample
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for buildplate plotting
|
||||
StackLayout:
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.8
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
orientation: "lr-tb"
|
||||
#:set row_y_hint 0.15
|
||||
#:set num_functions 3
|
||||
#:set spacer_y_hint ((1-(row_y_hint*num_functions*2))/(num_functions-1))
|
||||
|
||||
# First function on this panel (layers_to_figures) begins here
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: samples_to_figures_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
# Checkboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: samples_to_figures_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: samples_to_figures_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: samples_to_figures_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: samples_to_figures_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 2d\nsample figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.samples_to_figures()
|
||||
ProgressBar:
|
||||
id: samples_to_figures_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
|
||||
# This spacer clearly separates panels for functions
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: spacer_y_hint
|
||||
|
||||
# Second function on this panel (layers_to_3dplot) begins here
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: samples_to_3dplot_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
# Checboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: samples_to_3dplot_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: samples_to_3dplot_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: samples_to_3dplot_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: samples_to_3dplot_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 3d\nsample figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.samples_to_3dplot()
|
||||
ProgressBar:
|
||||
id: samples_to_3dplot_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
|
||||
# This spacer clearly separates panels for functions
|
||||
Label:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: spacer_y_hint
|
||||
|
||||
# Second function on this panel (layers_to_3dplot) begins here
|
||||
# First part of this panel will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "lr-tb"
|
||||
size_hint_x: 1.00
|
||||
size_hint_y: row_y_hint
|
||||
# Checkboxes for toggling plot colouring and colourbars
|
||||
# and downsampling factor input
|
||||
#:set one_third 1/3
|
||||
Label:
|
||||
text: "Downsampling: "
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "right"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: samples_to_3dplot_interactive_downsampling
|
||||
hint_text: "1"
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: samples_to_3dplot_interactive_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
CheckBox:
|
||||
id: samples_to_3dplot_interactive_sliceable
|
||||
active: True
|
||||
size_hint_x: 0.25 * one_third
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Sliceable model"
|
||||
size_hint_x: 0.75 * one_third
|
||||
size_hint_y: 0.5
|
||||
text_size: self.size
|
||||
halign: "left"
|
||||
valign: "middle"
|
||||
TextInput:
|
||||
id: samples_to_3dplot_interactive_plotparams
|
||||
size_hint_x: 1.
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate interactive 3d\nsample figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: row_y_hint
|
||||
on_press: root.samples_to_3dplot_interactive()
|
||||
ProgressBar:
|
||||
id: samples_to_3dplot_interactive_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: row_y_hint
|
||||
value: 0
|
||||
@@ -0,0 +1,284 @@
|
||||
# melter_desktop.kv
|
||||
#:kivy 2.0
|
||||
#:include Templates/input_output_chooser.kv
|
||||
#:import InputOutputChooser Templates.input_output_chooser.InputOutputChooser
|
||||
#:import DropdownButton Templates.dropdown_button.DropdownButton
|
||||
|
||||
|
||||
<Main>:
|
||||
name: "main_screen"
|
||||
id: main_screen
|
||||
TabbedPanel:
|
||||
id: test
|
||||
title: "Melter"
|
||||
do_default_tab: False
|
||||
|
||||
# First tab is for loading data
|
||||
TabbedPanelItem:
|
||||
id: loading_tab
|
||||
text: "Data Loading"
|
||||
|
||||
# UI made up of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_dataloading
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for loading data
|
||||
GridLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.8
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
# spacing: 2.
|
||||
cols: 1
|
||||
# This is the button and progress bar for loading data
|
||||
StackLayout:
|
||||
size_hint_y: 0.15
|
||||
orientation: "lr-tb"
|
||||
Button:
|
||||
size_hint_x: 0.25
|
||||
text: "Load Pyrometry Data"
|
||||
on_press: root.load_data()
|
||||
ProgressBar:
|
||||
id: read_layers_progbar
|
||||
size_hint_x: 0.75
|
||||
value: 0.
|
||||
# A button that applies the calibration curve
|
||||
Button:
|
||||
text: "Apply Calibration Curve"
|
||||
size_hint_x: 0.25
|
||||
width: 120
|
||||
on_press: root.apply_calibration_curve()
|
||||
StackLayout:
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.5
|
||||
cols: 1
|
||||
rows: 2
|
||||
# Containing a description of what the field points to
|
||||
Label:
|
||||
halign: "right"
|
||||
text: "Calibration Curve"
|
||||
width: 160
|
||||
# A textbox for cal curve equation entry
|
||||
TextInput:
|
||||
halign: "center"
|
||||
valign: "center"
|
||||
id: calibration_curve
|
||||
readonly: False
|
||||
hint_text: "y = x"
|
||||
ProgressBar:
|
||||
id: cal_curve_progbar
|
||||
size_hint_x: 0.5
|
||||
value: 0.
|
||||
# This label displays current status of data processing
|
||||
Label:
|
||||
id: dataloading_display
|
||||
text: "No data loaded!"
|
||||
halign: "center"
|
||||
valign: "center"
|
||||
|
||||
# Second tab is for detecting & separating samples
|
||||
TabbedPanelItem:
|
||||
id: detection_tab
|
||||
text: "Sample\nDetection"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_sampledetection
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for per sample data
|
||||
GridLayout:
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.75
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
# spacing: 2.
|
||||
cols: 2
|
||||
Button:
|
||||
text: "Test 5"
|
||||
Button:
|
||||
text: "Test 6"
|
||||
Button:
|
||||
text: "Test 7"
|
||||
Button:
|
||||
text: "Test 8"
|
||||
|
||||
# Third tab is for generating whole buildplate figures
|
||||
TabbedPanelItem:
|
||||
id: plate_vis_tab
|
||||
text: "Buildplate\nVisualization"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_buildplate
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for buildplate plotting
|
||||
GridLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.8 # These the buttons and progress bar for the layers_to_figures function
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
cols: 1
|
||||
# These the buttons and progress bar for the layers_to_figures function
|
||||
StackLayout:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 1.0
|
||||
orientation: "lr-tb"
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: layers_to_figures_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.15
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.15
|
||||
# Checboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: layers_to_figures_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: layers_to_figures_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: layers_to_figures_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: layers_to_figures_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 2d\nbuidplate figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.15
|
||||
on_press: root.layers_to_figures()
|
||||
ProgressBar:
|
||||
id: layers_to_figures_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.15
|
||||
value: 0.
|
||||
# These the buttons and progress bar for the layers_to_figures function
|
||||
StackLayout:
|
||||
size_hint_x: 1.0
|
||||
size_hint_y: 0.15
|
||||
orientation: "lr-tb"
|
||||
# This button will be a dropdown
|
||||
DropdownButton:
|
||||
id: layers_to_3dplot_filetype_dropdown
|
||||
text: "select file type\n(png)"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.15
|
||||
# Right of the dropdown will be a suite of options
|
||||
StackLayout:
|
||||
orientation: "tb-lr"
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.15
|
||||
# Checboxes for toggling plot colouring and colourbars
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_plot_w
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
CheckBox:
|
||||
id: layers_to_3dplot_colorbar
|
||||
active: True
|
||||
size_hint_x: 0.1
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Colour by temperature"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
Label:
|
||||
text: "Display colourbar"
|
||||
size_hint_x: 0.4
|
||||
size_hint_y: 0.5
|
||||
# And text input for other figure parameters
|
||||
TextInput:
|
||||
id: layers_to_3dplot_figureparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Figure parameters..."
|
||||
TextInput:
|
||||
id: layers_to_3dplot_plotparams
|
||||
size_hint_x: 0.5
|
||||
size_hint_y: 0.5
|
||||
hint_text: "Plot parameters..."
|
||||
# This button an progress bar trigger and track the
|
||||
# generation of figures
|
||||
Button:
|
||||
text: "Generate static 3d\nbuidplate figures"
|
||||
size_hint_x: 0.25
|
||||
size_hint_y: 0.15
|
||||
on_press: root.layers_to_plot()
|
||||
ProgressBar:
|
||||
id: layers_to_3dplot_progbar
|
||||
size_hint_x: 0.75
|
||||
size_hint_y: 0.15
|
||||
value: 0.
|
||||
|
||||
# Fourth tab is for generating figures
|
||||
TabbedPanelItem:
|
||||
id: sample_vis_tab
|
||||
text: "Per Sample\nVisualization"
|
||||
|
||||
# Items are stacked from bottom to top. UI made of floating sub-layouts
|
||||
FloatLayout:
|
||||
|
||||
# First item is an InputOutputChooser
|
||||
InputOutputChooser:
|
||||
id: io_chooser_persample
|
||||
size_hint_x: 1.0
|
||||
pos_hint: {"x": 0., "y": 0.875}
|
||||
|
||||
# Second item is a grid layout filled with buttons
|
||||
# These buttons denote available functions for per sample data
|
||||
GridLayout:
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.75
|
||||
pos_hint: {"x": 0.05, "y": 0.05}
|
||||
# spacing: 2.
|
||||
cols: 2
|
||||
Button:
|
||||
text: "Test 9"
|
||||
Button:
|
||||
text: "Test 10"
|
||||
Button:
|
||||
text: "Test 11"
|
||||
Button:
|
||||
text: "Test 12"
|
||||
Reference in New Issue
Block a user