add: right-click of changing skin for desktop pet (#99)
* fix: skin icon size * fix: skin icon size * fix: skin icon size * fix: skin icon size * fix: skin icon size * fix: skin icon size * add: right click logic of changing skin
This commit is contained in:
@@ -308,6 +308,7 @@ if sys.platform == 'darwin':
|
||||
|
||||
# Load skin
|
||||
self.load_skin(skin_name)
|
||||
self.available_skins = SkinLoader.list_skins()
|
||||
|
||||
# Get screen size
|
||||
from AppKit import NSScreen, NSWindowCollectionBehaviorCanJoinAllSpaces, NSWindowCollectionBehaviorStationary
|
||||
@@ -393,6 +394,29 @@ if sys.platform == 'darwin':
|
||||
"""Accept first mouse click"""
|
||||
return True
|
||||
|
||||
def rightMouseDown_(self, event):
|
||||
from AppKit import NSMenu, NSMenuItem, NSApp
|
||||
|
||||
menu = NSMenu.alloc().init()
|
||||
pet = self.window().delegate() # Assuming the window’s delegate is MacPet instance
|
||||
|
||||
for skin_name in pet.available_skins: # preload this in MacPet.__init__
|
||||
item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
|
||||
skin_name,
|
||||
'changeSkin:',
|
||||
''
|
||||
)
|
||||
item.setTarget_(pet)
|
||||
item.setRepresentedObject_(skin_name)
|
||||
menu.addItem_(item)
|
||||
|
||||
menu.addItem_(NSMenuItem.separatorItem())
|
||||
quit_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Quit', 'terminate:', '')
|
||||
menu.addItem_(quit_item)
|
||||
|
||||
NSApp.activateIgnoringOtherApps_(True)
|
||||
NSMenu.popUpContextMenu_withEvent_forView_(menu, event, self)
|
||||
|
||||
# Create draggable view
|
||||
self.content_view = DraggableImageView.alloc().initWithFrame_(
|
||||
NSMakeRect(0, 0, self.display_width, self.display_height)
|
||||
@@ -577,6 +601,13 @@ if sys.platform == 'darwin':
|
||||
"""Run the application"""
|
||||
AppHelper.runEventLoop()
|
||||
|
||||
def changeSkin_(self, sender):
|
||||
skin_name = sender.representedObject()
|
||||
print(f"Changing skin to: {skin_name}")
|
||||
self.load_skin(skin_name)
|
||||
self.current_state = 'idle'
|
||||
self.frame_idx = 0
|
||||
|
||||
# ============================================================================
|
||||
# Windows Implementation - tkinter with transparentcolor
|
||||
# ============================================================================
|
||||
@@ -615,6 +646,7 @@ else:
|
||||
self.label.bind('<Button-1>', lambda e: setattr(self, '_d', (e.x, e.y)))
|
||||
self.label.bind('<B1-Motion>', self._drag)
|
||||
self.label.bind('<Double-1>', lambda e: (self.root.destroy(), os._exit(0)))
|
||||
self.label.bind('<Button-3>', self._on_right_click)
|
||||
|
||||
# Animation state
|
||||
self.current_state = 'idle'
|
||||
@@ -755,6 +787,24 @@ else:
|
||||
"""Run the application (already in mainloop)"""
|
||||
pass
|
||||
|
||||
def _on_right_click(self, event):
|
||||
# Build a dynamic menu of all available skins
|
||||
menu = tk.Menu(self.root, tearoff=0)
|
||||
for skin_name in SkinLoader.list_skins():
|
||||
menu.add_command(
|
||||
label=skin_name,
|
||||
command=lambda name=skin_name: self._change_skin(name)
|
||||
)
|
||||
menu.add_separator()
|
||||
menu.add_command(label="Quit", command=lambda: (self.root.destroy(), os._exit(0)))
|
||||
menu.tk_popup(event.x_root, event.y_root)
|
||||
|
||||
def _change_skin(self, skin_name):
|
||||
print(f"Changing skin to: {skin_name}")
|
||||
self.load_skin(skin_name)
|
||||
self.current_state = 'idle'
|
||||
self.frame_idx = 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Singleton: if port already in use, another instance is running
|
||||
import socket
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": {
|
||||
"width": 40,
|
||||
"height": 61
|
||||
"width": 80,
|
||||
"height": 122
|
||||
},
|
||||
"animations": {
|
||||
"idle": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"description": "像素风小恐龙 Dinosaur",
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": { "width": 64, "height": 64 },
|
||||
"size": { "width": 128, "height": 128 },
|
||||
"animations": {
|
||||
"idle": {
|
||||
"file": "skin.png",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"description": "像素风小恐龙 Doux",
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": { "width": 48, "height": 48 },
|
||||
"size": { "width": 128, "height": 128 },
|
||||
"animations": {
|
||||
"idle": {
|
||||
"file": "skin.png",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"description": "Line 角色皮肤",
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": { "width": 39, "height": 46 },
|
||||
"size": { "width": 128, "height": 128 },
|
||||
"animations": {
|
||||
"idle": {
|
||||
"file": "skin.png",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"description": "像素风小恐龙 Mort",
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": { "width": 48, "height": 48 },
|
||||
"size": { "width": 128, "height": 128 },
|
||||
"animations": {
|
||||
"idle": {
|
||||
"file": "skin.png",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"description": "像素风小恐龙 Tard",
|
||||
"style": "pixel",
|
||||
"format": "sprite",
|
||||
"size": { "width": 48, "height": 48 },
|
||||
"size": { "width": 128, "height": 128 },
|
||||
"animations": {
|
||||
"idle": {
|
||||
"file": "skin.png",
|
||||
|
||||
Reference in New Issue
Block a user