Skip to content

Commit cb421bc

Browse files
committed
improves tooltip rendering
fixes redraw issue with active crosslines in Comparator
1 parent f282df0 commit cb421bc

4 files changed

Lines changed: 46 additions & 28 deletions

File tree

src/artisanlib/canvas.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,12 +2663,12 @@ def updateBackground(self) -> None:
26632663
finally:
26642664
if self.updateBackgroundSemaphore.available() < 1:
26652665
self.updateBackgroundSemaphore.release(1)
2666+
self.block_update = False
26662667

26672668
def doUpdate(self) -> None:
26682669
if not self.designerflag:
26692670
self.resetlinecountcaches() # ensure that the line counts are up to date
26702671
self.resetlines() # get rid of projection, cross lines and AUC line
2671-
26722672
try:
26732673
with warnings.catch_warnings():
26742674
warnings.simplefilter('ignore')
@@ -2691,8 +2691,6 @@ def doUpdate(self) -> None:
26912691
self.update_additional_artists()
26922692
self.fig.canvas.blit(axfig.bbox)
26932693

2694-
self.block_update = False
2695-
26962694
def device_name_subst(self, device_name:str) -> str:
26972695
try:
26982696
return device_name.format(self.etypes[0],self.etypes[1],self.etypes[2],self.etypes[3],self.mode)
@@ -3006,7 +3004,7 @@ def onpick(self, event:'PickEvent') -> None:
30063004
self.segmentpickflag = True
30073005

30083006
# toggle visibility of graph lines by clicking on the legend
3009-
elif self.legend is not None and event_artist != self.legend and isinstance(event_artist, (Line2D, Text)) \
3007+
elif not bool(self.aw.comparator) and self.legend is not None and event_artist != self.legend and isinstance(event_artist, (Line2D, Text)) \
30103008
and event_artist not in [self.l_backgroundeventtype1dots,self.l_backgroundeventtype2dots,self.l_backgroundeventtype3dots,self.l_backgroundeventtype4dots] \
30113009
and event_artist not in [self.l_eventtype1dots,self.l_eventtype2dots,self.l_eventtype3dots,self.l_eventtype4dots]:
30123010
idx = None
@@ -3069,7 +3067,7 @@ def onpick(self, event:'PickEvent') -> None:
30693067
pass
30703068

30713069
# show event information by clicking on event lines in step, step+ and combo modes
3072-
elif isinstance(event_artist, Line2D):
3070+
elif not bool(self.aw.comparator) and isinstance(event_artist, Line2D):
30733071
event_type:Optional[int] = None
30743072
if isinstance(event.ind, int): # type: ignore[attr-defined] # "PickEvent" has no attribute "ind"
30753073
ind = event.ind # type: ignore[attr-defined] # "PickEvent" has no attribute "ind"
@@ -3124,7 +3122,7 @@ def onpick(self, event:'PickEvent') -> None:
31243122
self.background_event_last_picked_ind = i
31253123
self.background_event_last_picked_pos = ind
31263124
break
3127-
elif event_artist in [self.l_eventtype1dots,self.l_eventtype2dots,self.l_eventtype3dots,self.l_eventtype4dots]:
3125+
elif not bool(self.aw.comparator) and event_artist in [self.l_eventtype1dots,self.l_eventtype2dots,self.l_eventtype3dots,self.l_eventtype4dots]:
31283126
tx = event_artist.get_xdata()[ind]
31293127
timex = self.time2index(tx)
31303128
if event_artist is not None and abs(tx - event.mouseevent.xdata)<3: # allow a slightly different mouse position, but close enough to the point on the line
@@ -3626,7 +3624,8 @@ def disconnect_draggableannotations_motion_notifiers(self) -> None:
36263624
cids.append(cid)
36273625
# disconnecting all established motion_notify_event_handlers of DraggableAnnotations
36283626
for cid in cids:
3629-
self.fig.canvas.mpl_disconnect(cid)
3627+
if cid != self.onmove_cid: # don't disconnect the general motion notify event used to move the cross lines
3628+
self.fig.canvas.mpl_disconnect(cid)
36303629
except Exception: # pylint: disable=broad-except
36313630
pass
36323631

@@ -3951,6 +3950,7 @@ def onclick(self, event:'MouseEvent') -> None:
39513950
self.redraw_keep_view(recomputeAllDeltas=True)
39523951
return
39533952

3953+
39543954
event_xdata = event.xdata
39553955
event_ydata = event.ydata
39563956
if (event_xdata is not None and event_xdata not in (float('-inf'),float('inf')) and
@@ -3961,13 +3961,13 @@ def onclick(self, event:'MouseEvent') -> None:
39613961
# Mark starting point of click-and-drag with a marker
39623962
self.base_horizontalcrossline, = self.ax.plot(numpy.array(self.baseX), numpy.array(self.baseY), 'r+', markersize=20)
39633963
self.base_verticalcrossline, = self.ax.plot(numpy.array(self.baseX), numpy.array(self.baseY), 'wo', markersize = 2)
3964-
elif event.button == 3 and event.inaxes and not self.designerflag and not self.wheelflag and self.aw.ntb.mode not in ['pan/zoom', 'zoom rect']:# and not self.flagon:
3964+
elif not bool(self.aw.comparator) and event.button == 3 and event.inaxes and not self.designerflag and not self.wheelflag and self.aw.ntb.mode not in ['pan/zoom', 'zoom rect']:# and not self.flagon:
39653965
# popup not available if pan/zoom or zoom rect is active as it interacts
39663966
timex = self.time2index(event_xdata)
39673967
if timex > 0:
39683968
# reset the zoom rectangles
39693969
menu = QMenu(self.aw) # if we bind this to self, we inherit the background-color: transparent from self.fig
3970-
# menu.setStyleSheet("QMenu::item {background-color: palette(window); selection-color: palette(window); selection-background-color: darkBlue;}")
3970+
# menu.setStyleSheet("QMenu::item {background-color: palette(window); selection-color: palette(window); selection-background-color: darkBlue;}")
39713971
# populate menu
39723972
ac = QAction(menu)
39733973
bt = self.temp2[timex]
@@ -5739,19 +5739,35 @@ def resetlinecountcaches(self) -> None:
57395739
# ATTENTION: all lines that should be populated need to established in self.ax.lines thus for example delta lines should be established (with empty point lists)
57405740
# even if they are not drawn before CHARGE to ensure that the linecount corresponds to the fixes lines in self.ax.lines!!
57415741
def resetlines(self) -> None:
5742-
if self.ax is not None and not bool(self.aw.comparator):
5743-
#note: delta curves are now in self.delta_ax and have been removed from the count of resetlines()
5744-
if self.linecount is None:
5745-
self.linecount = self.lenaxlines()
5746-
if self.deltalinecount is None:
5747-
self.deltalinecount = self.lendeltaaxlines()
5748-
total_linecount = self.linecount+self.deltalinecount
5749-
# remove lines beyond the max limit of self.linecount)
5750-
for i in range(len(self.ax.lines)-1,-1,-1):
5751-
if i >= total_linecount:
5752-
self.ax.lines[i].remove()
5753-
else:
5754-
break
5742+
if self.ax is not None:
5743+
if bool(self.aw.comparator):
5744+
if self.l_horizontalcrossline is not None:
5745+
try:
5746+
i = self.ax.lines.index(self.l_horizontalcrossline)
5747+
self.ax.lines[i].remove()
5748+
self.l_horizontalcrossline = None
5749+
except ValueError:
5750+
pass
5751+
if self.l_verticalcrossline is not None:
5752+
try:
5753+
i = self.ax.lines.index(self.l_verticalcrossline)
5754+
self.ax.lines[i].remove()
5755+
self.l_verticalcrossline = None
5756+
except ValueError:
5757+
pass
5758+
else:
5759+
#note: delta curves are now in self.delta_ax and have been removed from the count of resetlines()
5760+
if self.linecount is None:
5761+
self.linecount = self.lenaxlines()
5762+
if self.deltalinecount is None:
5763+
self.deltalinecount = self.lendeltaaxlines()
5764+
total_linecount = self.linecount+self.deltalinecount
5765+
# remove lines beyond the max limit of self.linecount)
5766+
for i in range(len(self.ax.lines)-1,-1,-1):
5767+
if i >= total_linecount:
5768+
self.ax.lines[i].remove()
5769+
else:
5770+
break
57555771

57565772
@pyqtSlot(int)
57575773
def getAlarmSet(self, n:int) -> 'Optional[AlarmSet]':

src/artisanlib/comparator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@ def drawLegend(self) -> None:
14191419
pass
14201420
try:
14211421
self.legend.set_draggable(state=True,use_blit=True) #,update='bbox')
1422+
self.legend.set_picker(self.aw.draggable_text_box_picker)
14221423
except Exception: # not available in mpl<3.x # pylint: disable=broad-except
14231424
self.legend.draggable(state=True) # type: ignore # for mpl 2.x
14241425
frame = self.legend.get_frame()

src/artisanlib/phases_canvas.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,14 @@ def hover(self, event:'Event') -> None:
127127
ror_end_temp:float = float2float(phases_data['BT_ROR_end_temp'], self.aw.qmc.LCDdecimalplaces)
128128
ror_delta_temp:float = phases_data['BT_ROR_end_temp'] - phases_data['BT_ROR_start_temp']
129129
ror_delta_temp_str:str = f"{('+' if ror_delta_temp>0 else '')}{float2float(ror_delta_temp, self.aw.qmc.LCDdecimalplaces)}"
130-
text = f"{ror_start_temp}°{self.aw.qmc.mode}/min => {ror_end_temp}°{self.aw.qmc.mode}/min {ror_delta_temp_str}°{self.aw.qmc.mode}/min"
130+
text = f"{ror_start_temp}°{self.aw.qmc.mode}/min {ror_delta_temp_str}°{self.aw.qmc.mode}/min {ror_end_temp}°{self.aw.qmc.mode}/min"
131131
elif phases_data['BT_start_temp'] != -1 and phases_data['BT_start_temp'] != -1:
132132
# BT temperature
133133
start_temp:float = float2float(phases_data['BT_start_temp'], self.aw.qmc.LCDdecimalplaces)
134134
end_temp:float = float2float(phases_data['BT_end_temp'], self.aw.qmc.LCDdecimalplaces)
135135
delta_temp:float = phases_data['BT_end_temp'] - phases_data['BT_start_temp']
136136
delta_temp_str:str = f"{('+' if delta_temp>0 else '')}{float2float(delta_temp, self.aw.qmc.LCDdecimalplaces)}"
137-
text = f"{start_temp}°{self.aw.qmc.mode} => {end_temp}°{self.aw.qmc.mode} {delta_temp_str}°{self.aw.qmc.mode}"
137+
text = f"{start_temp}°{self.aw.qmc.mode} {delta_temp_str}°{self.aw.qmc.mode} {end_temp}°{self.aw.qmc.mode}"
138138
if text != '':
139139
if self.tooltip_anno is None:
140140
self.tooltip_anno = self.ax.annotate('', xy=(0,0), xytext=(0,0), textcoords='offset points', ha='center', va='center',

wiki/ReleaseHistory.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ v3.2.1
1212
* CHANGES
1313
- updated Spanish localizations (thanks to Juan Carlos Bonilla)
1414
- updates libs (scipy, bleak, lxml, pillow)
15-
- Breaking feature only when hidden buttons are first at the top of the Events Buttons table. Hidden buttons at the top of the Events Buttons table are no longer counted in the first row's button count, which is limited by the Max Buttons per Row setting. All other hidden buttons continue to be counted in each row's button count.
16-
- Unlimited number of buttons can be created while display is limited to maximum 10 rows with maximum 50 buttons each.
17-
- Palette load uses and updates the user selected profile path.
15+
- Breaking change only when hidden buttons are first at the top of the Events Buttons table: hidden buttons at the top of the Events Buttons table are no longer counted in the first row's button count, which is limited by the Max Buttons per Row setting. All other hidden buttons continue to be counted in each row's button count.
16+
- unlimited number of buttons can be created while display is limited to maximum 10 rows with maximum 50 buttons each
17+
- palette load uses and updates the user selected profile path
1818

1919
* FIXES
2020
- fixes regression which broke the designer such that points could not be moved ([Discussion #1905](../../../discussions/1905) and [Issue #1916](../../../issues/1916))
2121
- fixes support for second scale
22-
- fixes rendering of special characters like quotes in task displays
22+
- fixes rendering of special characters like quotes in task displays of the Batch Manager
2323
- fixes regression which broke the import of roast profiles exported from Cropster, Giesen, IKAWA, Loring, Petroncini, RoastLog, RoastPath, ROEST, Rubasse, and Stronghold
2424
- fixes event buttons bottom row not rendered properly in all cases
2525
- fixes number of rendered event buttons rows
2626
- fixes graph bounce and jitter when moving the cursor in the designer
27+
- fixes redraw issue with active crosslines in Comparator
2728

2829
----
2930
v3.2.0 (June 23, 2025)

0 commit comments

Comments
 (0)