diff --git a/RangeSlider/RangeSlider.py b/RangeSlider/RangeSlider.py index f4671c1..8560491 100644 --- a/RangeSlider/RangeSlider.py +++ b/RangeSlider/RangeSlider.py @@ -23,7 +23,7 @@ def __init__(self, master, variables, Width = 400, Height = 80, min_val = 0, max auto=True, line_width=3, bar_radius=10, bar_color_inner='#5c8a8a', line_s_color="#0a50ff", bar_color_outer='#c2d6d6', line_color = '#476b6b', bgColor= '#ffffff', step_marker_color = "#ffffff", font_color = '#000000', show_value = True, digit_precision='.1f', valueSide='TOP', font_family='Times', font_size=16, suffix="", - step_size = 0,step_marker=False, cross_each_other = False): + step_size = 0,step_marker=False, cross_each_other = False, enable_right_click_movement=False): RangeSliderH.LINE_COLOR=line_color RangeSliderH.LINE_WIDTH=line_width RangeSliderH.BAR_COLOR_INNER=bar_color_inner @@ -129,8 +129,18 @@ def __init__(self, master, variables, Width = 400, Height = 80, min_val = 0, max self.canv = Canvas(self, height = self.canv_H, width = self.canv_W, bg=bgColor, bd=0 , highlightthickness=0, relief='ridge') self.canv.pack() - self.canv.bind("", self._mouseMotion) + + self.canv.bind("", self._mouseMotion_b1) # still leave the selection on motion without click / after mouse was released self.canv.bind("", self._moveBar) + if enable_right_click_movement: + # now able to grab right handle with right click if two handles are on the same position + # other possibilities without right-click: + # - move handle in direction of click on track; + # - if bars have equal position on mousedown, select based on first movement + # - if bars are both at 0, select second/right handle + # self.canv.bind("", self._mouseMotion_b1) # not necessary + self.canv.bind("", self._mouseMotion_b3) + self.canv.bind("", self._moveBar) self.track = self.__addTrack(self.slider_x, self.slider_y, self.canv_W-self.slider_x, self.slider_y, self.bars[0]["Pos"], self.bars[1]["Pos"]) tempIdx=0 @@ -174,7 +184,7 @@ def forcePos(self, pos): for idx in range(len(self.bars)): self.__moveBar(idx, pos[idx]) - def _mouseMotion(self, event): + def _mouseMotion_b1(self, event): x = event.x; y = event.y selection = self.__checkSelection(x,y) if selection[0]: @@ -184,6 +194,17 @@ def _mouseMotion(self, event): self.canv.config(cursor = "") self.selected_idx = None + def _mouseMotion_b3(self, event): + x = event.x; y = event.y + selection = self.__checkSelection(x,y, right_handle_first=True) + if selection[0]: + self.canv.config(cursor = "hand2") + self.selected_idx = selection[1] + else: + self.canv.config(cursor = "") + self.selected_idx = None + + def _moveBar(self, event): x = event.x; y = event.y if self.selected_idx == None: @@ -337,16 +358,22 @@ def __getValue(self, idx): pos = self.__calcPos(x) return pos*(self.max_val - self.min_val)+self.min_val - def __checkSelection(self, x, y): + def __checkSelection(self, x, y, right_handle_first=False): """ To check if the position is inside the bounding rectangle of a Bar Return [True, bar_index] or [False, None] """ - for idx in range(len(self.bars)): + if right_handle_first: + bars_ids = reversed(range(len(self.bars))) + else: + bars_ids = range(len(self.bars)) + + for idx in bars_ids: id = self.bars[idx]["Ids"][0] bbox = self.canv.bbox(id) if bbox[0] < x and bbox[2] > x and bbox[1] < y and bbox[3] > y: return [True, idx] + # Note: position may possibly be inside more than one bar/handle only the left-most (or right-most with reversed) can be moved return [False, None]