diff options
-rw-r--r-- | src/app.c | 17 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 3 | ||||
-rw-r--r-- | src/ui/macos.m | 9 | ||||
-rw-r--r-- | src/ui/util.c | 15 | ||||
-rw-r--r-- | src/ui/util.h | 1 | ||||
-rw-r--r-- | src/ui/widget.c | 19 | ||||
-rw-r--r-- | src/ui/widget.h | 1 |
7 files changed, 61 insertions, 4 deletions
@@ -406,6 +406,23 @@ iBool handleCommand_App(const char *cmd) { | |||
406 | refresh_Widget(tabs); | 406 | refresh_Widget(tabs); |
407 | return iTrue; | 407 | return iTrue; |
408 | } | 408 | } |
409 | else if (equal_Command(cmd, "tabs.close")) { | ||
410 | iWidget *tabs = findWidget_App("doctabs"); | ||
411 | if (tabCount_Widget(tabs) > 1) { | ||
412 | size_t index = tabPageIndex_Widget(tabs, document_App()); | ||
413 | iWidget *closed = removeTabPage_Widget(tabs, index); | ||
414 | destroy_Widget(closed); /* released later */ | ||
415 | if (index == tabCount_Widget(tabs)) { | ||
416 | index--; | ||
417 | } | ||
418 | arrange_Widget(tabs); | ||
419 | postCommandf_App("tabs.switch page:%p", tabPage_Widget(tabs, index)); | ||
420 | } | ||
421 | else { | ||
422 | postCommand_App("quit"); | ||
423 | } | ||
424 | return iTrue; | ||
425 | } | ||
409 | else if (equal_Command(cmd, "quit")) { | 426 | else if (equal_Command(cmd, "quit")) { |
410 | SDL_Event ev; | 427 | SDL_Event ev; |
411 | ev.type = SDL_QUIT; | 428 | ev.type = SDL_QUIT; |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index a789a759..53eb06bd 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -145,6 +145,9 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
145 | { "Copy", 'c', KMOD_PRIMARY, "copy" }, | 145 | { "Copy", 'c', KMOD_PRIMARY, "copy" }, |
146 | { "Copy Link", 0, 0, "document.copylink" } }, | 146 | { "Copy Link", 0, 0, "document.copylink" } }, |
147 | 6); | 147 | 6); |
148 | #if !defined (iPlatformApple) /* in system menu */ | ||
149 | addAction_Widget(w, SDLK_w, KMOD_PRIMARY, "tabs.close"); | ||
150 | #endif | ||
148 | } | 151 | } |
149 | 152 | ||
150 | void deinit_DocumentWidget(iDocumentWidget *d) { | 153 | void deinit_DocumentWidget(iDocumentWidget *d) { |
diff --git a/src/ui/macos.m b/src/ui/macos.m index bf5c2f84..dcae94e6 100644 --- a/src/ui/macos.m +++ b/src/ui/macos.m | |||
@@ -180,6 +180,10 @@ enum iTouchBarVariant { | |||
180 | postCommand_App("preferences"); | 180 | postCommand_App("preferences"); |
181 | } | 181 | } |
182 | 182 | ||
183 | - (void)closeTab { | ||
184 | postCommand_App("tabs.close"); | ||
185 | } | ||
186 | |||
183 | - (void)postMenuItemCommand:(id)sender { | 187 | - (void)postMenuItemCommand:(id)sender { |
184 | NSString *command = [menuCommands objectForKey:[(NSMenuItem *)sender title]]; | 188 | NSString *command = [menuCommands objectForKey:[(NSMenuItem *)sender title]]; |
185 | if (command) { | 189 | if (command) { |
@@ -347,6 +351,11 @@ void setupApplication_MacOS(void) { | |||
347 | NSMenuItem *prefsItem = [appMenu itemWithTitle:@"Preferences…"]; | 351 | NSMenuItem *prefsItem = [appMenu itemWithTitle:@"Preferences…"]; |
348 | prefsItem.target = myDel; | 352 | prefsItem.target = myDel; |
349 | prefsItem.action = @selector(showPreferences); | 353 | prefsItem.action = @selector(showPreferences); |
354 | /* Get rid of the default window close item */ | ||
355 | NSMenu *windowMenu = [[[NSApp mainMenu] itemWithTitle:@"Window"] submenu]; | ||
356 | NSMenuItem *windowCloseItem = [windowMenu itemWithTitle:@"Close"]; | ||
357 | windowCloseItem.target = myDel; | ||
358 | windowCloseItem.action = @selector(closeTab); | ||
350 | } | 359 | } |
351 | 360 | ||
352 | void insertMenuItems_MacOS(const char *menuLabel, const iMenuItem *items, size_t count) { | 361 | void insertMenuItems_MacOS(const char *menuLabel, const iMenuItem *items, size_t count) { |
diff --git a/src/ui/util.c b/src/ui/util.c index b0bef69e..40debd28 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -295,7 +295,11 @@ static iBool tabSwitcher_(iWidget *tabs, const char *cmd) { | |||
295 | iWidget *makeTabs_Widget(iWidget *parent) { | 295 | iWidget *makeTabs_Widget(iWidget *parent) { |
296 | iWidget *tabs = makeVDiv_Widget(); | 296 | iWidget *tabs = makeVDiv_Widget(); |
297 | iWidget *buttons = addChild_Widget(tabs, iClob(new_Widget())); | 297 | iWidget *buttons = addChild_Widget(tabs, iClob(new_Widget())); |
298 | setFlags_Widget(buttons, arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag, iTrue); | 298 | buttons->rect.size.y = 2 * gap_UI + lineHeight_Text(default_FontId); |
299 | setFlags_Widget(buttons, | ||
300 | resizeChildren_WidgetFlag | arrangeHorizontal_WidgetFlag | | ||
301 | fixedHeight_WidgetFlag, | ||
302 | iTrue); | ||
299 | setId_Widget(buttons, "tabs.buttons"); | 303 | setId_Widget(buttons, "tabs.buttons"); |
300 | iWidget *pages = addChildFlags_Widget( | 304 | iWidget *pages = addChildFlags_Widget( |
301 | tabs, iClob(new_Widget()), expand_WidgetFlag | resizeChildren_WidgetFlag); | 305 | tabs, iClob(new_Widget()), expand_WidgetFlag | resizeChildren_WidgetFlag); |
@@ -313,7 +317,7 @@ static void addTabPage_Widget_(iWidget *tabs, enum iWidgetAddPos addPos, iWidget | |||
313 | findChild_Widget(tabs, "tabs.buttons"), | 317 | findChild_Widget(tabs, "tabs.buttons"), |
314 | iClob(new_LabelWidget(label, key, kmods, format_CStr("tabs.switch page:%p", page))), | 318 | iClob(new_LabelWidget(label, key, kmods, format_CStr("tabs.switch page:%p", page))), |
315 | addPos); | 319 | addPos); |
316 | setFlags_Widget(button, selected_WidgetFlag, isSel); | 320 | setFlags_Widget(button, selected_WidgetFlag | expand_WidgetFlag, isSel); |
317 | addChildPos_Widget(pages, page, addPos); | 321 | addChildPos_Widget(pages, page, addPos); |
318 | setFlags_Widget(page, hidden_WidgetFlag | disabled_WidgetFlag, !isSel); | 322 | setFlags_Widget(page, hidden_WidgetFlag | disabled_WidgetFlag, !isSel); |
319 | } | 323 | } |
@@ -385,6 +389,11 @@ void setTabPageLabel_Widget(iWidget *tabs, const iAnyObject *page, const iString | |||
385 | arrange_Widget(tabs); | 389 | arrange_Widget(tabs); |
386 | } | 390 | } |
387 | 391 | ||
392 | size_t tabPageIndex_Widget(const iWidget *tabs, const iAnyObject *page) { | ||
393 | iWidget *pages = findChild_Widget(tabs, "tabs.pages"); | ||
394 | return childIndex_Widget(pages, page); | ||
395 | } | ||
396 | |||
388 | const iWidget *currentTabPage_Widget(const iWidget *tabs) { | 397 | const iWidget *currentTabPage_Widget(const iWidget *tabs) { |
389 | iWidget *pages = findChild_Widget(tabs, "tabs.pages"); | 398 | iWidget *pages = findChild_Widget(tabs, "tabs.pages"); |
390 | iConstForEach(ObjectList, i, pages->children) { | 399 | iConstForEach(ObjectList, i, pages->children) { |
@@ -396,7 +405,7 @@ const iWidget *currentTabPage_Widget(const iWidget *tabs) { | |||
396 | } | 405 | } |
397 | 406 | ||
398 | size_t tabCount_Widget(const iWidget *tabs) { | 407 | size_t tabCount_Widget(const iWidget *tabs) { |
399 | return childCount_Widget(findChild_Widget(tabs, "tabs.buttons")); | 408 | return childCount_Widget(findChild_Widget(tabs, "tabs.pages")); |
400 | } | 409 | } |
401 | 410 | ||
402 | /*-----------------------------------------------------------------------------------------------*/ | 411 | /*-----------------------------------------------------------------------------------------------*/ |
diff --git a/src/ui/util.h b/src/ui/util.h index 1f35b8e8..6eeea11d 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -101,6 +101,7 @@ iWidget * tabPage_Widget (iWidget *tabs, size_t index); | |||
101 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ | 101 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ |
102 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); | 102 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); |
103 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); | 103 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); |
104 | size_t tabPageIndex_Widget (const iWidget *tabs, const iAnyObject *page); | ||
104 | const iWidget *currentTabPage_Widget(const iWidget *tabs); | 105 | const iWidget *currentTabPage_Widget(const iWidget *tabs); |
105 | size_t tabCount_Widget (const iWidget *tabs); | 106 | size_t tabCount_Widget (const iWidget *tabs); |
106 | 107 | ||
diff --git a/src/ui/widget.c b/src/ui/widget.c index 0db8b8fd..56b05aa6 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -33,7 +33,12 @@ void destroyPending_Widget(void) { | |||
33 | iForEach(PtrSet, i, rootData_.pendingDestruction) { | 33 | iForEach(PtrSet, i, rootData_.pendingDestruction) { |
34 | iWidget *widget = *i.value; | 34 | iWidget *widget = *i.value; |
35 | remove_PtrSet(onTop_RootData_(), widget); | 35 | remove_PtrSet(onTop_RootData_(), widget); |
36 | iRelease(removeChild_Widget(widget->parent, widget)); | 36 | if (widget->parent) { |
37 | iRelease(removeChild_Widget(widget->parent, widget)); | ||
38 | } | ||
39 | else { | ||
40 | iRelease(widget); | ||
41 | } | ||
37 | remove_PtrSetIterator(&i); | 42 | remove_PtrSetIterator(&i); |
38 | } | 43 | } |
39 | } | 44 | } |
@@ -481,6 +486,7 @@ iAny *addChildFlags_Widget(iWidget *d, iAnyObject *child, int childFlags) { | |||
481 | } | 486 | } |
482 | 487 | ||
483 | iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { | 488 | iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { |
489 | iAssert(child); | ||
484 | ref_Object(child); | 490 | ref_Object(child); |
485 | iBool found = iFalse; | 491 | iBool found = iFalse; |
486 | iForEach(ObjectList, i, d->children) { | 492 | iForEach(ObjectList, i, d->children) { |
@@ -505,6 +511,17 @@ iAny *child_Widget(iWidget *d, size_t index) { | |||
505 | return NULL; | 511 | return NULL; |
506 | } | 512 | } |
507 | 513 | ||
514 | size_t childIndex_Widget(const iWidget *d, const iAnyObject *child) { | ||
515 | size_t index = 0; | ||
516 | iConstForEach(ObjectList, i, d->children) { | ||
517 | if (i.object == child) { | ||
518 | return index; | ||
519 | } | ||
520 | index++; | ||
521 | } | ||
522 | return iInvalidPos; | ||
523 | } | ||
524 | |||
508 | iAny *findChild_Widget(const iWidget *d, const char *id) { | 525 | iAny *findChild_Widget(const iWidget *d, const char *id) { |
509 | if (cmp_String(id_Widget(d), id) == 0) { | 526 | if (cmp_String(id_Widget(d), id) == 0) { |
510 | return iConstCast(iAny *, d); | 527 | return iConstCast(iAny *, d); |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 0aff6505..8277b4ba 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -128,6 +128,7 @@ iAny * addChildPos_Widget (iWidget *, iAnyObject *child, enum iWidgetAddPos ad | |||
128 | iAny * addChildFlags_Widget(iWidget *, iAnyObject *child, int childFlags); /* holds a ref */ | 128 | iAny * addChildFlags_Widget(iWidget *, iAnyObject *child, int childFlags); /* holds a ref */ |
129 | iAny * removeChild_Widget (iWidget *, iAnyObject *child); /* returns a ref */ | 129 | iAny * removeChild_Widget (iWidget *, iAnyObject *child); /* returns a ref */ |
130 | iAny * child_Widget (iWidget *, size_t index); /* O(n) */ | 130 | iAny * child_Widget (iWidget *, size_t index); /* O(n) */ |
131 | size_t childIndex_Widget (const iWidget *, const iAnyObject *child); /* O(n) */ | ||
131 | void arrange_Widget (iWidget *); | 132 | void arrange_Widget (iWidget *); |
132 | iBool dispatchEvent_Widget(iWidget *, const SDL_Event *); | 133 | iBool dispatchEvent_Widget(iWidget *, const SDL_Event *); |
133 | iBool processEvent_Widget (iWidget *, const SDL_Event *); | 134 | iBool processEvent_Widget (iWidget *, const SDL_Event *); |