GUI Rework

TIMELINE:

TODO

TASKS:

0 controller re-organization

  • merge (on class level) controller and dock controller
  • separate files (compilation units) for initialization of models, docks, etc. but same class

1 async on-demand calculation

  • controllers manage subscriptions: subscribeImage(repr.::t) subscribeImageBand(rep.::t, int) subscribeLabeling(bool full/ROI – if needed) subscribeFalseColor(type, bool [full vs. ROI] for ROI selector) unsubscribe(…)
  • when new data is calculated, the controller checks subscriptions to notify about the new data
  • when data becomes invalid, controller checks for subscriptions before recalculation
  • unsubscribe triggers (deferred?) cancellation of computation or deletion of data: deferred deletion is a future feature, if we implement, have a timer that is started by unsubscribe and cancelled by subscribe
  • the controller knows when data becomes invalid

  • GUI objects/dock objects subscribe to data via controller, never ask for data directly, when they become hidden, they unsubscribe, they are always functional even if they have no data (robust)

  • GUI receives updates via subscriptionData() and subscriptionProgress() signals

  • document data chain (who needs what) while implementing the subscriptions

2 task groups

  • task groups in background task queue with identifiers: // id = queue.beginGroup(); // enqueue tasks // queue.endGroup(); // save id in own structure, e.g. “roiChangeID” for later cancelling

3 remove disableGUI/enableGUI, make GUI object robust

  • local control over GUI state (each GUI object knows when to disable)
  • use the result of tasks 1 & 2 to implement this

PRACTICES (guidelines):

  • Signals/slots between GUI and Controller, and GUI:
    • MainWindow connects button/etc. signals to own, generic signal (if it needs to do stuff later, it can change to local slot that will emit the generic signal)
    • Controller connects signal from MainWindow to DockController, DistviewController, etc. In this case we connect signal to signal, as controllers know each other
    • DistViewController connects its own signal to corresp. GUI components if DVController decides it needs to do stuff on its own, it will change to slot, signal and also change Controller signal connection to slot
  • if you change something: do it in a way that only the same layer needs to know about it (e.g. only other controllers, or only other GUI components, but not controllers and GUI components)
  • models never request or initiate actions from outside the model the controller has knowledge what input models need to do their calculation the controller also knows what model data becomes invalid when another model has new results. that means: controllers reset stuff, controllers ask for calculations and then hands the results over. models have no business logic.
  • GUI results (user action) are always channeled to the resp. model for updates, other components do not know about these results. Only model calculation results are distributed to GUI components.
  • representation handling:
    1. representations are effectively singletons
    2. all representations are equal exceptions: image model knows them by heart! GUI exposes some functionality only for some representations
    3. representations are identified by the ENUM, not by bool, int, etc.
    4. to cycle through: foreach (representation::t i, representation::all())
    5. are of type representation::t and are typically called “type” in an argument

FIX:

  • [DONE] remove ROI argument from backgroundtasks and roi member variables
  • spec_rescale copy data (?)
  • seg_felzenszwalb command compile problems