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
This commit is contained in:
parent
7f8d0be06f
commit
d6f28abebe
@ -8,11 +8,16 @@
|
||||
|
||||
#include "SmartTabView.h"
|
||||
|
||||
#include <MenuItem.h>
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <TabView.h>
|
||||
|
||||
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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user