Merge pull request #3 from KapiX/tabview

Use native BTabView with slight modifications.
This commit is contained in:
Jim Saxton
2017-09-17 21:13:47 -07:00
committed by GitHub
7 changed files with 63 additions and 825 deletions

View File

@@ -599,7 +599,7 @@ SUBMENU SET MenuHead$, MenuItem$, SubMenuItem$, Option$, View$
-= T =-
TABVIEW x1,y1 TO x2,y2, ID$, Option$, View$
Option$ = "top, bottom" where to place the tabs.
Option$ = "top, bottom, left, right" where to place the tabs.
TABVIEW ADD TabView$, TabName$
For each tab, a new view is created; you can add widgets or draw on these views as ususal.
The ids for the views ist TabView$+"1" for the first, TabView$+"2" for the second view, etc.

View File

@@ -14,7 +14,6 @@
##
## Haiku stuff
##
HAIKUTAB = YabTabView.o
HAIKUOPT = -DHAIKU -DLIBRARY_PATH=\"`finddir B_USER_SETTINGS_DIRECTORY`/yab\"
#
@@ -99,7 +98,7 @@ BISONFLAGS = -d -l -t -v
YAB_OBJECTS = YabInterface.o YabWindow.o YabView.o YabBitmapView.o YabText.o YabFilePanel.o YabFilePanelLooper.o YabList.o \
function.o io.o graphic.o symbol.o bison.o \
$(COLUMN) column/YabColumnType.o column/ColorTools.o \
YabStackView.o SplitPane.o URLView.o YabControlLook.o $(HAIKUTAB) Spinner.o $(TABLIB) CalendarControl.o
YabStackView.o SplitPane.o URLView.o YabTabView.o Spinner.o $(TABLIB) CalendarControl.o
##
## Compile and link
@@ -162,12 +161,10 @@ column/ColorTools.o: column/ColorTools.cpp column/ColorTools.h
$(GPP) $(GPP_OPT) -c column/ColorTools.cpp -o column/ColorTools.o
column/YabColumnType.o: column/YabColumnType.cpp column/YabColumnType.h
$(GPP) $(GPP_OPT) -c column/YabColumnType.cpp -o column/YabColumnType.o
$(HAIKUTAB): YabTabView.cpp YabTabView.h
YabTabView.o: YabTabView.cpp YabTabView.h
$(GPP) $(GPP_OPT) -c YabTabView.cpp -o YabTabView.o
CalendarControl.o: CalendarControl.cpp CalendarControl.h DateTextView.cpp MonthWindow.cpp MonthView.cpp MouseSenseStringView.cpp
$(GPP) $(GPP_OPT) -c CalendarControl.cpp -o CalendarControl.o
YabControlLook.o: YabControlLook.h YabControlLook.cpp
$(GPP) $(GPP_OPT) -c YabControlLook.cpp -o YabControlLook.o
clean:
rm -f core *.o column/*.o flex.* bison.* yab yabasic.output $(YABLIBRARY)

View File

@@ -1,257 +0,0 @@
#include <GradientLinear.h>
#include <Region.h>
#include "YabControlLook.h"
YabControlLook::YabControlLook()
{ }
YabControlLook::~YabControlLook()
{ }
void YabControlLook::DrawActiveTabBottom(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders)
{
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
rgb_color edgeShadowColor;
rgb_color edgeLightColor;
rgb_color frameShadowColor;
rgb_color frameLightColor;
rgb_color bevelShadowColor;
rgb_color bevelLightColor;
BGradientLinear fillGradient;
fillGradient.SetStart(rect.LeftBottom() + BPoint(3, -3));
fillGradient.SetEnd(rect.LeftTop() + BPoint(3, 3));
if (flags & B_DISABLED) {
edgeShadowColor = base;
edgeLightColor = base;
frameShadowColor = tint_color(base, 1.30);
frameLightColor = tint_color(base, 1.25);
bevelShadowColor = tint_color(base, 1.07);
bevelLightColor = tint_color(base, 0.8);
fillGradient.AddColor(tint_color(base, 0.85), 0);
fillGradient.AddColor(base, 255);
} else {
edgeShadowColor = tint_color(base, 1.03);
edgeLightColor = tint_color(base, 0.80);
frameShadowColor = tint_color(base, 1.30);
frameLightColor = tint_color(base, 1.30);
bevelShadowColor = tint_color(base, 1.07);
bevelLightColor = tint_color(base, 0.6);
fillGradient.AddColor(tint_color(base, 0.75), 0);
fillGradient.AddColor(tint_color(base, 1.03), 255);
}
static const float kRoundCornerRadius = 4;
// left/top corner
BRect cornerRect(rect);
cornerRect.right = cornerRect.left + kRoundCornerRadius;
cornerRect.top = cornerRect.bottom - kRoundCornerRadius;
BRegion clipping(rect);
clipping.Exclude(cornerRect);
_DrawRoundCornerLeftBottom(view, cornerRect, updateRect, base, edgeShadowColor,
frameLightColor, bevelLightColor, fillGradient);
// left/top corner
cornerRect.right = rect.right;
cornerRect.left = cornerRect.right - kRoundCornerRadius;
clipping.Exclude(cornerRect);
_DrawRoundCornerRightBottom(view, cornerRect, updateRect, base, edgeShadowColor,
edgeLightColor, frameLightColor, frameShadowColor, bevelLightColor,
bevelShadowColor, fillGradient);
// rest of frame and fill
view->ConstrainClippingRegion(&clipping);
_DrawFrame(view, rect, edgeShadowColor, edgeLightColor, edgeLightColor,
edgeShadowColor,
borders & (B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER));
if ((borders & B_LEFT_BORDER) == 0)
rect.left++;
if ((borders & B_RIGHT_BORDER) == 0)
rect.right--;
_DrawFrame(view, rect, frameLightColor, frameShadowColor, frameShadowColor,
frameLightColor, B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER);
_DrawFrame(view, rect, bevelLightColor, bevelShadowColor, bevelShadowColor,
bevelLightColor);
view->FillRect(rect, fillGradient);
view->SetHighColor(216,216,216);
view->StrokeLine(BPoint(rect.left, rect.top), BPoint(rect.right, rect.top));
view->ConstrainClippingRegion(NULL);
}
void YabControlLook::DrawInactiveTabBottom(BView* view, BRect& rect,const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders)
{
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
rgb_color edgeShadowColor;
rgb_color edgeLightColor;
rgb_color frameShadowColor;
rgb_color frameLightColor;
rgb_color bevelShadowColor;
rgb_color bevelLightColor;
BGradientLinear fillGradient;
fillGradient.SetStart(rect.LeftBottom() + BPoint(3, -3));
fillGradient.SetEnd(rect.LeftTop() + BPoint(3, 3));
if (flags & B_DISABLED) {
edgeShadowColor = base;
edgeLightColor = base;
frameShadowColor = tint_color(base, 1.30);
frameLightColor = tint_color(base, 1.25);
bevelShadowColor = tint_color(base, 1.07);
bevelLightColor = tint_color(base, 0.8);
fillGradient.AddColor(tint_color(base, 0.85), 0);
fillGradient.AddColor(base, 255);
} else {
edgeShadowColor = tint_color(base, 1.03);
edgeLightColor = tint_color(base, 0.80);
frameShadowColor = tint_color(base, 1.30);
frameLightColor = tint_color(base, 1.30);
bevelShadowColor = tint_color(base, 1.17);
bevelLightColor = tint_color(base, 1.10);
fillGradient.AddColor(tint_color(base, 1.12), 0);
fillGradient.AddColor(tint_color(base, 1.08), 255);
}
// active tabs stand out at the top, but this is an inactive tab
view->SetHighColor(base);
view->FillRect(BRect(rect.left, rect.bottom - 4, rect.right, rect.bottom));
rect.bottom -= 4;
// frame and fill
_DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor,
edgeLightColor,
borders & (B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER));
_DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor,
frameShadowColor,
borders & (B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER));
if (rect.IsValid()) {
_DrawFrame(view, rect, bevelShadowColor, bevelShadowColor,
bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders);
} else {
if ((B_LEFT_BORDER & ~borders) != 0)
rect.left++;
}
view->FillRect(rect, fillGradient);
}
void
YabControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& rect,
const BRect& updateRect, const rgb_color& base, const rgb_color& edgeColor,
const rgb_color& frameColor, const rgb_color& bevelColor,
const BGradientLinear& fillGradient)
{
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
BRegion clipping(rect);
view->ConstrainClippingRegion(&clipping);
// background
view->SetHighColor(base);
view->FillRect(rect);
// outer edge
BRect ellipseRect(rect);
ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
view->SetHighColor(edgeColor);
view->FillEllipse(ellipseRect);
// frame
ellipseRect.InsetBy(1, 1);
view->SetHighColor(frameColor);
view->FillEllipse(ellipseRect);
// bevel
ellipseRect.InsetBy(1, 1);
view->SetHighColor(bevelColor);
view->FillEllipse(ellipseRect);
// fill
ellipseRect.InsetBy(1, 1);
view->FillEllipse(ellipseRect, fillGradient);
view->ConstrainClippingRegion(NULL);
}
void
YabControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& rect,
const BRect& updateRect, const rgb_color& base,
const rgb_color& edgeTopColor, const rgb_color& edgeRightColor,
const rgb_color& frameTopColor, const rgb_color& frameRightColor,
const rgb_color& bevelTopColor, const rgb_color& bevelRightColor,
const BGradientLinear& fillGradient)
{
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
BRegion clipping(rect);
view->ConstrainClippingRegion(&clipping);
// background
view->SetHighColor(base);
view->FillRect(rect);
// outer edge
BRect ellipseRect(rect);
ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
BGradientLinear gradient;
gradient.AddColor(edgeTopColor, 0);
gradient.AddColor(edgeRightColor, 255);
gradient.SetStart(rect.LeftTop());
gradient.SetEnd(rect.RightBottom());
view->FillEllipse(ellipseRect, gradient);
// frame
ellipseRect.InsetBy(1, 1);
rect.right--;
rect.top++;
if (frameTopColor == frameRightColor) {
view->SetHighColor(frameTopColor);
view->FillEllipse(ellipseRect);
} else {
gradient.SetColor(0, frameTopColor);
gradient.SetColor(1, frameRightColor);
gradient.SetStart(rect.LeftTop());
gradient.SetEnd(rect.RightBottom());
view->FillEllipse(ellipseRect, gradient);
}
// bevel
ellipseRect.InsetBy(1, 1);
rect.right--;
rect.top++;
gradient.SetColor(0, bevelTopColor);
gradient.SetColor(1, bevelRightColor);
gradient.SetStart(rect.LeftTop());
gradient.SetEnd(rect.RightBottom());
view->FillEllipse(ellipseRect, gradient);
// fill
ellipseRect.InsetBy(1, 1);
view->FillEllipse(ellipseRect, fillGradient);
view->ConstrainClippingRegion(NULL);
}

View File

@@ -1,33 +0,0 @@
#ifndef YABCONTROLLOOK
#define YABCONTROLLOOK
#include <ControlLook.h>
class YabControlLook : public BControlLook
{
public:
YabControlLook();
~YabControlLook();
virtual void DrawActiveTabBottom(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, uint32 borders = BControlLook::B_ALL_BORDERS);
virtual void DrawInactiveTabBottom(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, uint32 borders = BControlLook::B_ALL_BORDERS);
void _DrawRoundCornerLeftBottom(BView* view,
BRect& rect, const BRect& updateRect,
const rgb_color& base,
const rgb_color& edgeColor,
const rgb_color& frameColor,
const rgb_color& bevelColor,
const BGradientLinear& fillGradient);
void _DrawRoundCornerRightBottom(BView* view,
BRect& rect, const BRect& updateRect,
const rgb_color& base,
const rgb_color& edgeTopColor,
const rgb_color& edgeRightColor,
const rgb_color& frameTopColor,
const rgb_color& frameRightColor,
const rgb_color& bevelTopColor,
const rgb_color& bevelRightColor,
const BGradientLinear& fillGradient);
};
#endif

View File

@@ -390,7 +390,7 @@ int YabInterface::CloseWindow(const char* view)
{
for(int i = 0; i<((YabTabView*)child)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}
@@ -407,7 +407,7 @@ int YabInterface::CloseWindow(const char* view)
{
for(int i = 0; i<((YabTabView*)subchild)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}
@@ -601,12 +601,16 @@ void YabInterface::BoxViewSet(const char* id, const char* option, const char* va
}
void YabInterface::Tab(BRect frame, const char* id, const char* mode, const char* view)
{
tab_orientation side;
BTabView::tab_side side;
BString option(mode);
if(option.IFindFirst("top")!=B_ERROR)
side = B_TAB_TOP;
else if(option.IFindFirst("bottom")!=B_ERROR)
side = B_TAB_BOTTOM;
if(option.IFindFirst("top") != B_ERROR)
side = BTabView::kTopSide;
else if(option.IFindFirst("bottom") != B_ERROR)
side = BTabView::kBottomSide;
else if(option.IFindFirst("left") != B_ERROR)
side = BTabView::kLeftSide;
else if(option.IFindFirst("right") != B_ERROR)
side = BTabView::kRightSide;
else ErrorGen("Invalid Option");
YabView *myView = cast_as((BView*)viewList->GetView(view), YabView);
@@ -626,7 +630,7 @@ void YabInterface::Tab(BRect frame, const char* id, const char* mode, const char
myTabView->SetFlags(B_WILL_DRAW|B_FULL_UPDATE_ON_RESIZE|B_NAVIGABLE|B_NAVIGABLE_JUMP);
myTabView->SetOrientation(side);
myTabView->SetTabSide(side);
myTabView->SetTabWidth(B_WIDTH_FROM_LABEL);
myView->AddChild(myTabView);
@@ -3378,7 +3382,7 @@ void YabInterface::WindowClear(const char* window)
{
for(int i = 0; i<((YabTabView*)child)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}
@@ -3393,7 +3397,7 @@ void YabInterface::WindowClear(const char* window)
{
for(int i = 0; i<((YabTabView*)subchild)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}
@@ -3458,7 +3462,7 @@ void YabInterface::RemoveView(BView *myView)
{
for(int i = 0; i<((YabTabView*)child)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)child)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}
@@ -3473,7 +3477,7 @@ void YabInterface::RemoveView(BView *myView)
{
for(int i = 0; i<((YabTabView*)subchild)->CountTabs(); i++)
{
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i);
YabView *t = (YabView*)((YabTabView*)subchild)->TabAt(i)->View();
RemoveView(t);
viewList->DelView(t->Name());
}

View File

@@ -21,10 +21,11 @@
//
// File Name: YabTabView.cpp
// Author: Marc Flerackers (mflerackers@androme.be)
// Modified by Jan Bungeroth (jan@be-logos.org)
// Modified by Jan Bungeroth (jan@be-logos.org)
// Modified by Kacper Kasper (kacperkasper@gmail.com)
// Description: YabTabView provides the framework for containing and
// managing groups of BView objects. Modified for *sane*
// view handling (they stay connected to the window).
// view handling (they stay connected to the window).
//------------------------------------------------------------------------------
#include <List.h>
@@ -32,72 +33,24 @@
#include <String.h>
#include <View.h>
#include <stdio.h>
#include <ControlLook.h>
#include "YabControlLook.h"
#include "YabTabView.h"
#define X_OFFSET 0.0f
YabTabView::YabTabView(BRect frame, const char* name, button_width width, uint32 resizingMode, uint32 flags)
: BView(frame, name, resizingMode, flags)
: BTabView(frame, name, width, resizingMode, flags)
{
fTabList = new BList;
fTabNames = new BList;
fTabWidthSetting = width;
fSelection = 0;
fFocus = -1;
fTabOffset = 0.0f;
rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR);
SetViewColor(color);
SetLowColor(color);
font_height fh;
GetFontHeight(&fh);
fTabHeight = fh.ascent + fh.descent + fh.leading + 8.0f;
/*
if (layouted) {
BGroupLayout* layout = new(std::nothrow) BGroupLayout(B_HORIZONTAL);
if (layout) {
layout->SetInsets(3.0, 3.0 + TabHeight() - 1, 3.0, 3.0);
SetLayout(layout);
}
fContainerView = new BView("view container", B_WILL_DRAW);
fContainerView->SetLayout(new(std::nothrow) BCardLayout());
} else {
*/
BRect bounds = Bounds();
bounds.top += TabHeight();
bounds.InsetBy(3.0f, 3.0f);
fContainerView = new BView(bounds, "view container", B_FOLLOW_ALL,
B_WILL_DRAW);
// }
fContainerView->SetViewColor(color);
fContainerView->SetLowColor(color);
AddChild(fContainerView);
FocusChanged = 1;
OldTabView = 1;
fTabOrientation = B_TAB_TOP;
FocusChanged = 1;
OldTabView = 1;
}
YabTabView::~YabTabView()
{
for(int i=0; i<CountTabs(); i++)
{
delete TabAt(i);
delete (BString*)fTabNames->RemoveItem(i);
}
delete fTabList;
delete fTabNames;
}
@@ -105,129 +58,59 @@ void YabTabView::AddTab(BView *tabView, const char* label)
{
if(tabView)
{
tabView->Hide();
fContainerView->AddChild(tabView);
Invalidate();
if(CountTabs() == 0) tabView->Show();
BTab *tab = new BTab();
BTabView::AddTab(tabView, tab);
tab->SetLabel(label);
// HACK
// YAB assumes all views have a window, but that's not true for tabs
if(CountTabs() > 1)
AddChild(tabView);
tabView->Hide();
fTabList->AddItem(tabView);
fTabNames->AddItem(new BString(label));
}
}
BView* YabTabView::RemoveTab(int32 index)
{
if(index < 0 || index >= CountTabs())
return NULL;
BView *tab = (BView*)fTabList->RemoveItem(index);
delete (BString*)fTabNames->RemoveItem(index);
if (index <= fSelection && fSelection != 0)
fSelection--;
Select(fSelection);
if (fFocus == CountTabs() - 1)
SetFocusTab(fFocus, false);
else
SetFocusTab(fFocus, true);
return tab;
}
int32 YabTabView::CountTabs() const
{
return fTabList->CountItems();
}
int32 YabTabView::Selection() const
{
return fSelection;
}
void YabTabView::Select(int32 index)
{
if (index < 0 || index >= CountTabs())
index = Selection();
if (index < 0 || index >= CountTabs())
index = Selection();
BView *tab = TabAt(Selection());
if (tab)
BTab* tab = TabAt(index);
if (tab)
{
Invalidate();
tab->Hide();
FocusChanged = index+1;
}
tab = TabAt(index);
if (tab)
{
if (index != 0 && !Bounds().Contains(TabFrame(index))){
if (!Bounds().Contains(TabFrame(index).LeftTop()))
fTabOffset += TabFrame(index).left - Bounds().left - 20.0f;
else
fTabOffset += TabFrame(index).right - Bounds().right + 20.0f;
}
Invalidate();
tab->Show();
fSelection = index;
FocusChanged = index+1;
}
// HACK
// YAB assumes all views have a window, but that's not true for tabs
int32 prevSelected = Selection();
RemoveChild(tab->View());
tab->View()->Show();
BTabView::Select(index);
if(prevSelected > -1) {
BTab* prevTab = TabAt(prevSelected);
prevTab->View()->Hide();
AddChild(prevTab->View());
}
}
void YabTabView::MakeFocus(bool focused)
{
BView::MakeFocus(focused);
BView::MakeFocus(focused);
SetFocusTab(Selection(), focused);
}
int32 YabTabView::FocusTab() const
{
return fFocus;
}
SetFocusTab(Selection(), focused);
}
void YabTabView::SetFocusTab(int32 tab, bool focused)
{
if (tab >= CountTabs())
tab = 0;
if (tab < 0)
tab = CountTabs() - 1;
if (focused) {
if (tab == fFocus)
return;
if (fFocus != -1){
if (TabAt (fFocus) != NULL)
TabAt(fFocus)->MakeFocus(false);
Invalidate(TabFrame(fFocus));
}
if (TabAt(tab) != NULL){
TabAt(tab)->MakeFocus(true);
Invalidate(TabFrame(tab));
fFocus = tab;
}
} else if (fFocus != -1) {
TabAt(fFocus)->MakeFocus(false);
Invalidate(TabFrame(fFocus));
fFocus = -1;
}
FocusChanged = (FocusTab() != tab) ? 1 : 0;
BTabView::SetFocusTab(tab, focused);
}
BView* YabTabView::TabAt(int32 index)
{
if(index < 0 || index >= CountTabs())
return NULL;
return (BView*)fTabList->ItemAt(index);
}
const char* YabTabView::GetTabName(int32 index) const
{
if(index < 0 || index >= CountTabs())
@@ -235,309 +118,3 @@ const char* YabTabView::GetTabName(int32 index) const
return ((BString*)fTabNames->ItemAt(index))->String();
}
void YabTabView::KeyDown(const char *bytes, int32 numBytes)
{
if (IsHidden())
return;
switch (bytes[0]) {
case B_DOWN_ARROW:
case B_LEFT_ARROW: {
int32 focus = fFocus - 1;
if (focus < 0)
focus = CountTabs() - 1;
SetFocusTab(focus, true);
FocusChanged = 1;
break;
}
case B_UP_ARROW:
case B_RIGHT_ARROW: {
int32 focus = fFocus + 1;
if (focus >= CountTabs())
focus = 0;
SetFocusTab(focus, true);
FocusChanged = 1;
break;
}
case B_RETURN:
case B_SPACE:
Select(FocusTab());
break;
default:
BView::KeyDown(bytes, numBytes);
}
}
void YabTabView::MouseDown(BPoint point)
{
if (fTabOrientation == B_TAB_TOP && point.y > fTabHeight)
return;
if (fTabOrientation == B_TAB_BOTTOM && point.y < Bounds().bottom-fTabHeight)
return;
for (int32 i = 0; i < CountTabs(); i++) {
if (TabFrame(i).Contains(point) && i != Selection()) {
Select(i);
fFocus = -1;
return;
}
}
BView::MouseDown(point);
}
BRect YabTabView::TabFrame(int32 tab_index) const
{
float width = 100.0;
float height = fTabHeight;;
BRect tabFrame(Bounds());
switch (fTabWidthSetting) {
case B_WIDTH_FROM_LABEL:
{
float x = 0.0;
for (int32 i = 0; i < tab_index; i++){
x += StringWidth(GetTabName(i)) + 20.0;
}
if(fTabOrientation == B_TAB_TOP)
tabFrame.Set(x, 0.0, x + StringWidth(GetTabName(tab_index)) + 20.0, height);
else
tabFrame.Set(x, tabFrame.bottom - height, x + StringWidth(GetTabName(tab_index)) + 20.0, tabFrame.bottom);
return tabFrame;
}
case B_WIDTH_FROM_WIDEST:
width = 0.0;
for (int32 i = 0; i < CountTabs(); i++) {
float tabWidth = StringWidth(GetTabName(i)) + 20.0;
if (tabWidth > width)
width = tabWidth;
}
// fall through
case B_WIDTH_AS_USUAL:
default:
if(fTabOrientation == B_TAB_TOP)
tabFrame.Set(tab_index * width, 0.0, tab_index * width + width, height);
else
tabFrame.Set(tab_index * width, tabFrame.bottom - height, tab_index * width + width, tabFrame.bottom);
return tabFrame;
}
}
void YabTabView::SetTabWidth(button_width width)
{
fTabWidthSetting = width;
Invalidate();
}
button_width YabTabView::TabWidth() const
{
return fTabWidthSetting;
}
void YabTabView::SetTabHeight(float height)
{
if (fTabHeight == height)
return;
fContainerView->MoveBy(0.0f, height - fTabHeight);
fContainerView->ResizeBy(0.0f, height - fTabHeight);
fTabHeight = height;
Invalidate();
}
float YabTabView::TabHeight()
{
return fTabHeight;
}
BView *YabTabView::ContainerView()
{
return fContainerView;
}
void YabTabView::Draw(BRect updateRect)
{
// DrawBox(DrawTabs());
// SetHighColor(223,223,223);
// StrokeLine(BPoint(Bounds().left, Bounds().bottom-TabHeight()-2), BPoint(Bounds().right, Bounds().bottom-TabHeight()-2));
DrawBox(TabFrame(fSelection));
DrawTabs();
if (IsFocus() && fFocus != -1)
{
DrawFocusMark(TabFrame(fFocus), fFocus);
// Invalidate(TabFrame(fFocus));
}
}
BRect YabTabView::DrawTabs()
{
float left = 0;
for (int32 i = 0; i < CountTabs(); i++) {
BRect tabFrame = TabFrame(i);
DrawTab(tabFrame, i, i == fSelection ? B_TAB_FRONT : (i == 0) ? B_TAB_FIRST : B_TAB_ANY, i + 1 != fSelection);
left = tabFrame.right;
}
BRect frame(Bounds());
if (left < frame.right) {
frame.left = left;
if(fTabOrientation == B_TAB_TOP)
frame.bottom = fTabHeight;
else
frame.top = frame.bottom - fTabHeight;
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
uint32 borders = BControlLook::B_TOP_BORDER
| BControlLook::B_BOTTOM_BORDER | BControlLook::B_RIGHT_BORDER;
if (left == 0)
borders |= BControlLook::B_LEFT_BORDER;
if(fTabOrientation == B_TAB_TOP)
be_control_look->DrawInactiveTab(this, frame, frame, base, 0, borders);
else
fYabControlLook.DrawInactiveTabBottom(this, frame, frame, base, 0, borders);
}
if (fSelection < CountTabs())
return TabFrame(fSelection);
return BRect();
}
void YabTabView::DrawLabel(int32 current, BRect frame)
{
BString label = GetTabName(current);
if (label == NULL)
return;
float frameWidth = frame.Width();
float width = StringWidth(label.String());
font_height fh;
if (width > frameWidth) {
BFont font;
GetFont(&font);
font.TruncateString(&label, B_TRUNCATE_END, frameWidth);
width = frameWidth;
font.GetHeight(&fh);
} else {
GetFontHeight(&fh);
}
SetDrawingMode(B_OP_OVER);
SetHighColor(ui_color(B_CONTROL_TEXT_COLOR));
DrawString(label.String(),
BPoint((frame.left + frame.right - width) / 2.0,
(frame.top + frame.bottom - fh.ascent - fh.descent) / 2.0
+ fh.ascent));
}
void YabTabView::DrawTab(BRect frame, int32 current, tab_position position, bool full)
{
BView *owner = this;
rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR);
// uint32 borders = BControlLook::B_RIGHT_BORDER
// | BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER;
// if (frame.left == owner->Bounds().left)
// borders |= BControlLook::B_LEFT_BORDER;
// be_control_look->DrawButtonFrame(owner, frame, frame,
// no_tint, 0, borders);
// if (position == B_TAB_FRONT)
// no_tint = tint_color(no_tint, B_DARKEN_2_TINT);
// be_control_look->DrawButtonBackground(owner, frame, frame, no_tint);
uint32 borders = BControlLook::B_TOP_BORDER
| BControlLook::B_BOTTOM_BORDER;
if (frame.left == owner->Bounds().left)
borders |= BControlLook::B_LEFT_BORDER;
if (frame.right == owner->Bounds().right)
borders |= BControlLook::B_RIGHT_BORDER;
if (position == B_TAB_FRONT) {
if(fTabOrientation == B_TAB_TOP)
{
frame.bottom += 1;
be_control_look->DrawActiveTab(owner, frame, frame, no_tint, 0, borders);
}
else
{
frame.top -= 1;
fYabControlLook.DrawActiveTabBottom(owner, frame, frame, no_tint, 0, borders);
}
} else {
if(fTabOrientation == B_TAB_TOP)
be_control_look->DrawInactiveTab(owner, frame, frame, no_tint, 0, borders);
else
fYabControlLook.DrawInactiveTabBottom(owner, frame, frame, no_tint, 0, borders);
}
DrawLabel(current, frame);
return;
}
void YabTabView::DrawFocusMark(BRect frame, int32 current)
{
float width = StringWidth(GetTabName(current));
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
float offset = (fSelection == current) ? 3 : 2;
StrokeLine(BPoint((frame.left + frame.right - width) / 2.0,
frame.bottom - offset),
BPoint((frame.left + frame.right + width) / 2.0,
frame.bottom - offset));
}
void YabTabView::DrawBox(BRect selTabRect)
{
BRect rect(Bounds());
if(fTabOrientation == B_TAB_TOP)
rect.top = selTabRect.bottom;
else
rect.bottom -= selTabRect.Height();
// BRegion clipping(Bounds());
// selTabRect.left += 2;
// selTabRect.right -= 2;
// clipping.Exclude(selTabRect);
// ConstrainClippingRegion(&clipping);
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
be_control_look->DrawGroupFrame(this, rect, rect, base);
// ConstrainClippingRegion(NULL);
}
void YabTabView::SetOrientation(tab_orientation side)
{
if(fTabOrientation != side)
if(side == B_TAB_BOTTOM)
fContainerView->MoveTo(3.0, 3.0);
else
fContainerView->MoveTo(3.0, TabHeight());
fTabOrientation = side;
}
tab_orientation YabTabView::Orientation()
{
return fTabOrientation;
}

View File

@@ -21,9 +21,10 @@
//
// File Name: YabTabView.h
// Author: Marc Flerackers (mflerackers@androme.be)
// Jan Bungeroth (jan@be-logos.org)
// Jan Bungeroth (jan@be-logos.org)
// Kacper Kasper (kacperkasper@gmail.com)
// Description: YabTabView provides the framework for containing and
// managing groups of BView objects.
// managing groups of BView objects.
//------------------------------------------------------------------------------
#ifndef YABTAB_VIEW_H
@@ -31,23 +32,10 @@
// Standard Includes -----------------------------------------------------------
#include <View.h>
#include "YabControlLook.h"
// Local Defines ---------------------------------------------------------------
enum tab_position {
B_TAB_FIRST = 999,
B_TAB_FRONT,
B_TAB_ANY
};
enum tab_orientation {
B_TAB_TOP = 0,
B_TAB_BOTTOM
};
#include <TabView.h>
// YabTabView class ------------------------------------------------------------------
class YabTabView : public BView
class YabTabView : public BTabView
{
public:
YabTabView(BRect frame, const char *name,
@@ -58,57 +46,19 @@ public:
B_FRAME_EVENTS | B_NAVIGABLE);
~YabTabView();
virtual void KeyDown(const char *bytes, int32 numBytes);
virtual void MouseDown(BPoint point);
virtual void Select(int32 tab);
int32 Selection() const;
virtual void MakeFocus(bool focused = true);
virtual void SetFocusTab(int32 tab, bool focused);
int32 FocusTab() const;
virtual void Draw(BRect updateRect);
virtual BRect DrawTabs();
virtual void DrawBox(BRect selTabRect);
virtual BRect TabFrame(int32 tab_index) const;
virtual void DrawFocusMark(BRect frame, int32 current);
virtual void DrawLabel(int32 current, BRect frame);
virtual void DrawTab(BRect frame, int32 current, tab_position position, bool full);
virtual const char* GetTabName(int32 index) const;
virtual void AddTab(BView *target, const char* tabname);
virtual BView *RemoveTab(int32 tabIndex);
virtual BView *TabAt ( int32 tab_index );
virtual void SetTabWidth(button_width width);
button_width TabWidth() const;
virtual void Select(int32 index);
virtual void MakeFocus(bool focused = true);
virtual void SetFocusTab(int32 tab, bool focused);
void SetOrientation(tab_orientation side);
tab_orientation Orientation();
virtual void SetTabHeight(float height);
float TabHeight();
BView *ContainerView();
int32 CountTabs() const;
int32 FocusChanged;
int32 OldTabView;
private:
BList *fTabList;
BList *fTabNames;
BView *fContainerView;
button_width fTabWidthSetting;
float fTabWidth;
float fTabHeight;
int32 fSelection;
int32 fInitialSelection;
int32 fFocus;
float fTabOffset;
tab_orientation fTabOrientation;
YabControlLook fYabControlLook;
};
//------------------------------------------------------------------------------