yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
app_delegate.mm
Go to the documentation of this file.
1// AppDelegate.mm
2
3// Must define before any ImGui includes (needed by imgui_test_engine via editor_manager.h)
4#ifndef IMGUI_DEFINE_MATH_OPERATORS
5#define IMGUI_DEFINE_MATH_OPERATORS
6#endif
7
9#import "app/controller.h"
10#import "util/file_util.h"
11#import "app/editor/editor.h"
12#import "app/rom.h"
13#include <span>
14#include <vector>
15
16using std::span;
17
18#if defined(__APPLE__) && defined(__MACH__)
19/* Apple OSX and iOS (Darwin). */
20#include <TargetConditionals.h>
21
22#import <CoreText/CoreText.h>
23
24#if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
25/* iOS in Xcode simulator */
26
27#elif TARGET_OS_MAC == 1
28/* macOS */
29#import <Cocoa/Cocoa.h>
30
31@interface AppDelegate : NSObject <NSApplicationDelegate>
32- (void)setupMenus;
33// - (void)changeApplicationIcon;
34@end
35
36@implementation AppDelegate
37
38// - (void)changeApplicationIcon {
39// NSImage *newIcon = [NSImage imageNamed:@"newIcon"];
40// [NSApp setApplicationIconImage:newIcon];
41// }
42
43- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
44 [self setupMenus];
45
46 // Disable automatic UI state persistence to prevent crashes
47 // macOS NSPersistentUIManager can crash if state gets corrupted
48 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSQuitAlwaysKeepsWindows"];
49}
50
51- (void)setupMenus {
52 NSMenu *mainMenu = [NSApp mainMenu];
53
54 NSMenuItem *fileMenuItem = [mainMenu itemWithTitle:@"File"];
55 if (!fileMenuItem) {
56 NSMenu *fileMenu = [[NSMenu alloc] initWithTitle:@"File"];
57 fileMenuItem = [[NSMenuItem alloc] initWithTitle:@"File" action:nil keyEquivalent:@""];
58 [fileMenuItem setSubmenu:fileMenu];
59
60 NSMenuItem *openItem = [[NSMenuItem alloc] initWithTitle:@"Open"
61 action:@selector(openFileAction:)
62 keyEquivalent:@"o"];
63 [fileMenu addItem:openItem];
64
65 // Open Recent
66 NSMenu *openRecentMenu = [[NSMenu alloc] initWithTitle:@"Open Recent"];
67 NSMenuItem *openRecentMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open Recent"
68 action:nil
69 keyEquivalent:@""];
70 [openRecentMenuItem setSubmenu:openRecentMenu];
71 [fileMenu addItem:openRecentMenuItem];
72
73 // Add a separator
74 [fileMenu addItem:[NSMenuItem separatorItem]];
75
76 // Save
77 NSMenuItem *saveItem = [[NSMenuItem alloc] initWithTitle:@"Save" action:nil keyEquivalent:@"s"];
78 [fileMenu addItem:saveItem];
79
80 // Separator
81 [fileMenu addItem:[NSMenuItem separatorItem]];
82
83 // Options submenu
84 NSMenu *optionsMenu = [[NSMenu alloc] initWithTitle:@"Options"];
85 NSMenuItem *optionsMenuItem = [[NSMenuItem alloc] initWithTitle:@"Options"
86 action:nil
87 keyEquivalent:@""];
88 [optionsMenuItem setSubmenu:optionsMenu];
89
90 // Flag checkmark field
91 NSMenuItem *flagItem = [[NSMenuItem alloc] initWithTitle:@"Flag"
92 action:@selector(toggleFlagAction:)
93 keyEquivalent:@""];
94 [flagItem setTarget:self];
95 [flagItem setState:NSControlStateValueOff];
96 [optionsMenu addItem:flagItem];
97 [fileMenu addItem:optionsMenuItem];
98
99 [mainMenu insertItem:fileMenuItem atIndex:1];
100 }
101
102 NSMenuItem *editMenuItem = [mainMenu itemWithTitle:@"Edit"];
103 if (!editMenuItem) {
104 NSMenu *editMenu = [[NSMenu alloc] initWithTitle:@"Edit"];
105 editMenuItem = [[NSMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:@""];
106 [editMenuItem setSubmenu:editMenu];
107
108 NSMenuItem *undoItem = [[NSMenuItem alloc] initWithTitle:@"Undo" action:nil keyEquivalent:@"z"];
109
110 [editMenu addItem:undoItem];
111
112 NSMenuItem *redoItem = [[NSMenuItem alloc] initWithTitle:@"Redo" action:nil keyEquivalent:@"Z"];
113
114 [editMenu addItem:redoItem];
115
116 // Add a separator
117 [editMenu addItem:[NSMenuItem separatorItem]];
118
119 NSMenuItem *cutItem = [[NSMenuItem alloc] initWithTitle:@"Cut"
120 action:@selector(cutAction:)
121 keyEquivalent:@"x"];
122 [editMenu addItem:cutItem];
123
124 NSMenuItem *copyItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:nil keyEquivalent:@"c"];
125 [editMenu addItem:copyItem];
126
127 NSMenuItem *pasteItem = [[NSMenuItem alloc] initWithTitle:@"Paste"
128 action:nil
129 keyEquivalent:@"v"];
130
131 [editMenu addItem:pasteItem];
132
133 // Add a separator
134 [editMenu addItem:[NSMenuItem separatorItem]];
135
136 NSMenuItem *selectAllItem = [[NSMenuItem alloc] initWithTitle:@"Select All"
137 action:nil
138 keyEquivalent:@"a"];
139
140 [editMenu addItem:selectAllItem];
141
142 [mainMenu insertItem:editMenuItem atIndex:2];
143 }
144
145 NSMenuItem *viewMenuItem = [mainMenu itemWithTitle:@"View"];
146 if (!viewMenuItem) {
147 NSMenu *viewMenu = [[NSMenu alloc] initWithTitle:@"View"];
148 viewMenuItem = [[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""];
149 [viewMenuItem setSubmenu:viewMenu];
150
151 // Emulator view button
152 NSMenuItem *emulatorViewItem = [[NSMenuItem alloc] initWithTitle:@"Emulator View"
153 action:nil
154 keyEquivalent:@"1"];
155
156 [viewMenu addItem:emulatorViewItem];
157
158 // Hex Editor View
159 NSMenuItem *hexEditorViewItem = [[NSMenuItem alloc] initWithTitle:@"Hex Editor View"
160 action:nil
161 keyEquivalent:@"2"];
162
163 [viewMenu addItem:hexEditorViewItem];
164
165 // Disassembly view button
166 NSMenuItem *disassemblyViewItem = [[NSMenuItem alloc] initWithTitle:@"Disassembly View"
167 action:nil
168 keyEquivalent:@"3"];
169
170 [viewMenu addItem:disassemblyViewItem];
171
172 // Memory view button
173 NSMenuItem *memoryViewItem = [[NSMenuItem alloc] initWithTitle:@"Memory View"
174 action:nil
175 keyEquivalent:@"4"];
176
177 [viewMenu addItem:memoryViewItem];
178
179 // Add a separator
180 [viewMenu addItem:[NSMenuItem separatorItem]];
181
182 // Toggle fullscreen button
183 NSMenuItem *toggleFullscreenItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Fullscreen"
184 action:nil
185 keyEquivalent:@"f"];
186
187 [viewMenu addItem:toggleFullscreenItem];
188
189 [mainMenu insertItem:viewMenuItem atIndex:3];
190 }
191
192 NSMenuItem *helpMenuItem = [mainMenu itemWithTitle:@"Help"];
193 if (!helpMenuItem) {
194 NSMenu *helpMenu = [[NSMenu alloc] initWithTitle:@"Help"];
195 helpMenuItem = [[NSMenuItem alloc] initWithTitle:@"Help" action:nil keyEquivalent:@""];
196 [helpMenuItem setSubmenu:helpMenu];
197
198 // URL to online documentation
199 NSMenuItem *documentationItem = [[NSMenuItem alloc] initWithTitle:@"Documentation"
200 action:nil
201 keyEquivalent:@"?"];
202 [helpMenu addItem:documentationItem];
203
204 [mainMenu insertItem:helpMenuItem atIndex:4];
205 }
206}
207
208// Action method for the New menu item
209- (void)newFileAction:(id)sender {
210 NSLog(@"New File action triggered");
211}
212
213- (void)toggleFlagAction:(id)sender {
214 NSMenuItem *flagItem = (NSMenuItem *)sender;
215 if ([flagItem state] == NSControlStateValueOff) {
216 [flagItem setState:NSControlStateValueOn];
217 } else {
218 [flagItem setState:NSControlStateValueOff];
219 }
220}
221
222- (void)openFileAction:(id)sender {
223 // TODO: Re-implmenent this without the SharedRom singleton
224 // if (!yaze::SharedRom::shared_rom_
225 // ->LoadFromFile(yaze::util::FileDialogWrapper::ShowOpenFileDialog())
226 // .ok()) {
227 // NSAlert *alert = [[NSAlert alloc] init];
228 // [alert setMessageText:@"Error"];
229 // [alert setInformativeText:@"Failed to load file."];
230 // [alert addButtonWithTitle:@"OK"];
231 // [alert runModal];
232 // }
233}
234
235- (void)cutAction:(id)sender {
236 // TODO: Implement
237}
238
239- (void)openRecentFileAction:(id)sender {
240 NSLog(@"Open Recent File action triggered");
241}
242
243@end
244
245extern "C" void yaze_initialize_cococa() {
246 @autoreleasepool {
247 AppDelegate *delegate = [[AppDelegate alloc] init];
248 [NSApplication sharedApplication];
249 [NSApp setDelegate:delegate];
250 [NSApp finishLaunching];
251 }
252}
253
254extern "C" int yaze_run_cocoa_app_delegate(const char *filename) {
255 yaze_initialize_cococa();
256 auto controller = std::make_unique<yaze::Controller>();
257 EXIT_IF_ERROR(controller->OnEntry(filename));
258 while (controller->IsActive()) {
259 @autoreleasepool {
260 controller->OnInput();
261 if (auto status = controller->OnLoad(); !status.ok()) {
262 NSAlert *alert = [[NSAlert alloc] init];
263 [alert setMessageText:@"Error"];
264 [alert setInformativeText:[NSString stringWithUTF8String:status.message().data()]];
265 [alert addButtonWithTitle:@"OK"];
266 [alert runModal];
267 break;
268 }
269 controller->DoRender();
270 }
271 }
272 controller->OnExit();
273 return EXIT_SUCCESS;
274}
275
276#endif
277
278#endif
#define EXIT_IF_ERROR(expression)
Definition macro.h:35