Switch the list to a BColumnListView-based one.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39476 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,32 +9,190 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ListView.h>
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
|
#include <ColumnTypes.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
|
#include <MimeType.h>
|
||||||
|
#include <MessageRunner.h>
|
||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <Roster.h>
|
#include <Roster.h>
|
||||||
#include <MimeType.h>
|
|
||||||
#include <MessageRunner.h>
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#include "TeamsListView.h"
|
#include "TeamsListView.h"
|
||||||
|
|
||||||
|
|
||||||
TeamListItem::TeamListItem(team_info& info)
|
// #pragma mark - BitmapStringField
|
||||||
|
|
||||||
|
|
||||||
|
BBitmapStringField::BBitmapStringField(BBitmap* bitmap, const char* string)
|
||||||
:
|
:
|
||||||
BStringItem("", false),
|
Inherited(string),
|
||||||
fIcon(NULL)
|
fBitmap(bitmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BBitmapStringField::~BBitmapStringField()
|
||||||
|
{
|
||||||
|
delete fBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BBitmapStringField::SetBitmap(BBitmap* bitmap)
|
||||||
|
{
|
||||||
|
delete fBitmap;
|
||||||
|
fBitmap = bitmap;
|
||||||
|
// TODO: cause a redraw?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - TeamsColumn
|
||||||
|
|
||||||
|
|
||||||
|
float TeamsColumn::sTextMargin = 0.0;
|
||||||
|
|
||||||
|
|
||||||
|
TeamsColumn::TeamsColumn(const char* title, float width, float minWidth,
|
||||||
|
float maxWidth, uint32 truncateMode, alignment align)
|
||||||
|
:
|
||||||
|
Inherited(title, width, minWidth, maxWidth, align),
|
||||||
|
fTruncateMode(truncateMode)
|
||||||
|
{
|
||||||
|
SetWantsEvents(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamsColumn::DrawField(BField* field, BRect rect, BView* parent)
|
||||||
|
{
|
||||||
|
BBitmapStringField* bitmapField
|
||||||
|
= dynamic_cast<BBitmapStringField*>(field);
|
||||||
|
BStringField* stringField = dynamic_cast<BStringField*>(field);
|
||||||
|
|
||||||
|
if (bitmapField) {
|
||||||
|
const BBitmap* bitmap = bitmapField->Bitmap();
|
||||||
|
|
||||||
|
// figure out the placement
|
||||||
|
float x = 0.0;
|
||||||
|
BRect r = bitmap ? bitmap->Bounds() : BRect(0, 0, 15, 15);
|
||||||
|
float y = rect.top + ((rect.Height() - r.Height()) / 2);
|
||||||
|
float width = 0.0;
|
||||||
|
|
||||||
|
switch (Alignment()) {
|
||||||
|
default:
|
||||||
|
case B_ALIGN_LEFT:
|
||||||
|
case B_ALIGN_CENTER:
|
||||||
|
x = rect.left + sTextMargin;
|
||||||
|
width = rect.right - (x + r.Width()) - (2 * sTextMargin);
|
||||||
|
r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_ALIGN_RIGHT:
|
||||||
|
x = rect.right - sTextMargin - r.Width();
|
||||||
|
width = (x - rect.left - (2 * sTextMargin));
|
||||||
|
r.Set(rect.left, rect.top, rect.left + width, rect.bottom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width != bitmapField->Width()) {
|
||||||
|
BString truncatedString(bitmapField->String());
|
||||||
|
parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
|
||||||
|
bitmapField->SetClippedString(truncatedString.String());
|
||||||
|
bitmapField->SetWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the bitmap
|
||||||
|
if (bitmap) {
|
||||||
|
parent->SetDrawingMode(B_OP_ALPHA);
|
||||||
|
parent->DrawBitmap(bitmap, BPoint(x, y));
|
||||||
|
parent->SetDrawingMode(B_OP_OVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the string
|
||||||
|
DrawString(bitmapField->ClippedString(), parent, r);
|
||||||
|
|
||||||
|
} else if (stringField) {
|
||||||
|
|
||||||
|
float width = rect.Width() - (2 * sTextMargin);
|
||||||
|
|
||||||
|
if (width != stringField->Width()) {
|
||||||
|
BString truncatedString(stringField->String());
|
||||||
|
|
||||||
|
parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
|
||||||
|
stringField->SetClippedString(truncatedString.String());
|
||||||
|
stringField->SetWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawString(stringField->ClippedString(), parent, rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
TeamsColumn::GetPreferredWidth(BField *_field, BView* parent) const
|
||||||
|
{
|
||||||
|
BBitmapStringField* bitmapField
|
||||||
|
= dynamic_cast<BBitmapStringField*>(_field);
|
||||||
|
BStringField* stringField = dynamic_cast<BStringField*>(_field);
|
||||||
|
|
||||||
|
float parentWidth = Inherited::GetPreferredWidth(_field, parent);
|
||||||
|
float width = 0.0;
|
||||||
|
|
||||||
|
if (bitmapField) {
|
||||||
|
const BBitmap* bitmap = bitmapField->Bitmap();
|
||||||
|
BFont font;
|
||||||
|
parent->GetFont(&font);
|
||||||
|
width = font.StringWidth(bitmapField->String()) + 3 * sTextMargin;
|
||||||
|
if (bitmap)
|
||||||
|
width += bitmap->Bounds().Width();
|
||||||
|
else
|
||||||
|
width += 16;
|
||||||
|
} else if (stringField) {
|
||||||
|
BFont font;
|
||||||
|
parent->GetFont(&font);
|
||||||
|
width = font.StringWidth(stringField->String()) + 2 * sTextMargin;
|
||||||
|
}
|
||||||
|
return max_c(width, parentWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamsColumn::AcceptsField(const BField* field) const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const BStringField*>(field) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamsColumn::InitTextMargin(BView* parent)
|
||||||
|
{
|
||||||
|
BFont font;
|
||||||
|
parent->GetFont(&font);
|
||||||
|
sTextMargin = ceilf(font.Size() * 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - TeamRow
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kNameColumn,
|
||||||
|
kIDColumn,
|
||||||
|
kThreadCountColumn,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TeamRow::TeamRow(team_info& info)
|
||||||
|
: BRow(20.0)
|
||||||
{
|
{
|
||||||
_SetTo(info);
|
_SetTo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TeamListItem::TeamListItem(team_id team)
|
TeamRow::TeamRow(team_id team)
|
||||||
:
|
: BRow(20.0)
|
||||||
BStringItem("", false),
|
|
||||||
fIcon(NULL)
|
|
||||||
{
|
{
|
||||||
team_info info;
|
team_info info;
|
||||||
get_team_info(team, &info);
|
get_team_info(team, &info);
|
||||||
@@ -42,89 +200,8 @@ TeamListItem::TeamListItem(team_id team)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TeamListItem::~TeamListItem()
|
|
||||||
{
|
|
||||||
delete fIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
|
||||||
{
|
|
||||||
BRect rect = frame;
|
|
||||||
|
|
||||||
if (fIcon) {
|
|
||||||
rgb_color highColor = owner->HighColor();
|
|
||||||
rgb_color lowColor = owner->LowColor();
|
|
||||||
|
|
||||||
if (IsSelected() || complete) {
|
|
||||||
// Draw the background...
|
|
||||||
if (IsSelected())
|
|
||||||
owner->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT));
|
|
||||||
|
|
||||||
owner->FillRect(rect, B_SOLID_LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
BPoint point(rect.left + 2.0f,
|
|
||||||
rect.top + (rect.Height() - B_MINI_ICON) / 2.0f);
|
|
||||||
|
|
||||||
// Draw icon
|
|
||||||
owner->SetDrawingMode(B_OP_ALPHA);
|
|
||||||
owner->DrawBitmap(fIcon, point);
|
|
||||||
owner->SetDrawingMode(B_OP_COPY);
|
|
||||||
|
|
||||||
owner->MovePenTo(rect.left + B_MINI_ICON + 8.0f, frame.top + fBaselineOffset);
|
|
||||||
|
|
||||||
if (!IsEnabled())
|
|
||||||
owner->SetHighColor(tint_color(owner->HighColor(), B_LIGHTEN_2_TINT));
|
|
||||||
else
|
|
||||||
owner->SetHighColor(0, 0, 0);
|
|
||||||
|
|
||||||
owner->DrawString(Text());
|
|
||||||
|
|
||||||
owner->SetHighColor(highColor);
|
|
||||||
owner->SetLowColor(lowColor);
|
|
||||||
} else
|
|
||||||
// No icon, fallback on plain StringItem...
|
|
||||||
BStringItem::DrawItem(owner, rect, complete);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TeamListItem::Update(BView* owner, const BFont* font)
|
|
||||||
{
|
|
||||||
BStringItem::Update(owner, font);
|
|
||||||
|
|
||||||
if (Height() < B_MINI_ICON + 4.0f)
|
|
||||||
SetHeight(B_MINI_ICON + 4.0f);
|
|
||||||
|
|
||||||
font_height fontHeight;
|
|
||||||
font->GetHeight(&fontHeight);
|
|
||||||
|
|
||||||
fBaselineOffset = fontHeight.ascent +
|
|
||||||
+ (Height() - ceilf(fontHeight.ascent + fontHeight.descent)) / 2.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
int
|
|
||||||
TeamListItem::Compare(const void* a, const void* b)
|
|
||||||
{
|
|
||||||
const BListItem*itemA = *static_cast<const BListItem* const *>(a);
|
|
||||||
const BListItem*itemB = *static_cast<const BListItem* const *>(b);
|
|
||||||
const TeamListItem*teamItemA = dynamic_cast<const TeamListItem*>(itemA);
|
|
||||||
const TeamListItem*teamItemB = dynamic_cast<const TeamListItem*>(itemB);
|
|
||||||
|
|
||||||
if (teamItemA != NULL && teamItemB != NULL) {
|
|
||||||
return teamItemA->fTeamInfo.team - teamItemB->fTeamInfo.team;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TeamListItem::_SetTo(team_info& info)
|
TeamRow::_SetTo(team_info& info)
|
||||||
{
|
{
|
||||||
BPath systemPath;
|
BPath systemPath;
|
||||||
team_info teamInfo = fTeamInfo = info;
|
team_info teamInfo = fTeamInfo = info;
|
||||||
@@ -156,39 +233,61 @@ TeamListItem::_SetTo(team_info& info)
|
|||||||
entry.GetRef(&appInfo.ref);
|
entry.GetRef(&appInfo.ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetText(teamInfo.args);
|
BBitmap* icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGBA32);
|
||||||
|
|
||||||
fIcon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGBA32);
|
status = BNodeInfo::GetTrackerIcon(&appInfo.ref, icon, B_MINI_ICON);
|
||||||
|
|
||||||
status = BNodeInfo::GetTrackerIcon(&appInfo.ref, fIcon, B_MINI_ICON);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
BMimeType genericAppType(B_APP_MIME_TYPE);
|
BMimeType genericAppType(B_APP_MIME_TYPE);
|
||||||
status = genericAppType.GetIcon(fIcon, B_MINI_ICON);
|
status = genericAppType.GetIcon(icon, B_MINI_ICON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
delete fIcon;
|
delete icon;
|
||||||
fIcon = NULL;
|
icon = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BString tmp;
|
||||||
|
tmp << teamInfo.team;
|
||||||
|
|
||||||
|
SetField(new BBitmapStringField(icon, teamInfo.args), kNameColumn);
|
||||||
|
SetField(new BStringField(tmp), kIDColumn);
|
||||||
|
|
||||||
|
tmp = "";
|
||||||
|
tmp << teamInfo.thread_count;
|
||||||
|
|
||||||
|
SetField(new BStringField(tmp), kThreadCountColumn);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
// #pragma mark - TeamsListView
|
||||||
|
|
||||||
|
|
||||||
TeamsListView::TeamsListView(BRect frame, const char* name)
|
TeamsListView::TeamsListView(BRect frame, const char* name)
|
||||||
:
|
:
|
||||||
BListView(frame, name, B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL),
|
Inherited(frame, name, B_FOLLOW_ALL, 0, B_NO_BORDER, true),
|
||||||
fUpdateRunner(NULL)
|
fUpdateRunner(NULL)
|
||||||
{
|
{
|
||||||
|
AddColumn(new TeamsColumn("Name", 400, 100, 600,
|
||||||
|
B_TRUNCATE_BEGINNING), kNameColumn);
|
||||||
|
AddColumn(new TeamsColumn("ID", 80, 40, 100,
|
||||||
|
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT), kIDColumn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
AddColumn(new TeamsColumn("Thread count", 100, 50, 500,
|
||||||
|
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT), kThreadCountColumn);
|
||||||
|
*/
|
||||||
|
SetSortingEnabled(false);
|
||||||
|
|
||||||
team_info tmi;
|
team_info tmi;
|
||||||
get_team_info(B_CURRENT_TEAM, &tmi);
|
get_team_info(B_CURRENT_TEAM, &tmi);
|
||||||
fThisTeam = tmi.team;
|
fThisTeam = tmi.team;
|
||||||
|
/*
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
SetFlags(Flags() | B_SUBPIXEL_PRECISE);
|
SetFlags(Flags() | B_SUBPIXEL_PRECISE);
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -201,7 +300,8 @@ TeamsListView::~TeamsListView()
|
|||||||
void
|
void
|
||||||
TeamsListView::AttachedToWindow()
|
TeamsListView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
BListView::AttachedToWindow();
|
Inherited::AttachedToWindow();
|
||||||
|
TeamsColumn::InitTextMargin(ScrollView());
|
||||||
|
|
||||||
_InitList();
|
_InitList();
|
||||||
|
|
||||||
@@ -215,18 +315,14 @@ TeamsListView::AttachedToWindow()
|
|||||||
void
|
void
|
||||||
TeamsListView::DetachedFromWindow()
|
TeamsListView::DetachedFromWindow()
|
||||||
{
|
{
|
||||||
BListView::DetachedFromWindow();
|
Inherited::DetachedFromWindow();
|
||||||
|
|
||||||
be_roster->StopWatching(this);
|
be_roster->StopWatching(this);
|
||||||
|
|
||||||
delete fUpdateRunner;
|
delete fUpdateRunner;
|
||||||
fUpdateRunner = NULL;
|
fUpdateRunner = NULL;
|
||||||
|
|
||||||
// free all items, they will be retrieved again in AttachedToWindow()
|
Clear(); // MakeEmpty();
|
||||||
for (int32 i = CountItems(); i-- > 0;) {
|
|
||||||
delete ItemAt(i);
|
|
||||||
}
|
|
||||||
MakeEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -244,12 +340,12 @@ TeamsListView::MessageReceived(BMessage* message)
|
|||||||
if (message->FindInt32("be:team", &team) != B_OK)
|
if (message->FindInt32("be:team", &team) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TeamListItem* item = new(std::nothrow) TeamListItem(team);
|
TeamRow* row = new(std::nothrow) TeamRow(team);
|
||||||
if (item != NULL) {
|
if (row != NULL) {
|
||||||
if (!AddItem(item))
|
AddRow(row);
|
||||||
delete item;
|
/*else
|
||||||
else
|
|
||||||
SortItems(&TeamListItem::Compare);
|
SortItems(&TeamListItem::Compare);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -260,30 +356,30 @@ TeamsListView::MessageReceived(BMessage* message)
|
|||||||
if (message->FindInt32("be:team", &team) != B_OK)
|
if (message->FindInt32("be:team", &team) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TeamListItem* item = FindItem(team);
|
TeamRow* row = FindTeamRow(team);
|
||||||
if (item != NULL) {
|
if (row != NULL) {
|
||||||
RemoveItem(item);
|
RemoveRow(row);
|
||||||
delete item;
|
delete row;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BListView::MessageReceived(message);
|
Inherited::MessageReceived(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TeamListItem*
|
TeamRow*
|
||||||
TeamsListView::FindItem(team_id teamId)
|
TeamsListView::FindTeamRow(team_id teamId)
|
||||||
{
|
{
|
||||||
for (int32 i = CountItems(); i-- > 0;) {
|
for (int32 i = CountRows(); i-- > 0;) {
|
||||||
TeamListItem* item = dynamic_cast<TeamListItem*>(ItemAt(i));
|
TeamRow* row = dynamic_cast<TeamRow*>(RowAt(i));
|
||||||
if (item == NULL)
|
if (row == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (item->TeamID() == teamId)
|
if (row->TeamID() == teamId)
|
||||||
return item;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -297,8 +393,8 @@ TeamsListView::_InitList()
|
|||||||
team_info tmi;
|
team_info tmi;
|
||||||
|
|
||||||
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
|
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
|
||||||
TeamListItem* item = new(std::nothrow) TeamListItem(tmi);
|
TeamRow* row = new(std::nothrow) TeamRow(tmi);
|
||||||
if (item == NULL) {
|
if (row == NULL) {
|
||||||
// Memory issue. Bail out.
|
// Memory issue. Bail out.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -306,15 +402,11 @@ TeamsListView::_InitList()
|
|||||||
if (tmi.team == B_SYSTEM_TEAM ||
|
if (tmi.team == B_SYSTEM_TEAM ||
|
||||||
tmi.team == fThisTeam) {
|
tmi.team == fThisTeam) {
|
||||||
// We don't support debugging kernel and... ourself!
|
// We don't support debugging kernel and... ourself!
|
||||||
item->SetEnabled(false);
|
row->SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AddItem(item))
|
AddRow(row);
|
||||||
delete item;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SortItems(&TeamListItem::Compare);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -323,44 +415,37 @@ TeamsListView::_UpdateList()
|
|||||||
{
|
{
|
||||||
int32 tmi_cookie = 0;
|
int32 tmi_cookie = 0;
|
||||||
team_info tmi;
|
team_info tmi;
|
||||||
TeamListItem* item;
|
TeamRow* row;
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
// NOTA: assuming get_next_team_info() returns teams ordered by team ID...
|
// NOTA: assuming get_next_team_info() returns teams ordered by team ID...
|
||||||
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
|
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
|
||||||
|
|
||||||
item = (TeamListItem*) ItemAt(index);
|
row = dynamic_cast<TeamRow*>(RowAt(index));
|
||||||
while (item && tmi.team > item->TeamID()) {
|
while (row && tmi.team > row->TeamID()) {
|
||||||
RemoveItem(item);
|
RemoveRow(row);
|
||||||
delete item;
|
delete row;
|
||||||
item = (TeamListItem*) ItemAt(index);
|
row = dynamic_cast<TeamRow*>(RowAt(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == NULL || tmi.team != item->TeamID()) {
|
if (row == NULL || tmi.team != row->TeamID()) {
|
||||||
// Team not found in previously known teams list: insert a new item
|
// Team not found in previously known teams list: insert a new row
|
||||||
TeamListItem* newItem = new(std::nothrow) TeamListItem(tmi);
|
TeamRow* newRow = new(std::nothrow) TeamRow(tmi);
|
||||||
if (newItem != NULL) {
|
if (newRow != NULL) {
|
||||||
bool added;
|
if (row == NULL) {
|
||||||
|
// No row found with bigger team id: append at list end
|
||||||
if (item == NULL) {
|
AddRow(newRow);
|
||||||
// No item found with bigger team id: append at list end
|
|
||||||
added = AddItem(newItem);
|
|
||||||
} else
|
} else
|
||||||
added = AddItem(newItem, index);
|
AddRow(newRow, index);
|
||||||
|
|
||||||
if (!added) {
|
|
||||||
// AddItem() failed! Memory Issue?
|
|
||||||
delete newItem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index++; // Move list sync head.
|
index++; // Move list sync head.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove tail list items, if we don't walk list thru the end
|
// Remove tail list rows, if we don't walk list thru the end
|
||||||
while ((item = (TeamListItem*) ItemAt(index)) != NULL) {
|
while ((row = dynamic_cast<TeamRow*>(RowAt(index))) != NULL) {
|
||||||
RemoveItem(item);
|
RemoveRow(row);
|
||||||
delete item;
|
delete row;
|
||||||
item = (TeamListItem*) ItemAt(++index);
|
row = dynamic_cast<TeamRow*>(RowAt(++index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2010, Philippe Houdoin, [email protected]. All rights reserved.
|
* Copyright 2009-2010 Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT license.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Philippe Houdoin
|
||||||
*/
|
*/
|
||||||
#ifndef TEAMS_LIST_ITEM_H
|
#ifndef TEAMS_LIST_ITEM_H
|
||||||
#define TEAMS_LIST_ITEM_H
|
#define TEAMS_LIST_ITEM_H
|
||||||
|
|
||||||
|
|
||||||
#include <ListView.h>
|
#include <ColumnListView.h>
|
||||||
#include <StringItem.h>
|
#include <ColumnTypes.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
class BBitmap;
|
class BBitmap;
|
||||||
class BMessageRunner;
|
class BMessageRunner;
|
||||||
|
|
||||||
|
|
||||||
class TeamListItem : public BStringItem {
|
// A field type displaying both a bitmap and a string so that the
|
||||||
|
// tree display looks nicer (both text and bitmap are indented)
|
||||||
|
class BBitmapStringField : public BStringField {
|
||||||
|
typedef BStringField Inherited;
|
||||||
public:
|
public:
|
||||||
TeamListItem(team_info & teamInfo);
|
BBitmapStringField(BBitmap* bitmap,
|
||||||
TeamListItem(team_id teamId);
|
const char* string);
|
||||||
virtual ~TeamListItem();
|
virtual ~BBitmapStringField();
|
||||||
|
|
||||||
|
void SetBitmap(BBitmap* bitmap);
|
||||||
|
const BBitmap* Bitmap() const
|
||||||
|
{ return fBitmap; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BBitmap* fBitmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// BColumn for TeamsListView which knows how to render
|
||||||
|
// a BBitmapStringField
|
||||||
|
class TeamsColumn : public BTitledColumn {
|
||||||
|
typedef BTitledColumn Inherited;
|
||||||
|
public:
|
||||||
|
TeamsColumn(const char* title,
|
||||||
|
float width, float minWidth,
|
||||||
|
float maxWidth, uint32 truncateMode,
|
||||||
|
alignment align = B_ALIGN_LEFT);
|
||||||
|
|
||||||
|
virtual void DrawField(BField* field, BRect rect,
|
||||||
|
BView* parent);
|
||||||
|
virtual float GetPreferredWidth(BField* field, BView* parent) const;
|
||||||
|
|
||||||
|
virtual bool AcceptsField(const BField* field) const;
|
||||||
|
|
||||||
|
static void InitTextMargin(BView* parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 fTruncateMode;
|
||||||
|
static float sTextMargin;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TeamRow : public BRow {
|
||||||
|
typedef BRow Inherited;
|
||||||
|
public:
|
||||||
|
TeamRow(team_info & teamInfo);
|
||||||
|
TeamRow(team_id teamId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void DrawItem(BView *owner, BRect itemRect,
|
team_id TeamID() const { return fTeamInfo.team; }
|
||||||
bool drawEverything = false);
|
|
||||||
virtual void Update(BView *owner, const BFont *font);
|
|
||||||
|
|
||||||
team_id TeamID() { return fTeamInfo.team; };
|
virtual void SetEnabled(bool enabled) { fEnabled = enabled; }
|
||||||
|
bool IsEnabled() const { return fEnabled; }
|
||||||
static int Compare(const void* a, const void* b);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SetTo(team_info & info);
|
status_t _SetTo(team_info & info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool fEnabled;
|
||||||
team_info fTeamInfo;
|
team_info fTeamInfo;
|
||||||
BBitmap * fIcon;
|
|
||||||
float fBaselineOffset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TeamsListView : public BListView {
|
class TeamsListView : public BColumnListView {
|
||||||
|
typedef BColumnListView Inherited;
|
||||||
public:
|
public:
|
||||||
TeamsListView(BRect frame, const char* name);
|
TeamsListView(BRect frame, const char* name);
|
||||||
virtual ~TeamsListView();
|
virtual ~TeamsListView();
|
||||||
|
|
||||||
TeamListItem* FindItem(team_id teamId);
|
TeamRow* FindTeamRow(team_id teamId);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
|
|||||||
@@ -60,12 +60,10 @@ TeamsWindow::MessageReceived(BMessage* message)
|
|||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case kMsgDebugThisTeam:
|
case kMsgDebugThisTeam:
|
||||||
{
|
{
|
||||||
TeamListItem* item = dynamic_cast<TeamListItem*>(fTeamsListView->ItemAt(
|
TeamRow* row = dynamic_cast<TeamRow*>(fTeamsListView->CurrentSelection());
|
||||||
fTeamsListView->CurrentSelection()));
|
if (row != NULL) {
|
||||||
|
|
||||||
if (item != NULL) {
|
|
||||||
BMessage message(MSG_DEBUG_THIS_TEAM);
|
BMessage message(MSG_DEBUG_THIS_TEAM);
|
||||||
message.AddInt32("team", item->TeamID());
|
message.AddInt32("team", row->TeamID());
|
||||||
be_app_messenger.SendMessage(&message);
|
be_app_messenger.SendMessage(&message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -109,21 +107,11 @@ TeamsWindow::_Init()
|
|||||||
|
|
||||||
// Add a teams list view
|
// Add a teams list view
|
||||||
frame = Bounds();
|
frame = Bounds();
|
||||||
frame.right -= B_V_SCROLL_BAR_WIDTH;
|
frame.InsetBy(-1, -1);
|
||||||
|
|
||||||
fTeamsListView = new TeamsListView(frame, "TeamsList");
|
fTeamsListView = new TeamsListView(frame, "TeamsList");
|
||||||
fTeamsListView->SetInvocationMessage(new BMessage(kMsgDebugThisTeam));
|
fTeamsListView->SetInvocationMessage(new BMessage(kMsgDebugThisTeam));
|
||||||
|
|
||||||
BScrollView * teamsScroller = new BScrollView("TeamsListScroller",
|
AddChild(fTeamsListView);
|
||||||
fTeamsListView, B_FOLLOW_ALL_SIDES, 0, false, true, B_NO_BORDER);
|
|
||||||
|
|
||||||
AddChild(teamsScroller);
|
|
||||||
|
|
||||||
// small visual tweak
|
|
||||||
if (BScrollBar* scrollBar = teamsScroller->ScrollBar(B_VERTICAL)) {
|
|
||||||
scrollBar->MoveBy(0, -1);
|
|
||||||
scrollBar->ResizeBy(0, -(B_H_SCROLL_BAR_HEIGHT - 2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class BListView;
|
|||||||
class BFile;
|
class BFile;
|
||||||
class BMessage;
|
class BMessage;
|
||||||
class SettingsManager;
|
class SettingsManager;
|
||||||
|
class TeamsListView;
|
||||||
|
|
||||||
class TeamsWindow : public BWindow {
|
class TeamsWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
@@ -32,7 +32,7 @@ private:
|
|||||||
status_t _SaveSettings();
|
status_t _SaveSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BListView* fTeamsListView;
|
TeamsListView* fTeamsListView;
|
||||||
SettingsManager* fSettingsManager;
|
SettingsManager* fSettingsManager;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user