Repository navigation
Expand file tree
/
Copy pathslot_editor.py
More file actions
173 lines (145 loc) · 6.14 KB
/
Copy pathslot_editor.py
File metadata and controls
173 lines (145 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env python3
"""Standalone editor window for MicPipe slot editing"""
import sys
import json
def main():
if len(sys.argv) < 4:
print(json.dumps({"error": "Usage: slot_editor.py <slot_index> <title> <prompt>"}))
sys.exit(1)
slot_index = int(sys.argv[1])
current_title = sys.argv[2]
current_prompt = sys.argv[3]
# Import Cocoa
from AppKit import (
NSApplication, NSWindow, NSTextField, NSTextView, NSScrollView,
NSButton, NSFont, NSMakeRect, NSWindowStyleMaskTitled,
NSWindowStyleMaskClosable, NSBackingStoreBuffered,
NSBezelStyleRounded, NSFloatingWindowLevel,
NSApplicationActivationPolicyRegular, NSMenu, NSMenuItem,
NSEventModifierFlagCommand
)
from Foundation import NSObject
import objc
# Create application with regular activation policy (shows in dock, can receive focus)
app = NSApplication.sharedApplication()
app.setActivationPolicy_(NSApplicationActivationPolicyRegular)
# Standard edit shortcuts such as Cmd+A/C/V depend on menu actions
# being available in the responder chain for this standalone app.
main_menu = NSMenu.alloc().init()
app_menu_item = NSMenuItem.alloc().init()
app_menu = NSMenu.alloc().initWithTitle_("MicPipe")
quit_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
"Quit MicPipe", "terminate:", "q"
)
app_menu.addItem_(quit_item)
app_menu_item.setSubmenu_(app_menu)
main_menu.addItem_(app_menu_item)
edit_menu_item = NSMenuItem.alloc().init()
edit_menu = NSMenu.alloc().initWithTitle_("Edit")
edit_actions = [
("Select All", "selectAll:", "a", 0),
("Cut", "cut:", "x", 0),
("Copy", "copy:", "c", 0),
("Paste", "paste:", "v", 0),
]
for title, action, key, extra_flags in edit_actions:
item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(title, action, key)
item.setKeyEquivalentModifierMask_(NSEventModifierFlagCommand | extra_flags)
edit_menu.addItem_(item)
edit_menu_item.setSubmenu_(edit_menu)
main_menu.addItem_(edit_menu_item)
app.setMainMenu_(main_menu)
result = {"saved": False, "title": "", "prompt": ""}
# Create window
window_rect = NSMakeRect(200, 200, 500, 350)
window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
window_rect,
NSWindowStyleMaskTitled | NSWindowStyleMaskClosable,
NSBackingStoreBuffered,
False
)
window.setTitle_(f"Edit Slot {slot_index + 1}")
window.setLevel_(NSFloatingWindowLevel) # Float above other windows
content_view = window.contentView()
# Title label
title_label = NSTextField.alloc().initWithFrame_(NSMakeRect(20, 300, 460, 20))
title_label.setStringValue_("Title (shown in menu):")
title_label.setBezeled_(False)
title_label.setDrawsBackground_(False)
title_label.setEditable_(False)
title_label.setSelectable_(False)
content_view.addSubview_(title_label)
# Title input
title_field = NSTextField.alloc().initWithFrame_(NSMakeRect(20, 270, 460, 24))
title_field.setStringValue_(current_title)
title_field.setFont_(NSFont.systemFontOfSize_(13))
title_field.setEditable_(True)
title_field.setSelectable_(True)
content_view.addSubview_(title_field)
# Prompt label
prompt_label = NSTextField.alloc().initWithFrame_(NSMakeRect(20, 240, 460, 20))
prompt_label.setStringValue_("Prompt (multi-line, press Enter for new line):")
prompt_label.setBezeled_(False)
prompt_label.setDrawsBackground_(False)
prompt_label.setEditable_(False)
prompt_label.setSelectable_(False)
content_view.addSubview_(prompt_label)
# Prompt text view with scroll
scroll_view = NSScrollView.alloc().initWithFrame_(NSMakeRect(20, 60, 460, 175))
scroll_view.setBorderType_(1)
scroll_view.setHasVerticalScroller_(True)
prompt_text = NSTextView.alloc().initWithFrame_(NSMakeRect(0, 0, 440, 175))
prompt_text.setString_(current_prompt)
prompt_text.setFont_(NSFont.systemFontOfSize_(13))
prompt_text.setEditable_(True)
prompt_text.setSelectable_(True)
prompt_text.setAllowsUndo_(True)
prompt_text.setRichText_(False)
prompt_text.setImportsGraphics_(False)
prompt_text.setUsesRuler_(False)
scroll_view.setDocumentView_(prompt_text)
content_view.addSubview_(scroll_view)
# Button handler
class ButtonHandler(NSObject):
@objc.typedSelector(b'v@:@')
def saveClicked_(self, sender):
result["saved"] = True
result["title"] = str(title_field.stringValue())
result["prompt"] = str(prompt_text.string())
app.stop_(None)
@objc.typedSelector(b'v@:@')
def cancelClicked_(self, sender):
result["saved"] = False
app.stop_(None)
class WindowHandler(NSObject):
@objc.typedSelector(b'v@:@')
def windowWillClose_(self, notification):
result["saved"] = False
app.stop_(None)
handler = ButtonHandler.alloc().init()
window_handler = WindowHandler.alloc().init()
window.setDelegate_(window_handler)
cancel_btn = NSButton.alloc().initWithFrame_(NSMakeRect(380, 15, 100, 32))
cancel_btn.setTitle_("Cancel")
cancel_btn.setBezelStyle_(NSBezelStyleRounded)
cancel_btn.setTarget_(handler)
cancel_btn.setAction_(objc.selector(handler.cancelClicked_, signature=b'v@:@'))
content_view.addSubview_(cancel_btn)
save_btn = NSButton.alloc().initWithFrame_(NSMakeRect(270, 15, 100, 32))
save_btn.setTitle_("Save")
save_btn.setBezelStyle_(NSBezelStyleRounded)
save_btn.setTarget_(handler)
save_btn.setAction_(objc.selector(handler.saveClicked_, signature=b'v@:@'))
content_view.addSubview_(save_btn)
# Show window and activate
window.center()
window.makeKeyAndOrderFront_(None)
window.makeFirstResponder_(title_field)
# Activate this app (bring to front)
app.activateIgnoringOtherApps_(True)
# Run event loop
app.run()
# Output result as JSON
print(json.dumps(result))
if __name__ == "__main__":
main()