@@ -852,6 +852,15 @@ def updateObject(self, obj : wmwpy.classes.Object | None):
852
852
image = obj .foreground_PhotoImage ,
853
853
tags = ('object' , 'foreground' , id )
854
854
)
855
+
856
+ if len (obj ._foreground ) == 0 and len (obj ._background ) == 0 :
857
+ self .level_canvas .create_image (
858
+ canvas_pos [0 ],
859
+ canvas_pos [1 ],
860
+ anchor = 'c' ,
861
+ image = ImageTk .PhotoImage (Image .new ('RGBA' , (1 , 1 ), 'black' )),
862
+ tags = ('object' , 'foreground' , id ),
863
+ )
855
864
856
865
if (obj == self .selectedObject or self .settings .get ('view.radius' , True )) and obj .Type is not None :
857
866
properties = filter (lambda name : obj .Type .PROPERTIES [name ].get ('type' , 'string' ) == 'radius' , obj .Type .PROPERTIES )
@@ -924,21 +933,22 @@ def updateObject(self, obj : wmwpy.classes.Object | None):
924
933
tags = ('part' , 'path' , property , 'pathPoint' , id ),
925
934
)
926
935
927
- if is_closed :
928
- line = self .level_canvas .create_polygon (
929
- path_canvas_points ,
930
- fill = '' ,
931
- outline = 'black' ,
932
- width = 2 ,
933
- tags = ('passthrough' , 'part' , 'path' , property , 'pathLine' , id ),
934
- )
935
- else :
936
- line = self .level_canvas .create_line (
937
- path_canvas_points ,
938
- fill = 'black' ,
939
- width = 2 ,
940
- tags = ('passthrough' , 'part' , 'path' , property , 'pathLine' , id ),
941
- )
936
+ if len (path_canvas_points ) > 1 :
937
+ if is_closed :
938
+ line = self .level_canvas .create_polygon (
939
+ path_canvas_points ,
940
+ fill = '' ,
941
+ outline = 'black' ,
942
+ width = 2 ,
943
+ tags = ('passthrough' , 'part' , 'path' , property , 'pathLine' , id ),
944
+ )
945
+ else :
946
+ line = self .level_canvas .create_line (
947
+ path_canvas_points ,
948
+ fill = 'black' ,
949
+ width = 2 ,
950
+ tags = ('passthrough' , 'part' , 'path' , property , 'pathLine' , id ),
951
+ )
942
952
943
953
# self.level_canvas.tag_bind(line, '<Button-1>', self.onLevelClick)
944
954
@@ -952,27 +962,34 @@ def updateObject(self, obj : wmwpy.classes.Object | None):
952
962
953
963
self .updateSelectionRectangle ()
954
964
self .updateLevelScroll ()
955
-
956
965
957
- def onLevelClick (self , event : tk .Event ):
958
- logging .debug ('level' )
959
-
960
- if self .level == None :
961
- return
962
-
963
- mouse = (self .level_canvas .canvasx (event .x ), self .level_canvas .canvasy (event .y ))
966
+
967
+ def selectObjectAt (
968
+ self ,
969
+ pos : tuple [float , float ] | list [float ] | tk .Event ,
970
+ halo : int | float = 5 ,
971
+ ):
972
+ event = None
973
+ if isinstance (pos , tk .Event ):
974
+ event = pos
975
+ logging .debug (f'select obj event: { event .__dict__ } ' )
976
+ pos = (pos .x , pos .y )
977
+
978
+ pos = (
979
+ self .level_canvas .canvasx (pos [0 ]),
980
+ self .level_canvas .canvasy (pos [1 ])
981
+ )
964
982
965
983
# objects = self.level_canvas.find_overlapping(*mouse, *mouse)
966
984
objects = self .level_canvas .find_overlapping (
967
- mouse [0 ] - 5 , mouse [1 ] - 5 ,
968
- mouse [0 ] + 5 , mouse [1 ] + 5 ,
985
+ pos [0 ] - halo , pos [1 ] - halo ,
986
+ pos [0 ] + halo , pos [1 ] + halo ,
969
987
)
970
988
logging .debug (f'under mouse: { objects } ' )
971
- # logging.debug(f'close: {close}')
972
- length = len (objects )
973
989
974
990
for id in reversed (objects ):
975
991
tags = self .level_canvas .gettags (id )
992
+ logging .debug (f'tags: { tags } ' )
976
993
if tags [0 ] in ['selection' , 'level' ]:
977
994
continue
978
995
@@ -983,6 +1000,7 @@ def onLevelClick(self, event : tk.Event):
983
1000
984
1001
if tags [obj_tag ].startswith ('object-' ):
985
1002
obj = self .level .getObjectById (tags [obj_tag ][7 ::])
1003
+ logging .debug (f'obj: { obj } ' )
986
1004
if obj == None :
987
1005
continue
988
1006
else :
@@ -994,24 +1012,36 @@ def onLevelClick(self, event : tk.Event):
994
1012
continue
995
1013
elif tags [0 ] == 'object' :
996
1014
logging .debug (f'selecting obj: { obj .name } ' )
997
- self .selectObject (obj )
998
- return
1015
+ self .selectObject (obj , event )
1016
+ return 'object' , obj
999
1017
elif tags [0 ] == 'part' :
1000
1018
self .selectPart (
1001
1019
obj ,
1002
1020
tags [1 ],
1003
1021
id ,
1004
1022
tags [2 ],
1005
1023
)
1006
- return
1024
+ return 'part' , obj , self . selectedPart
1007
1025
1008
1026
self .selectObject (None )
1027
+
1028
+ return None , None
1029
+
1030
+ def onLevelClick (self , event : tk .Event ):
1031
+ logging .debug ('level' )
1032
+
1033
+ if self .level == None :
1034
+ return
1035
+
1036
+ self .selectObjectAt (event )
1009
1037
1010
1038
1011
1039
1012
1040
def onLevelMove (self , event : tk .Event ):
1013
- if self .selectedPart :
1041
+ if self .selectedPart [ 'type' ] != None :
1014
1042
self .dragPart (event )
1043
+ elif self .selectedObject :
1044
+ self .dragObject (self .selectedObject , event )
1015
1045
1016
1046
1017
1047
def createLevelContextMenu (self ):
@@ -1022,19 +1052,15 @@ def createLevelContextMenu(self):
1022
1052
def onLevelRightClick (self , event ):
1023
1053
logging .debug ('level context menu' )
1024
1054
1025
- mouse = ( self .level_canvas . canvasx (event . x ), self . level_canvas . canvasy ( event . y ) )
1055
+ selected_type , selected_obj , * extra = self .selectObjectAt (event )
1026
1056
1027
- objects = self .level_canvas .find_overlapping (* mouse , * mouse )
1028
- logging .debug (objects )
1029
- length = len (objects )
1030
-
1031
- if length <= 1 :
1032
- if length == 1 :
1033
- if objects [0 ] != self .level_images ['background' ]:
1034
- return
1035
-
1036
- self .selectObject (None )
1057
+ if selected_type == None :
1037
1058
self .showPopup (self .levelContextMenu , event )
1059
+ elif selected_type == 'object' :
1060
+ self .showPopup (self .createObjectContextMenu (selected_obj ), event )
1061
+ elif selected_type == 'part' :
1062
+ self .showPopup (self .createPartContextMenu (selected_obj , extra [0 ]), event )
1063
+
1038
1064
1039
1065
def bindObject (self , id , obj : wmwpy .classes .Object | None = None ):
1040
1066
if obj == None :
@@ -1043,26 +1069,26 @@ def bindObject(self, id, obj : wmwpy.classes.Object | None = None):
1043
1069
else :
1044
1070
return
1045
1071
1046
- self .level_canvas .tag_bind (
1047
- id ,
1048
- '<Button1-Motion>' ,
1049
- lambda e , object = obj : self .dragObject (object , e )
1050
- )
1072
+ # self.level_canvas.tag_bind(
1073
+ # id,
1074
+ # '<Button1-Motion>',
1075
+ # lambda e, object = obj: self.dragObject(object, e)
1076
+ # )
1051
1077
1052
1078
context_menu = self .createObjectContextMenu (obj )
1053
1079
1054
- if platform .system () == 'Darwin' :
1055
- self .level_canvas .tag_bind (
1056
- id ,
1057
- '<Button-2>' ,
1058
- lambda e , object = obj , menu = context_menu : self .showPopup (menu , e , callback = lambda : self .selectObject (object ))
1059
- )
1060
- else :
1061
- self .level_canvas .tag_bind (
1062
- id ,
1063
- '<Button-3>' ,
1064
- lambda e , object = obj , menu = context_menu : self .showPopup (menu , e , callback = lambda : self .selectObject (object ))
1065
- )
1080
+ # if platform.system() == 'Darwin':
1081
+ # self.level_canvas.tag_bind(
1082
+ # id,
1083
+ # '<Button-2>',
1084
+ # lambda e, object = obj, menu = context_menu: self.showPopup(menu, e, callback = lambda : self.selectObject(object))
1085
+ # )
1086
+ # else:
1087
+ # self.level_canvas.tag_bind(
1088
+ # id,
1089
+ # '<Button-3>',
1090
+ # lambda e, object = obj, menu = context_menu: self.showPopup(menu, e, callback = lambda : self.selectObject(object))
1091
+ # )
1066
1092
1067
1093
def unbindObject (self , id ):
1068
1094
self .level_canvas .tag_unbind (
@@ -1092,6 +1118,23 @@ def createObjectContextMenu(self, obj : wmwpy.classes.Object):
1092
1118
self .objectContextMenu .add_command (label = 'delete' , command = lambda * args : self .deleteObject (obj ), accelerator = 'Del' )
1093
1119
1094
1120
return self .objectContextMenu
1121
+
1122
+ def createPartContextMenu (
1123
+ self ,
1124
+ obj : wmwpy .classes .Object ,
1125
+ part : dict [
1126
+ typing .Literal [
1127
+ 'type' ,
1128
+ 'id' ,
1129
+ 'property'
1130
+ ], str | None ,
1131
+ ],
1132
+ ):
1133
+
1134
+ self .objectContextMenu .delete (0 , 3 )
1135
+ self .objectContextMenu .add_command (label = 'delete' , command = lambda * args : self .deleteProperty (obj , part ['property' ]), accelerator = 'Del' )
1136
+
1137
+ return self .objectContextMenu
1095
1138
1096
1139
def showPopup (self , menu : tk .Menu , event : tk .Event = None , callback : typing .Callable = None ):
1097
1140
try :
@@ -1140,16 +1183,27 @@ def deleteObject(self, obj : wmwpy.classes.Object = None):
1140
1183
if obj == None :
1141
1184
return
1142
1185
1143
- self .level_canvas .delete (f'object-{ str (obj .id )} ' )
1144
-
1145
- if obj in self .level .objects :
1146
- index = self .level .objects .index (obj )
1147
- del self .level .objects [index ]
1148
-
1149
- if obj == self .selectedObject :
1150
- self .selectObject (None )
1151
-
1152
- self .updateObjectSelector ()
1186
+ if self .selectedPart ['type' ]:
1187
+ self .deleteProperty (obj , self .selectedPart ['property' ])
1188
+ else :
1189
+ self .level_canvas .delete (f'object-{ str (obj .id )} ' )
1190
+
1191
+ if obj in self .level .objects :
1192
+ index = self .level .objects .index (obj )
1193
+ del self .level .objects [index ]
1194
+
1195
+ if obj == self .selectedObject :
1196
+ self .selectObject (None )
1197
+
1198
+ self .updateObjectSelector ()
1199
+
1200
+ def deleteProperty (self , obj : wmwpy .classes .Object , property : str ):
1201
+ if property in obj .properties :
1202
+ del obj .properties [property ]
1203
+
1204
+ self .updateObject (obj )
1205
+ if self .selectedObject == obj :
1206
+ self .updateProperties ()
1153
1207
1154
1208
def checkLevelFocus (
1155
1209
self ,
@@ -1729,6 +1783,7 @@ def selectObject(event: tk.Event):
1729
1783
item = self .object_selector ['treeview' ].selection ()
1730
1784
# logging.debug(f"selection: {self.object_selector['treeview'].selection()}")
1731
1785
item = self .object_selector ['treeview' ].item (item )
1786
+ self .level_canvas .focus_set ()
1732
1787
1733
1788
if 'object' in item ['tags' ]:
1734
1789
id = item ['values' ][2 ]
@@ -1799,7 +1854,6 @@ def rightClick(event):
1799
1854
self .showPopup (self .object_selector ['menu' ], event )
1800
1855
1801
1856
self .object_selector ['treeview' ].bind ('<ButtonRelease-1>' , selectObject )
1802
- self .object_selector ['treeview' ].bind ('<Return>' , selectObject )
1803
1857
1804
1858
if platform .system () == 'Darwin' :
1805
1859
self .object_selector ['treeview' ].bind ('<Button-2>' , rightClick )
@@ -1918,7 +1972,7 @@ def getRelativeMousePos(self, pos : tuple, widget : tk.Widget):
1918
1972
def selectObject (
1919
1973
self ,
1920
1974
obj : wmwpy .classes .Object = None ,
1921
- event : tk .Event = None ,
1975
+ event : tk .Event | None = None ,
1922
1976
partInfo : dict [str , str ] = None ,
1923
1977
):
1924
1978
self .selectedPart = {
@@ -1936,21 +1990,24 @@ def selectObject(
1936
1990
self .selectedPart ['id' ] = partInfo .get ('id' , None )
1937
1991
self .selectedPart ['property' ] = partInfo .get ('property' , None )
1938
1992
1939
- if event :
1940
- obj_pos = self .getObjectPosition (obj .pos , obj .offset )
1941
- self .dragInfo ['offset' ] = numpy .array ((obj_pos [0 ], obj_pos [1 ])) - (self .level_canvas .canvasx (event .x ), self .level_canvas .canvasy (event .y ))
1942
1993
1943
1994
# logging.debug(obj.name)
1944
1995
logging .debug ('object' )
1945
1996
1946
1997
self .updateObject (obj )
1947
1998
self .updateProperties ()
1948
1999
self .updateSelectionRectangle ()
2000
+ if event :
2001
+ obj_pos = self .getObjectPosition (obj .pos , obj .offset )
2002
+ self .dragInfo ['offset' ] = numpy .array ((obj_pos [0 ], obj_pos [1 ])) - (self .level_canvas .canvasx (event .x ), self .level_canvas .canvasy (event .y ))
2003
+ else :
2004
+ self .dragInfo ['offset' ] = (0 ,0 )
1949
2005
1950
2006
if self .selectedObject == None :
1951
2007
if len (self .object_selector ['treeview' ].selection ()) > 0 :
1952
2008
self .object_selector ['treeview' ].selection_remove (self .object_selector ['treeview' ].selection ()[0 ])
1953
2009
else :
2010
+
1954
2011
children = self .object_selector ['treeview' ].get_children ('' )
1955
2012
1956
2013
selected = None
@@ -1985,6 +2042,7 @@ def selectPart(
1985
2042
}
1986
2043
)
1987
2044
logging .debug (f'selected part: { self .selectedPart } ' )
2045
+ return self .selectedPart
1988
2046
1989
2047
def dragPart (
1990
2048
self ,
0 commit comments