diff --git a/src/View/HydraulicStructures/PlotAC.py b/src/View/HydraulicStructures/PlotAC.py index 7c39ec19..e15efe34 100644 --- a/src/View/HydraulicStructures/PlotAC.py +++ b/src/View/HydraulicStructures/PlotAC.py @@ -42,7 +42,7 @@ class PlotAC(PamhyrPlot): self._isometric_axis = False self._auto_relim_update = True - self._autoscale_update = False + self._autoscale_update = True @property def river(self): diff --git a/src/View/HydraulicStructures/PlotRKC.py b/src/View/HydraulicStructures/PlotRKC.py index 4c4a982b..9ec4d052 100644 --- a/src/View/HydraulicStructures/PlotRKC.py +++ b/src/View/HydraulicStructures/PlotRKC.py @@ -30,6 +30,14 @@ _translate = QCoreApplication.translate class PlotRKC(PamhyrPlot): + # Class attributes: PlotRKZ (frictions) does not call this __init__ + _selected = None # Selected hydraulic structure, in blue + profile = None + line_rk_zmin = None + line_rk_zmin_zmax = None + hs_vlines = None + _hs_drawn = [] # Structures of hs_vlines, in order + def __init__(self, canvas=None, trad=None, toolbar=None, river=None, reach=None, profile=None, parent=None): @@ -133,19 +141,14 @@ class PlotRKC(PamhyrPlot): vymin = [] vymax = [] self.anotate_lst = [] + self._hs_drawn = [] hs_color = [] - index = self.parent.tableView.selectedIndexes() - for i, hs in enumerate(lhs): + for hs in lhs: section = hs.input_section if section is None: continue - if i == index[0].row(): - color = "blue" - elif hs.enabled: - color = "red" - else: - color = "darkgrey" + color = self._hs_color(hs) x = section.rk if x is not None: @@ -163,6 +166,7 @@ class PlotRKC(PamhyrPlot): vymin.append(min(z_min)) vymax.append(max(z_max)) hs_color.append(color) + self._hs_drawn.append(hs) self.hs_vlines = self.canvas.axes.vlines( x=vx, ymin=vymin, ymax=vymax, @@ -171,6 +175,28 @@ class PlotRKC(PamhyrPlot): color=hs_color, ) + def _hs_color(self, hs): + if hs is self._selected: + return "blue" + if hs.enabled: + return "red" + return "darkgrey" + + def set_selected(self, hs): + """Draw the selected structure in blue, without redrawing the + plot (the view is kept)""" + self._selected = hs + if self.hs_vlines is None: + return + + colors = [self._hs_color(h) for h in self._hs_drawn] + if colors: + self.hs_vlines.set_color(colors) + for annotation, color in zip(self.anotate_lst, colors): + annotation.set_color(color) + + self.canvas.figure.canvas.draw_idle() + def color_highlight(self, highlight): reach = self._current_reach @@ -254,7 +280,8 @@ class PlotRKC(PamhyrPlot): closest = self._closest_profile(event) index = self.parent.tableView.selectedIndexes() - if self.parent._table is not None: + # Moves the selected structure: nothing to do without selection + if self.parent._table is not None and len(index) > 2: self.parent._table.setData(index[2], closest) return diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py index 3cb4a126..2e321346 100644 --- a/src/View/HydraulicStructures/Window.py +++ b/src/View/HydraulicStructures/Window.py @@ -130,11 +130,13 @@ class HydraulicStructuresWindow(PamhyrWindow): self._checkbox = self.find(QCheckBox, f"checkBox") self._set_checkbox_state() + _toolbar_items = ["home", "move", "zoom", "save", "iso", "back/forward"] + def setup_plots(self): self.canvas = MplCanvas(width=5, height=4, dpi=100) self.canvas.setObjectName("canvas") self.toolbar = PamhyrPlotToolbar( - self.canvas, self + self.canvas, self, items=self._toolbar_items ) self.plot_layout = self.find(QVBoxLayout, "verticalLayout") self.plot_layout.addWidget(self.toolbar) @@ -143,7 +145,7 @@ class HydraulicStructuresWindow(PamhyrWindow): self.plot_rkc = PlotRKC( canvas=self.canvas, river=self._study.river, - reach=None, + reach=self._displayed_reach(None), profile=None, trad=self._trad, toolbar=self.toolbar, @@ -154,7 +156,7 @@ class HydraulicStructuresWindow(PamhyrWindow): self.canvas_2 = MplCanvas(width=5, height=4, dpi=100) self.canvas_2.setObjectName("canvas_2") self.toolbar_2 = PamhyrPlotToolbar( - self.canvas_2, self + self.canvas_2, self, items=self._toolbar_items ) self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2") self.plot_layout_2.addWidget(self.toolbar_2) @@ -183,7 +185,7 @@ class HydraulicStructuresWindow(PamhyrWindow): table = self.find(QTableView, "tableView") table.selectionModel()\ .selectionChanged\ - .connect(self.update) + .connect(self.update_selection) self._table.dataChanged.connect(self.update) self._table.layoutChanged.connect(self.update) @@ -282,44 +284,65 @@ class HydraulicStructuresWindow(PamhyrWindow): ) def update(self): + """Data changed: plots redrawn, fitted to their data""" self._set_checkbox_state() - self._update_clear_plot() + self._update_plots(redraw=True) - def _update_clear_plot(self): + def update_selection(self): + """Selection changed: the selected structure is drawn in blue, + the view is kept (unless its reach is another one)""" + self._set_checkbox_state() + self._update_plots(redraw=False) + + def _selected_structure(self): rows = self.index_selected_rows() - if len(rows) == 0 or len(self._hs_lst) == 0: - self._update_clear_all() + return None + return self._hs_lst.get(rows[0]) + + def _displayed_reach(self, selected): + """Reach of the selected structure; otherwise the reach already + shown, the reach of the first structure, or the first reach""" + edges = self._study.river.enable_edges() + if selected is not None and selected.input_reach in edges: + return selected.input_reach + + current = getattr(self, "plot_rkc", None) + if current is not None and current._current_reach in edges: + return current._current_reach + + for hs in self._hs_lst.lst: + if hs.input_reach in edges: + return hs.input_reach + + return edges[0] if len(edges) > 0 else None + + def _update_plots(self, redraw=True): + selected = self._selected_structure() + reach = self._displayed_reach(selected) + + self.plot_rkc._selected = selected + if redraw or reach is not self.plot_rkc._current_reach: + self.plot_rkc.set_reach(reach) + else: + self.plot_rkc.set_selected(selected) + + self._update_profile_plot(selected, reach) + + def _update_profile_plot(self, selected, reach): + profile = None + if (selected is not None and reach is not None + and selected.input_section is not None): + profiles = reach.reach.get_profiles_from_rk( + float(selected.input_section.rk) + ) + if profiles: + profile = profiles[0] + + if profile is None: + self.plot_ac.clear() + self.plot_ac.update_idle() return - reach = self._hs_lst.get(rows[0]).input_reach - if reach is not None: - self.plot_rkc.set_reach(reach) - self.plot_ac.set_reach(reach) - - profile = self._hs_lst.get(rows[0]).input_section - if profile is not None: - profiles = reach.reach\ - .get_profiles_from_rk( - float(profile.rk) - ) - - if len(profiles) != 0 and profiles is not None: - profile = profiles[0] - - self.plot_rkc.set_profile(profile) - self.plot_ac.set_profile(profile) - else: - self._update_clear_profile() - else: - self._update_clear_profile() - else: - self._update_clear_all() - - def _update_clear_all(self): - self.plot_rkc.clear() - self.plot_ac.clear() - - def _update_clear_profile(self): - self.plot_ac.clear() - self.plot_rkc.clear_profile() + self.plot_ac.set_reach(reach) + self.plot_ac.set_profile(profile)