Skip to content

Commit 3dd0018

Browse files
committed
add optional marker menu
A custom right click menu can be added to a marker with myMenu = { # key is the title and value is the function to call 'My fancy marker menu entry 1': function1, # separators can also be added '-': None, 'And a second entry after the separator': function2 } map_widget.set_marker(x, y, menu=myMenu)
1 parent eb84f60 commit 3dd0018

4 files changed

Lines changed: 74 additions & 3 deletions

File tree

tkintermapview/canvas_path.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ def __init__(self,
1414
position_list, color="#3E69CB",
1515
command=None,
1616
name=None,
17-
data: any = None):
17+
data: any = None,
18+
menu: any = None):
1819

1920
self.map_widget = map_widget
2021
self.position_list = position_list
@@ -25,7 +26,9 @@ def __init__(self,
2526
self.command = command
2627
self.canvas_line = None
2728
self.name = name
29+
self.menu = menu
2830
self.data = data
31+
self.mouse_over = False
2932

3033
self.last_upper_left_tile_pos = None
3134
self.last_position_list_length = len(self.position_list)
@@ -58,6 +61,7 @@ def get_canvas_pos(self, position, widget_tile_width, widget_tile_height):
5861
return canvas_pos_x, canvas_pos_y
5962

6063
def mouse_enter(self, event=None):
64+
self.mouse_over = True
6165
if sys.platform == "darwin":
6266
self.map_widget.canvas.config(cursor="pointinghand")
6367
elif sys.platform.startswith("win"):
@@ -66,12 +70,23 @@ def mouse_enter(self, event=None):
6670
self.map_widget.canvas.config(cursor="hand2") # not tested what it looks like on Linux!
6771

6872
def mouse_leave(self, event=None):
73+
self.mouse_over = False
6974
self.map_widget.canvas.config(cursor="arrow")
7075

7176
def click(self, event=None):
7277
if self.command is not None:
7378
self.command(self)
7479

80+
def click_right(self, event=None):
81+
if self.menu is not None:
82+
m = tkinter.Menu(self.map_widget, tearoff=0)
83+
for title, cmd in self.menu.items():
84+
if title == '-':
85+
m.add_separator()
86+
continue
87+
m.add_command(label=f"{title}", command=cmd)
88+
m.tk_popup(event.x_root, event.y_root) # display menu
89+
7590
def draw(self, move=False):
7691
new_line_length = self.last_position_list_length != len(self.position_list)
7792
self.last_position_list_length = len(self.position_list)
@@ -105,6 +120,10 @@ def draw(self, move=False):
105120
self.map_widget.canvas.tag_bind(self.canvas_line, "<Enter>", self.mouse_enter)
106121
self.map_widget.canvas.tag_bind(self.canvas_line, "<Leave>", self.mouse_leave)
107122
self.map_widget.canvas.tag_bind(self.canvas_line, "<Button-1>", self.click)
123+
if sys.platform == "darwin":
124+
self.map_widget.canvas.tag_bind(self.canvas_line, "<Button-2>", self.click_right)
125+
else:
126+
self.map_widget.canvas.tag_bind(self.canvas_line, "<Button-3>", self.click_right)
108127
else:
109128
self.map_widget.canvas.coords(self.canvas_line, self.canvas_line_positions)
110129
else:

tkintermapview/canvas_polygon.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def __init__(self,
1717
border_width: int = 5,
1818
command: Callable = None,
1919
name: str = None,
20-
data: any = None):
20+
data: any = None,
21+
menu: any = None):
2122

2223
self.map_widget = map_widget
2324
self.position_list = position_list # list with decimal positions
@@ -26,7 +27,9 @@ def __init__(self,
2627
self.deleted = False
2728

2829
self.name = name
30+
self.menu = menu
2931
self.data = data
32+
self.mouse_over = False
3033
self.outline_color = outline_color
3134
self.fill_color = fill_color # can also be None for transparent fill
3235
self.border_width = border_width
@@ -56,6 +59,7 @@ def remove_position(self, deg_x, deg_y):
5659
self.draw()
5760

5861
def mouse_enter(self, event=None):
62+
self.mouse_over = True
5963
if sys.platform == "darwin":
6064
self.map_widget.canvas.config(cursor="pointinghand")
6165
elif sys.platform.startswith("win"):
@@ -64,12 +68,23 @@ def mouse_enter(self, event=None):
6468
self.map_widget.canvas.config(cursor="hand2") # not tested what it looks like on Linux!
6569

6670
def mouse_leave(self, event=None):
71+
self.mouse_over = False
6772
self.map_widget.canvas.config(cursor="arrow")
6873

6974
def click(self, event=None):
7075
if self.command is not None:
7176
self.command(self)
7277

78+
def click_right(self, event=None):
79+
if self.menu is not None:
80+
m = tkinter.Menu(self.map_widget, tearoff=0)
81+
for title, cmd in self.menu.items():
82+
if title == '-':
83+
m.add_separator()
84+
continue
85+
m.add_command(label=f"{title}", command=cmd)
86+
m.tk_popup(event.x_root, event.y_root) # display menu
87+
7388
def get_canvas_pos(self, position, widget_tile_width, widget_tile_height):
7489
tile_position = decimal_to_osm(*position, round(self.map_widget.zoom))
7590

@@ -120,6 +135,10 @@ def draw(self, move=False):
120135
self.map_widget.canvas.tag_bind(self.canvas_polygon, "<Enter>", self.mouse_enter)
121136
self.map_widget.canvas.tag_bind(self.canvas_polygon, "<Leave>", self.mouse_leave)
122137
self.map_widget.canvas.tag_bind(self.canvas_polygon, "<Button-1>", self.click)
138+
if sys.platform == "darwin":
139+
self.map_widget.canvas.tag_bind(self.canvas_polygon, "<Button-2>", self.click_right)
140+
else:
141+
self.map_widget.canvas.tag_bind(self.canvas_polygon, "<Button-3>", self.click_right)
123142
else:
124143
self.map_widget.canvas.coords(self.canvas_polygon, self.canvas_polygon_positions)
125144
else:

tkintermapview/canvas_position_marker.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def __init__(self,
2020
command: Callable = None,
2121
image=None,
2222
image_zoom_visibility: tuple = (13, float("inf")),
23-
data: any = None):
23+
data: any = None,
24+
menu: any = None):
2425

2526
self.map_widget = map_widget
2627
self.position = position
@@ -33,7 +34,9 @@ def __init__(self,
3334
self.image_zoom_visibility = image_zoom_visibility
3435
self.deleted = False
3536
self.command = command
37+
self.menu = menu
3638
self.data = data
39+
self.mouse_over = False
3740

3841
self.polygon = None
3942
self.big_circle = None
@@ -70,6 +73,7 @@ def hide_image(self, image_hidden):
7073
self.draw()
7174

7275
def mouse_enter(self, event=None):
76+
self.mouse_over = True
7377
if sys.platform == "darwin":
7478
self.map_widget.canvas.config(cursor="pointinghand")
7579
elif sys.platform.startswith("win"):
@@ -78,12 +82,23 @@ def mouse_enter(self, event=None):
7882
self.map_widget.canvas.config(cursor="hand2") # not tested what it looks like on Linux!
7983

8084
def mouse_leave(self, event=None):
85+
self.mouse_over = False
8186
self.map_widget.canvas.config(cursor="arrow")
8287

8388
def click(self, event=None):
8489
if self.command is not None:
8590
self.command(self)
8691

92+
def click_right(self, event=None):
93+
if self.menu is not None:
94+
m = tkinter.Menu(self.map_widget, tearoff=0)
95+
for title, cmd in self.menu.items():
96+
if title == '-':
97+
m.add_separator()
98+
continue
99+
m.add_command(label=f"{title}", command=cmd)
100+
m.tk_popup(event.x_root, event.y_root) # display menu
101+
87102
def get_canvas_pos(self, position):
88103
tile_position = decimal_to_osm(*position, round(self.map_widget.zoom))
89104

@@ -110,6 +125,10 @@ def draw(self, event=None):
110125
self.map_widget.canvas.tag_bind(self.polygon, "<Enter>", self.mouse_enter)
111126
self.map_widget.canvas.tag_bind(self.polygon, "<Leave>", self.mouse_leave)
112127
self.map_widget.canvas.tag_bind(self.polygon, "<Button-1>", self.click)
128+
if sys.platform == "darwin":
129+
self.map_widget.canvas.tag_bind(self.polygon, "<Button-2>", self.click_right)
130+
else:
131+
self.map_widget.canvas.tag_bind(self.polygon, "<Button-3>", self.click_right)
113132
else:
114133
self.map_widget.canvas.coords(self.polygon,
115134
canvas_pos_x - 14, canvas_pos_y - 23,
@@ -124,6 +143,10 @@ def draw(self, event=None):
124143
self.map_widget.canvas.tag_bind(self.big_circle, "<Enter>", self.mouse_enter)
125144
self.map_widget.canvas.tag_bind(self.big_circle, "<Leave>", self.mouse_leave)
126145
self.map_widget.canvas.tag_bind(self.big_circle, "<Button-1>", self.click)
146+
if sys.platform == "darwin":
147+
self.map_widget.canvas.tag_bind(self.big_circle, "<Button-2>", self.click_right)
148+
else:
149+
self.map_widget.canvas.tag_bind(self.big_circle, "<Button-3>", self.click_right)
127150
else:
128151
self.map_widget.canvas.coords(self.big_circle,
129152
canvas_pos_x - 14, canvas_pos_y - 45,
@@ -141,6 +164,10 @@ def draw(self, event=None):
141164
self.map_widget.canvas.tag_bind(self.canvas_text, "<Enter>", self.mouse_enter)
142165
self.map_widget.canvas.tag_bind(self.canvas_text, "<Leave>", self.mouse_leave)
143166
self.map_widget.canvas.tag_bind(self.canvas_text, "<Button-1>", self.click)
167+
if sys.platform == "darwin":
168+
self.map_widget.canvas.tag_bind(self.canvas_text, "<Button-2>", self.click_right)
169+
else:
170+
self.map_widget.canvas.tag_bind(self.canvas_text, "<Button-3>", self.click_right)
144171
else:
145172
self.map_widget.canvas.coords(self.canvas_text, canvas_pos_x, canvas_pos_y - 56)
146173
self.map_widget.canvas.itemconfig(self.canvas_text, text=self.text)

tkintermapview/map_widget.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ def convert_canvas_coords_to_decimal_coords(self, canvas_x: int, canvas_y: int)
202202
def mouse_right_click(self, event):
203203
coordinate_mouse_pos = self.convert_canvas_coords_to_decimal_coords(event.x, event.y)
204204

205+
# check if mouse is over a marker with menu
206+
for m in self.canvas_marker_list + self.canvas_path_list + self.canvas_polygon_list:
207+
if m.mouse_over and m.menu:
208+
# don't show right click menu of map
209+
return
210+
205211
def click_coordinates_event():
206212
try:
207213
pyperclip.copy(f"{coordinate_mouse_pos[0]:.7f} {coordinate_mouse_pos[1]:.7f}")

0 commit comments

Comments
 (0)