From d6f28abebe5323d306c9a7c63bd2f7bb7bc90d1c Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Wed, 8 Aug 2007 09:50:01 +0000 Subject: [PATCH] Added a popup menu to the tabview: for now it only contains a "close tab" item. Note that you can also close the tab by clicking on it with the tertiary mouse button. Renamed some methods of TermWindow. I'm not really happy with this code (tab creation/deletion code is spread between TermWindow and SmartTabView), I will need to come up with something better. There are still some visual glitches when tabs are switched, created or deleted. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21850 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/terminal/SmartTabView.cpp | 103 ++++++++++++++++++---- src/apps/terminal/SmartTabView.h | 10 +++ src/apps/terminal/TermWindow.cpp | 136 +++++++++++++++-------------- src/apps/terminal/TermWindow.h | 3 +- 4 files changed, 170 insertions(+), 82 deletions(-) diff --git a/src/apps/terminal/SmartTabView.cpp b/src/apps/terminal/SmartTabView.cpp index 6f8c1a1904..6df8557cb2 100644 --- a/src/apps/terminal/SmartTabView.cpp +++ b/src/apps/terminal/SmartTabView.cpp @@ -8,11 +8,16 @@ #include "SmartTabView.h" +#include #include +#include +#include #include #include +const static uint32 kCloseTab = 'ClTb'; + SmartTabView::SmartTabView(BRect frame, const char *name, button_width width, uint32 resizingMode, uint32 flags) : @@ -32,24 +37,45 @@ SmartTabView::~SmartTabView() void SmartTabView::MouseDown(BPoint point) { - int32 buttons; - Window()->CurrentMessage()->FindInt32("buttons", &buttons); + bool handled = false; - if (CountTabs() > 1 && point.y <= TabHeight() && buttons & B_TERTIARY_MOUSE_BUTTON) { - for (int32 i = 0; i < CountTabs(); i++) { - if (TabFrame(i).Contains(point)) { - // Select another tab - if (i > 0) - Select(i - 1); - else if (i < CountTabs()) - Select(i + 1); - BTab *tab = RemoveTab(i); - delete tab; - return; + if (CountTabs() > 1) { + int32 tabIndex = _ClickedTabIndex(point); + if (tabIndex >= 0) { + int32 buttons; + Window()->CurrentMessage()->FindInt32("buttons", &buttons); + if (buttons & B_SECONDARY_MOUSE_BUTTON) { + BMessage *message = new BMessage(kCloseTab); + message->AddInt32("index", tabIndex); + + BPopUpMenu *popUpMenu = new BPopUpMenu("tab menu"); + popUpMenu->AddItem(new BMenuItem("Close Tab", message)); + popUpMenu->SetAsyncAutoDestruct(true); + popUpMenu->SetTargetForItems(BMessenger(this)); + + // TODO: I thought I'd get a "sticky" menu with this call... + // Bug in our implementation or I just have to use the "other" + // Go() method? + popUpMenu->Go(ConvertToScreen(point), true, true, true); + + handled = true; + } else if (buttons & B_TERTIARY_MOUSE_BUTTON) { + RemoveAndDeleteTab(tabIndex); + handled = true; } - } - } else + } + } + + if (!handled) BTabView::MouseDown(point); + +} + + +void +SmartTabView::AttachedToWindow() +{ + BTabView::AttachedToWindow(); } @@ -60,6 +86,24 @@ SmartTabView::AllAttached() } +void +SmartTabView::MessageReceived(BMessage *message) +{ + switch (message->what) { + case kCloseTab: + { + int32 tabIndex = 0; + if (message->FindInt32("index", &tabIndex) == B_OK) + RemoveAndDeleteTab(tabIndex); + break; + } + default: + BTabView::MessageReceived(message); + break; + } +} + + void SmartTabView::Select(int32 index) { @@ -71,6 +115,21 @@ SmartTabView::Select(int32 index) } +void +SmartTabView::RemoveAndDeleteTab(int32 index) +{ + // Select another tab + if (index == Selection()) { + if (index > 0) + Select(index - 1); + else if (index < CountTabs()) + Select(index + 1); + } + BTab *tab = RemoveTab(index); + delete tab; +} + + void SmartTabView::AddTab(BView *target, BTab *tab) { @@ -108,3 +167,17 @@ SmartTabView::DrawTabs() } +int32 +SmartTabView::_ClickedTabIndex(const BPoint &point) +{ + if (point.y <= TabHeight()) { + for (int32 i = 0; i < CountTabs(); i++) { + if (TabFrame(i).Contains(point)) + return i; + } + } + + return -1; +} + + diff --git a/src/apps/terminal/SmartTabView.h b/src/apps/terminal/SmartTabView.h index 150ad55d29..9d2e79652c 100644 --- a/src/apps/terminal/SmartTabView.h +++ b/src/apps/terminal/SmartTabView.h @@ -10,6 +10,7 @@ #include +class BPopUpMenu; class SmartTabView : public BTabView { public: SmartTabView(BRect frame, const char *name, @@ -22,13 +23,22 @@ public: virtual void MouseDown(BPoint where); + virtual void AttachedToWindow(); virtual void AllAttached(); + + virtual void MessageReceived(BMessage *message); + virtual void Select(int32 tab); + void RemoveAndDeleteTab(int32 index); + virtual void AddTab(BView *target, BTab *tab = NULL); virtual BTab* RemoveTab(int32 index); virtual BRect DrawTabs(); + +private: + int32 _ClickedTabIndex(const BPoint &point); }; #endif // __SMARTTABVIEW_H diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 913f68f602..cd893489c3 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -116,7 +116,7 @@ TermWindow::_InitWindow(const char *command) fTabView = new SmartTabView(textFrame, "tab view"); AddChild(fTabView); - _NewTab(command); + _AddTab(command); } @@ -202,8 +202,7 @@ TermWindow::_SetupMenu() void TermWindow::MessageReceived(BMessage *message) { - int32 coding_id; - BRect r; + int32 encodingId; BFont halfFont; BFont fullFont; bool findresult; @@ -225,28 +224,24 @@ TermWindow::MessageReceived(BMessage *message) _ActiveTermView()->Clear(); break; - case MENU_SWITCH_TERM: { + case MENU_SWITCH_TERM: be_app->PostMessage(MENU_SWITCH_TERM); break; - } + case kNewTab: - _NewTab(NULL); + _AddTab(NULL); break; case kCloseView: - { // TODO: We assume that this message was sent from the current active tab. // Since the implementation of BTabView uses AddChild/RemoveChild on the // views, the current active tab is the only one who is attached, thus - // the only one which could send a message. - if (fTabView->CountTabs() > 1) - delete fTabView->RemoveTab(fTabView->Selection()); - else - PostMessage(B_QUIT_REQUESTED); + // the only one which could send a message. Change this. + _RemoveTab(fTabView->Selection()); break; - } - case MENU_NEW_TERM: { + case MENU_NEW_TERM: + { app_info info; be_app->GetAppInfo(&info); @@ -255,18 +250,18 @@ TermWindow::MessageReceived(BMessage *message) be_roster->Launch(TERM_SIGNATURE); break; } - case MENU_PREF_OPEN: { + case MENU_PREF_OPEN: if (!fPrefWindow) fPrefWindow = new PrefWindow(this); else fPrefWindow->Activate(); break; - } - case MSG_PREF_CLOSED: { + + case MSG_PREF_CLOSED: fPrefWindow = NULL; break; - } - case MENU_FIND_STRING: { + + case MENU_FIND_STRING: if (!fFindPanel) { BRect r = Frame(); r.left += 20; @@ -278,8 +273,8 @@ TermWindow::MessageReceived(BMessage *message) else fFindPanel->Activate(); break; - } - case MSG_FIND: { + + case MSG_FIND: fFindPanel->PostMessage(B_QUIT_REQUESTED); message->FindBool("findselection", &fFindSelection); if (!fFindSelection) @@ -314,8 +309,8 @@ TermWindow::MessageReceived(BMessage *message) fFindBackwardMenuItem->SetEnabled(true); fFindForwardMenuItem->SetEnabled(true); break; - } - case MENU_FIND_FORWARD: { + + case MENU_FIND_FORWARD: findresult = _ActiveTermView()->Find(fFindString, true, fMatchCase, fMatchWord); if (!findresult) { BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL, @@ -323,8 +318,8 @@ TermWindow::MessageReceived(BMessage *message) alert->Go(); } break; - } - case MENU_FIND_BACKWARD: { + + case MENU_FIND_BACKWARD: findresult = _ActiveTermView()->Find(fFindString, false, fMatchCase, fMatchWord); if (!findresult) { BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL, @@ -332,25 +327,25 @@ TermWindow::MessageReceived(BMessage *message) alert->Go(); } break; - } + case MSG_FIND_CLOSED: fFindPanel = NULL; break; - case MENU_ENCODING: { - message->FindInt32 ("op", &coding_id); - _ActiveTermView()->SetEncoding(coding_id); + case MENU_ENCODING: + if (message->FindInt32("op", &encodingId) == B_OK) + _ActiveTermView()->SetEncoding(encodingId); break; - } // Message from Preference panel. case MSG_ROWS_CHANGED: - case MSG_COLS_CHANGED: { - r = _ActiveTermView()->SetTermSize (PrefHandler::Default()->getInt32 (PREF_ROWS), + case MSG_COLS_CHANGED: + { + BRect rect = _ActiveTermView()->SetTermSize(PrefHandler::Default()->getInt32 (PREF_ROWS), PrefHandler::Default()->getInt32 (PREF_COLS), 0); - ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + kViewOffset * 2, - r.Height()+fMenubar->Bounds().Height() + kViewOffset *2); + ResizeTo (rect.Width()+ B_V_SCROLL_BAR_WIDTH + kViewOffset * 2, + rect.Height()+fMenubar->Bounds().Height() + kViewOffset *2); BPath path; if (PrefHandler::GetDefaultPath(path) == B_OK) @@ -360,7 +355,8 @@ TermWindow::MessageReceived(BMessage *message) case MSG_HALF_FONT_CHANGED: case MSG_FULL_FONT_CHANGED: case MSG_HALF_SIZE_CHANGED: - case MSG_FULL_SIZE_CHANGED: { + case MSG_FULL_SIZE_CHANGED: + { halfFont.SetFamilyAndStyle (PrefHandler::Default()->getString(PREF_HALF_FONT_FAMILY),NULL); halfFont.SetSize (PrefHandler::Default()->getFloat(PREF_HALF_FONT_SIZE)); @@ -371,52 +367,51 @@ TermWindow::MessageReceived(BMessage *message) fullFont.SetSpacing (B_FIXED_SPACING); _ActiveTermView()->SetTermFont (&halfFont, &fullFont); - r = _ActiveTermView()->SetTermSize (0, 0, 0); + BRect rect = _ActiveTermView()->SetTermSize (0, 0, 0); int width, height; - - _ActiveTermView()->GetFontSize (&width, &height); + _ActiveTermView()->GetFontSize(&width, &height); SetSizeLimits (MIN_COLS * width, MAX_COLS * width, MIN_COLS * height, MAX_COLS * height); - ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + kViewOffset * 2, - r.Height()+fMenubar->Bounds().Height() + kViewOffset * 2); + ResizeTo(rect.Width()+ B_V_SCROLL_BAR_WIDTH + kViewOffset * 2, + rect.Height()+fMenubar->Bounds().Height() + kViewOffset * 2); _ActiveTermView()->Invalidate(); break; } - case EIGHTYTWENTYFOUR: { + case EIGHTYTWENTYFOUR: PrefHandler::Default()->setString(PREF_COLS, "80"); PrefHandler::Default()->setString(PREF_ROWS, "24"); PostMessage (MSG_COLS_CHANGED); break; - } - case EIGHTYTWENTYFIVE: { + + case EIGHTYTWENTYFIVE: PrefHandler::Default()->setString(PREF_COLS, "80"); PrefHandler::Default()->setString(PREF_ROWS, "25"); PostMessage (MSG_COLS_CHANGED); break; - } - case EIGHTYFORTY: { + + case EIGHTYFORTY: PrefHandler::Default()->setString(PREF_COLS, "80"); PrefHandler::Default()->setString(PREF_ROWS, "40"); PostMessage (MSG_COLS_CHANGED); break; - } - case ONETHREETWOTWENTYFOUR: { + + case ONETHREETWOTWENTYFOUR: PrefHandler::Default()->setString(PREF_COLS, "132"); PrefHandler::Default()->setString(PREF_ROWS, "24"); PostMessage (MSG_COLS_CHANGED); break; - } - case ONETHREETWOTWENTYFIVE: { + + case ONETHREETWOTWENTYFIVE: PrefHandler::Default()->setString(PREF_COLS, "132"); PrefHandler::Default()->setString(PREF_ROWS, "25"); PostMessage (MSG_COLS_CHANGED); break; - } - case FULLSCREEN: { + + case FULLSCREEN: if (!fSavedFrame.IsValid()) { // go fullscreen float mbHeight = fMenubar->Bounds().Height() + 1; fSavedFrame = Frame(); @@ -440,39 +435,38 @@ TermWindow::MessageReceived(BMessage *message) fSavedFrame = BRect(0,0,-1,-1); } break; - } - case MSG_FONT_CHANGED: { + + case MSG_FONT_CHANGED: PostMessage(MSG_HALF_FONT_CHANGED); break; - } - case MSG_COLOR_CHANGED: { + + case MSG_COLOR_CHANGED: _SetTermColors(); _ActiveTermView()->Invalidate(); break; - } - case SAVE_AS_DEFAULT: { + + case SAVE_AS_DEFAULT: + { BPath path; if (PrefHandler::GetDefaultPath(path) == B_OK) PrefHandler::Default()->SaveAsText(path.Path(), PREFFILE_MIMETYPE); break; } - case MENU_PAGE_SETUP: { + case MENU_PAGE_SETUP: _DoPageSetup(); break; - } - case MENU_PRINT: { + + case MENU_PRINT: _DoPrint(); break; - } - case B_ABOUT_REQUESTED: { + case B_ABOUT_REQUESTED: be_app->PostMessage(B_ABOUT_REQUESTED); break; - } - default: { + + default: BWindow::MessageReceived(message); break; - } } } @@ -567,7 +561,7 @@ TermWindow::_DoPrint() void -TermWindow::_NewTab(const char *command) +TermWindow::_AddTab(const char *command) { // Setup font. @@ -628,6 +622,16 @@ TermWindow::_NewTab(const char *command) } +void +TermWindow::_RemoveTab(int32 index) +{ + if (fTabView->CountTabs() > 1) + delete fTabView->RemoveTab(fTabView->Selection()); + else + PostMessage(B_QUIT_REQUESTED); +} + + TermView * TermWindow::_ActiveTermView() { diff --git a/src/apps/terminal/TermWindow.h b/src/apps/terminal/TermWindow.h index eb14814881..5cec4dec08 100644 --- a/src/apps/terminal/TermWindow.h +++ b/src/apps/terminal/TermWindow.h @@ -59,7 +59,8 @@ private: void _SetupMenu(); status_t _DoPageSetup(); void _DoPrint(); - void _NewTab(const char *command); + void _AddTab(const char *command); + void _RemoveTab(int32 index); TermView* _ActiveTermView(); SmartTabView *fTabView;