Diff of /dosma/gui/dosma_gui.py [000000] .. [030aeb]

Switch to side-by-side view

--- a
+++ b/dosma/gui/dosma_gui.py
@@ -0,0 +1,149 @@
+import inspect
+import tkinter as tk
+from tkinter import IntVar
+from typing import Dict
+
+import Pmw
+
+from dosma.cli import SEGMENTATION_MODEL_KEY, SEGMENTATION_WEIGHTS_DIR_KEY
+from dosma.gui.gui_utils import gui_utils as gutils
+from dosma.models import SUPPORTED_MODELS
+from dosma.models.seg_model import SegModel
+from dosma.tissues.tissue import Tissue
+
+
+class ScanReader:
+    def __init__(self, parent):
+        self.parent = parent
+        self.hbox = None
+        self.action_box = None
+        self.params: Dict = {}
+        self.action_var = None
+        self._action_bool = IntVar()
+        self.balloon = None
+
+    def load_scan(self, scan_class):
+        self._action_bool = IntVar()
+        if self.hbox:
+            self.hbox.destroy()
+        if self.action_box:
+            self.action_box.destroy()
+        self.action_var = None
+        self.balloon = Pmw.Balloon()
+
+        cmd_line_actions = scan_class.cmd_line_actions()
+        hbox = tk.Frame(self.parent)
+        hbox.pack(anchor="nw", side="top")
+
+        buttons = []
+        count = 0
+        for a_method, a_description in cmd_line_actions:
+            b = tk.Radiobutton(
+                hbox,
+                text=a_description.name,
+                value=count,
+                command=lambda v=(a_method, a_description): self.show_action_params(v[0], v[1]),
+                variable=self._action_bool,
+            )
+            self.balloon.bind(b, a_description.help)
+            buttons.append(b)
+            count += 1
+
+        self._action_bool.set(-1)
+
+        for b in buttons:
+            b.pack(anchor="nw", side="left", padx=5)
+
+        self.hbox = hbox
+
+    def show_action_params(self, action, action_wrapper):
+        self.action_var = action_wrapper.name
+        if self.action_box:
+            self.action_box.destroy()
+
+        if self.params:
+            self.params = {}
+
+        hbox = tk.Frame(self.parent)
+        hbox.pack(anchor="nw", side="top")
+        self.action_box = hbox
+
+        func_signature = inspect.signature(action)
+        parameters = func_signature.parameters
+
+        for param_name in parameters.keys():
+            param = parameters[param_name]
+            param_type = param.annotation
+            param_default = param.default
+
+            if param_name == "self" or param_type is Tissue:
+                continue
+
+            # # see if the type is a custom type, if not handle it as a basic type
+            is_custom_arg = param_type in CUSTOM_TYPE_TO_GUI
+            if is_custom_arg:
+                CUSTOM_TYPE_TO_GUI[param_type](self.params, hbox, self.balloon)
+                continue
+
+            param_var = gutils.convert_base_type_to_gui(
+                param_name,
+                param_type,
+                param_default,
+                hbox,
+                balloon=self.balloon,
+                param_help=action_wrapper.get_param_help(param_name),
+            )
+
+            # map parameter name --> variable, is_required
+            # if you have a non zero default value, it must be specified.
+            is_required = (param_type is not bool and param_default == inspect._empty) or (
+                param_type in [float, int] and bool(param_default)
+            )
+            self.params[param_name] = (param_var, is_required)
+
+    def get_cmd_line_str(self):
+        if not self.action_var:
+            raise ValueError("No action selected. Select an action to continue.")
+        cmd_line_str = "%s" % self.action_var
+        for param_name in self.params:
+            param_var, add_arg = self.params[param_name]
+
+            if add_arg and not param_var.get():
+                raise ValueError('"%s" must have a value' % param_name)
+
+            if param_var.get():
+                cmd_line_str += " --%s" % param_name
+                if add_arg:
+                    cmd_line_str += " %s" % param_var.get()
+
+        return cmd_line_str
+
+
+def add_segmentation_gui_parser(params, hbox, balloon):
+    # add model
+    param_name, param_type, param_default = SEGMENTATION_MODEL_KEY, str, None
+    param_var = gutils.convert_base_type_to_gui(
+        param_name,
+        param_type,
+        param_default,
+        hbox,
+        balloon=balloon,
+        param_help="segmentation models",
+        options=SUPPORTED_MODELS,
+    )
+    params[param_name] = (param_var, param_type is not bool)
+
+    # add weights directory
+    param_name, param_type, param_default = SEGMENTATION_WEIGHTS_DIR_KEY, str, None
+    param_var = gutils.convert_base_type_to_gui(
+        param_name,
+        param_type,
+        param_default,
+        hbox,
+        balloon=balloon,
+        param_help="path to weights directory",
+    )
+    params[param_name] = (param_var, param_type is not bool)
+
+
+CUSTOM_TYPE_TO_GUI = {SegModel: add_segmentation_gui_parser}