* Changed the layout of the team window. Trying a single window approach.

* Added Run/Step* buttons.
* Added some handling for selection in the thread list.
* Extended listener mechanisms all over the place (in models and views).
* The team debugger now gets the initial states for the team's threads.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31097 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-06-18 00:35:12 +00:00
parent 6d9fec816e
commit ae53f49064
18 changed files with 536 additions and 61 deletions
+2 -1
View File
@@ -6,8 +6,9 @@
#include "Image.h"
Image::Image(const image_info& imageInfo)
Image::Image(Team* team,const image_info& imageInfo)
:
fTeam(team),
fInfo(imageInfo)
{
}
+7 -1
View File
@@ -11,18 +11,24 @@
#include <util/DoublyLinkedList.h>
class Team;
class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> {
public:
Image(const image_info& imageInfo);
Image(Team* team, const image_info& imageInfo);
~Image();
status_t Init();
Team* GetTeam() const { return fTeam; }
image_id ID() const { return fInfo.id; }
const char* Name() const { return fInfo.name; }
const image_info& Info() const { return fInfo; }
private:
Team* fTeam;
image_info fInfo;
};
+2 -1
View File
@@ -20,8 +20,9 @@ Application Debugger :
ElfFile.cpp
Image.cpp
TeamDebugger.cpp
Team.cpp
TeamDebugger.cpp
TeamDebugModel.cpp
Thread.cpp
# DebugAnalyzer:util
+17
View File
@@ -0,0 +1,17 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef MESSAGE_CODES_H
#define MESSAGE_CODES_H
enum {
MSG_THREAD_RUN = 'run_',
MSG_THREAD_STEP_OVER = 'stov',
MSG_THREAD_STEP_INTO = 'stin',
MSG_THREAD_STEP_OUT = 'stou'
};
#endif // MESSAGE_CODES_H
+48 -10
View File
@@ -7,6 +7,8 @@
#include <new>
#include <AutoLocker.h>
// #pragma mark - Team
@@ -53,7 +55,7 @@ Team::AddThread(Thread* thread)
status_t
Team::AddThread(const thread_info& threadInfo, Thread** _thread)
{
Thread* thread = new(std::nothrow) Thread(threadInfo.thread);
Thread* thread = new(std::nothrow) Thread(this, threadInfo.thread);
if (thread == NULL)
return B_NO_MEMORY;
@@ -134,7 +136,7 @@ Team::AddImage(Image* image)
status_t
Team::AddImage(const image_info& imageInfo, Image** _image)
{
Image* image = new(std::nothrow) Image(imageInfo);
Image* image = new(std::nothrow) Image(this, imageInfo);
if (image == NULL)
return B_NO_MEMORY;
@@ -197,6 +199,7 @@ Team::Images() const
void
Team::AddListener(Listener* listener)
{
AutoLocker<Team> locker(this);
fListeners.Add(listener);
}
@@ -204,6 +207,7 @@ Team::AddListener(Listener* listener)
void
Team::RemoveListener(Listener* listener)
{
AutoLocker<Team> locker(this);
fListeners.Remove(listener);
}
@@ -213,7 +217,7 @@ Team::_NotifyThreadAdded(Thread* thread)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->ThreadAdded(this, thread);
listener->ThreadAdded(ThreadEvent(TEAM_EVENT_THREAD_ADDED, thread));
}
}
@@ -223,7 +227,7 @@ Team::_NotifyThreadRemoved(Thread* thread)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->ThreadRemoved(this, thread);
listener->ThreadRemoved(ThreadEvent(TEAM_EVENT_THREAD_REMOVED, thread));
}
}
@@ -233,7 +237,7 @@ Team::_NotifyImageAdded(Image* image)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->ImageAdded(this, image);
listener->ImageAdded(ImageEvent(TEAM_EVENT_IMAGE_ADDED, image));
}
}
@@ -243,37 +247,71 @@ Team::_NotifyImageRemoved(Image* image)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->ImageRemoved(this, image);
listener->ImageRemoved(ImageEvent(TEAM_EVENT_IMAGE_REMOVED, image));
}
}
// #pragma mark - Event
Team::Event::Event(uint32 type, Team* team)
:
fEventType(type),
fTeam(team)
{
}
// #pragma mark - ThreadEvent
Team::ThreadEvent::ThreadEvent(uint32 type, Thread* thread)
:
Event(type, thread->GetTeam()),
fThread(thread)
{
}
// #pragma mark - ImageEvent
Team::ImageEvent::ImageEvent(uint32 type, Image* image)
:
Event(type, image->GetTeam()),
fImage(image)
{
}
// #pragma mark - Listener
Team::Listener::~Listener()
{
}
void
Team::Listener::ThreadAdded(Team* team, Thread* thread)
Team::Listener::ThreadAdded(const Team::ThreadEvent& event)
{
}
void
Team::Listener::ThreadRemoved(Team* team, Thread* thread)
Team::Listener::ThreadRemoved(const Team::ThreadEvent& event)
{
}
void
Team::Listener::ImageAdded(Team* team, Image* image)
Team::Listener::ImageAdded(const Team::ImageEvent& event)
{
}
void
Team::Listener::ImageRemoved(Team* team, Image* image)
Team::Listener::ImageRemoved(const Team::ImageEvent& event)
{
}
+51 -4
View File
@@ -11,8 +11,20 @@
#include "Thread.h"
// team event types
enum {
TEAM_EVENT_THREAD_ADDED,
TEAM_EVENT_THREAD_REMOVED,
TEAM_EVENT_IMAGE_ADDED,
TEAM_EVENT_IMAGE_REMOVED
};
class Team : public BLocker {
public:
class Event;
class ThreadEvent;
class ImageEvent;
class Listener;
public:
@@ -65,15 +77,50 @@ private:
};
class Team::Event {
public:
Event(uint32 type, Team* team);
uint32 EventType() const { return fEventType; }
Team* GetTeam() const { return fTeam; }
protected:
uint32 fEventType;
Team* fTeam;
};
class Team::ThreadEvent : public Event {
public:
ThreadEvent(uint32 type, Thread* thread);
Thread* GetThread() const { return fThread; }
protected:
Thread* fThread;
};
class Team::ImageEvent : public Event {
public:
ImageEvent(uint32 type, Image* image);
Image* GetImage() const { return fImage; }
protected:
Image* fImage;
};
class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
public:
virtual ~Listener();
virtual void ThreadAdded(Team* team, Thread* thread);
virtual void ThreadRemoved(Team* team, Thread* thread);
virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(const Team::ThreadEvent& event);
virtual void ImageAdded(Team* team, Image* image);
virtual void ImageRemoved(Team* team, Image* image);
virtual void ImageAdded(const Team::ImageEvent& event);
virtual void ImageRemoved(const Team::ImageEvent& event);
};
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "TeamDebugModel.h"
#include <new>
#include <AutoLocker.h>
// #pragma mark - TeamDebugModel
TeamDebugModel::TeamDebugModel(Team* team)
:
fTeam(team)
{
}
TeamDebugModel::~TeamDebugModel()
{
}
status_t
TeamDebugModel::Init()
{
return B_OK;
}
void
TeamDebugModel::AddListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Add(listener);
}
void
TeamDebugModel::RemoveListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Remove(listener);
}
// #pragma mark - Event
TeamDebugModel::Event::Event(uint32 type, TeamDebugModel* model)
:
fEventType(type),
fModel(model)
{
}
// #pragma mark - Listener
TeamDebugModel::Listener::~Listener()
{
}
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_DEBUG_MODEL_H
#define TEAM_DEBUG_MODEL_H
#include "Team.h"
// team debug model event types
//enum {
// TEAM_EVENT_THREAD_ADDED
//};
class TeamDebugModel {
public:
class Event;
class Listener;
public:
TeamDebugModel(Team* team);
~TeamDebugModel();
status_t Init();
bool Lock() { return fTeam->Lock(); }
void Unlock() { fTeam->Unlock(); }
Team* GetTeam() const { return fTeam; }
void AddListener(Listener* listener);
void RemoveListener(Listener* listener);
private:
typedef DoublyLinkedList<Listener> ListenerList;
private:
Team* fTeam;
ListenerList fListeners;
};
class TeamDebugModel::Event {
public:
Event(uint32 type, TeamDebugModel* model);
uint32 EventType() const { return fEventType; }
TeamDebugModel* Model() const { return fModel; }
protected:
uint32 fEventType;
TeamDebugModel* fModel;
};
class TeamDebugModel::Listener
: public DoublyLinkedListLinkImpl<TeamDebugModel::Listener> {
public:
virtual ~Listener();
// virtual void ThreadAdded(const Team::ThreadEvent& event);
};
#endif // TEAM_DEBUG_MODEL_H
+45 -2
View File
@@ -16,12 +16,14 @@
#include "debug_utils.h"
#include "Team.h"
#include "TeamDebugModel.h"
TeamDebugger::TeamDebugger()
:
BLooper("team debugger"),
fTeam(NULL),
fDebugModel(NULL),
fTeamID(-1),
fDebuggerPort(-1),
fNubPort(-1),
@@ -29,6 +31,7 @@ TeamDebugger::TeamDebugger()
fTeamWindow(NULL),
fTerminating(false)
{
fDebugContext.reply_port = -1;
}
@@ -46,6 +49,9 @@ TeamDebugger::~TeamDebugger()
if (fDebugEventListener >= 0)
wait_for_thread(fDebugEventListener, NULL);
destroy_debug_context(&fDebugContext);
delete fDebugModel;
delete fTeam;
}
@@ -72,6 +78,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
fTeam->SetName(teamInfo.args);
// TODO: Set a better name!
// create the team debug model
fDebugModel = new(std::nothrow) TeamDebugModel(fTeam);
if (fDebugModel == NULL)
return B_NO_MEMORY;
error = fDebugModel->Init();
if (error != B_OK)
return error;
// create debugger port
char buffer[128];
snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID);
@@ -99,9 +114,12 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
thread_info threadInfo;
int32 cookie = 0;
while (get_next_thread_info(fTeamID, &cookie, &threadInfo) == B_OK) {
error = fTeam->AddThread(threadInfo);
::Thread* thread;
error = fTeam->AddThread(threadInfo, &thread);
if (error != B_OK)
return error;
_UpdateThreadState(thread);
}
image_info imageInfo;
@@ -128,7 +146,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
// create the team window
try {
fTeamWindow = TeamWindow::Create(fTeam, this);
fTeamWindow = TeamWindow::Create(fDebugModel, this);
} catch (...) {
// TODO: Notify the user!
fprintf(stderr, "Error: Failed to create team window!\n");
@@ -303,3 +321,28 @@ TeamDebugger::_HandleImageDeleted(const debug_image_deleted& message)
fTeam->RemoveImage(message.info.id);
return false;
}
void
TeamDebugger::_UpdateThreadState(::Thread* thread)
{
debug_nub_get_cpu_state message;
message.reply_port = fDebugContext.reply_port;
message.thread = thread->ID();
debug_nub_get_cpu_state_reply reply;
status_t error = send_debug_message(&fDebugContext,
B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), &reply,
sizeof(reply));
uint32 newState = THREAD_STATE_UNKNOWN;
if (error == B_OK) {
if (reply.error == B_OK)
newState = THREAD_STATE_STOPPED;
else if (reply.error == B_BAD_THREAD_STATE)
newState = THREAD_STATE_RUNNING;
}
thread->SetState(newState);
}
+4
View File
@@ -15,6 +15,7 @@
class Team;
class TeamDebugModel;
class TeamDebugger : public DoublyLinkedListLinkImpl<TeamDebugger>,
@@ -47,8 +48,11 @@ private:
bool _HandleImageDeleted(
const debug_image_deleted& message);
void _UpdateThreadState(::Thread* thread);
private:
::Team* fTeam;
TeamDebugModel* fDebugModel;
team_id fTeamID;
port_id fDebuggerPort;
port_id fNubPort;
+11 -2
View File
@@ -6,9 +6,11 @@
#include "Thread.h"
Thread::Thread(thread_id threadID)
Thread::Thread(Team* team, thread_id threadID)
:
fID(threadID)
fTeam(team),
fID(threadID),
fState(THREAD_STATE_UNKNOWN)
{
}
@@ -30,3 +32,10 @@ Thread::SetName(const BString& name)
{
fName = name;
}
void
Thread::SetState(uint32 state)
{
fState = state;
}
+17 -2
View File
@@ -12,22 +12,37 @@
#include <util/DoublyLinkedList.h>
class Team;
enum {
THREAD_STATE_UNKNOWN,
THREAD_STATE_RUNNING,
THREAD_STATE_STOPPED
};
class Thread : public Referenceable, public DoublyLinkedListLinkImpl<Thread> {
public:
Thread(thread_id threadID);
Thread(Team* team, thread_id threadID);
~Thread();
status_t Init();
thread_id ID() const { return fID; }
Team* GetTeam() const { return fTeam; }
thread_id ID() const { return fID; }
const char* Name() const { return fName.String(); }
void SetName(const BString& name);
uint32 State() const { return fState; }
void SetState(uint32 state);
private:
Team* fTeam;
thread_id fID;
BString fName;
uint32 fState;
};
@@ -204,14 +204,14 @@ ImageListView::MessageReceived(BMessage* message)
void
ImageListView::ImageAdded(Team* team, Image* image)
ImageListView::ImageAdded(const Team::ImageEvent& event)
{
Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this);
}
void
ImageListView::ImageRemoved(Team* team, Image* image)
ImageListView::ImageRemoved(const Team::ImageEvent& event)
{
Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this);
}
@@ -29,8 +29,8 @@ private:
private:
// Team::Listener
virtual void ImageAdded(Team* team, Image* image);
virtual void ImageRemoved(Team* team, Image* image);
virtual void ImageAdded(const Team::ImageEvent& event);
virtual void ImageRemoved(const Team::ImageEvent& event);
// TableListener
virtual void TableRowInvoked(Table* table, int32 rowIndex);
+120 -17
View File
@@ -5,6 +5,9 @@
#include "TeamWindow.h"
#include <stdio.h>
#include <Button.h>
#include <LayoutBuilder.h>
#include <Message.h>
#include <TabView.h>
@@ -12,23 +15,29 @@
#include <TextView.h>
#include "ImageListView.h"
#include "Team.h"
#include "ThreadListView.h"
#include "MessageCodes.h"
#include "TeamDebugModel.h"
// #pragma mark - TeamWindow
TeamWindow::TeamWindow(::Team* team, Listener* listener)
TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
:
BWindow(BRect(100, 100, 699, 499), "Team", B_DOCUMENT_WINDOW,
BWindow(BRect(100, 100, 899, 699), "Team", B_DOCUMENT_WINDOW,
B_ASYNCHRONOUS_CONTROLS),
fTeam(team),
fDebugModel(debugModel),
fActiveThread(NULL),
fListener(listener),
fTabView(NULL),
fThreadListView(NULL),
fImageListView(NULL)
fImageListView(NULL),
fRunButton(NULL),
fStepOverButton(NULL),
fStepIntoButton(NULL),
fStepOutButton(NULL)
{
::Team* team = debugModel->GetTeam();
BString name = team->Name();
if (team->ID() >= 0)
name << " (" << team->ID() << ")";
@@ -42,9 +51,9 @@ TeamWindow::~TeamWindow()
/*static*/ TeamWindow*
TeamWindow::Create(::Team* team, Listener* listener)
TeamWindow::Create(TeamDebugModel* debugModel, Listener* listener)
{
TeamWindow* self = new TeamWindow(team, listener);
TeamWindow* self = new TeamWindow(debugModel, listener);
try {
self->_Init();
@@ -61,6 +70,18 @@ void
TeamWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_THREAD_RUN:
printf("MSG_THREAD_RUN\n");
break;
case MSG_THREAD_STEP_OVER:
printf("MSG_THREAD_STEP_OVER\n");
break;
case MSG_THREAD_STEP_INTO:
printf("MSG_THREAD_STEP_INTO\n");
break;
case MSG_THREAD_STEP_OUT:
printf("MSG_THREAD_STEP_OUT\n");
break;
default:
BWindow::MessageReceived(message);
break;
@@ -75,6 +96,13 @@ TeamWindow::QuitRequested()
}
void
TeamWindow::ThreadSelectionChanged(::Thread* thread)
{
_SetActiveThread(thread);
}
void
TeamWindow::_Init()
{
@@ -84,18 +112,93 @@ TeamWindow::_Init()
BLayoutBuilder::Group<>(rootLayout)
.AddSplit(B_VERTICAL, 3.0f)
.Add(fTabView = new BTabView("tab view"), 0.4f)
.AddSplit(B_HORIZONTAL, 3.0f)
.Add(fImageListView = ImageListView::Create())
.Add(new BTextView("source view"), 2.0f)
.AddGroup(B_VERTICAL, 4.0f)
.AddGroup(B_HORIZONTAL, 4.0f)
.Add(fRunButton = new BButton("Run"))
.Add(fStepOverButton = new BButton("Step Over"))
.Add(fStepIntoButton = new BButton("Step Into"))
.Add(fStepOutButton = new BButton("Step Out"))
.AddGlue()
.End()
.AddSplit(B_HORIZONTAL, 3.0f)
.Add(new BTextView("source view"), 3.0f)
.Add(new BTextView("variables view"))
.End()
.End()
.End();
fTabView->AddTab(fThreadListView = ThreadListView::Create());
// fTabView->AddTab(fTeamsPage = new TeamsPage(this));
// fTabView->AddTab(fThreadsPage = new ThreadsPage(this));
fThreadListView->SetTeam(fTeam);
fImageListView->SetTeam(fTeam);
// add threads tab
BSplitView* threadGroup = new BSplitView(B_HORIZONTAL);
threadGroup->SetName("Threads");
fTabView->AddTab(threadGroup);
BLayoutBuilder::Split<>(threadGroup)
.Add(fThreadListView = ThreadListView::Create(this))
.Add(new BTextView("stack frames"));
// add images tab
BSplitView* imagesGroup = new BSplitView(B_HORIZONTAL);
imagesGroup->SetName("Images");
fTabView->AddTab(imagesGroup);
BLayoutBuilder::Split<>(imagesGroup)
.Add(fImageListView = ImageListView::Create())
.Add(new BTextView("source files"));
fThreadListView->SetTeam(fDebugModel->GetTeam());
fImageListView->SetTeam(fDebugModel->GetTeam());
fRunButton->SetMessage(new BMessage(MSG_THREAD_RUN));
fStepOverButton->SetMessage(new BMessage(MSG_THREAD_STEP_OVER));
fStepIntoButton->SetMessage(new BMessage(MSG_THREAD_STEP_INTO));
fStepOutButton->SetMessage(new BMessage(MSG_THREAD_STEP_OUT));
fRunButton->SetTarget(this);
fStepOverButton->SetTarget(this);
fRunButton->SetTarget(this);
fStepOutButton->SetTarget(this);
_UpdateRunButtons();
}
void
TeamWindow::_SetActiveThread(::Thread* thread)
{
if (thread == fActiveThread)
return;
fActiveThread = thread;
_UpdateRunButtons();
}
void
TeamWindow::_UpdateRunButtons()
{
uint32 threadState = fActiveThread != NULL
? fActiveThread->State() : THREAD_STATE_UNKNOWN;
switch (threadState) {
case THREAD_STATE_UNKNOWN:
fRunButton->SetEnabled(false);
fStepOverButton->SetEnabled(false);
fStepIntoButton->SetEnabled(false);
fStepOutButton->SetEnabled(false);
break;
case THREAD_STATE_RUNNING:
fRunButton->SetLabel("Stop");
fRunButton->SetEnabled(true);
fStepOverButton->SetEnabled(false);
fStepIntoButton->SetEnabled(false);
fStepOutButton->SetEnabled(false);
break;
case THREAD_STATE_STOPPED:
fRunButton->SetLabel("Run");
fRunButton->SetEnabled(true);
fStepOverButton->SetEnabled(true);
fStepIntoButton->SetEnabled(true);
fStepOutButton->SetEnabled(true);
break;
}
}
+21 -5
View File
@@ -8,36 +8,52 @@
#include <String.h>
#include <Window.h>
#include "ThreadListView.h"
class BButton;
class BTabView;
class ImageListView;
class Team;
class ThreadListView;
class TeamDebugModel;
class TeamWindow : public BWindow {
class TeamWindow : public BWindow, private ThreadListView::Listener {
public:
class Listener;
public:
TeamWindow(::Team* team, Listener* listener);
TeamWindow(TeamDebugModel* debugModel,
Listener* listener);
~TeamWindow();
static TeamWindow* Create(::Team* team, Listener* listener);
static TeamWindow* Create(TeamDebugModel* debugModel,
Listener* listener);
// throws
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
private:
// ThreadListView::Listener
virtual void ThreadSelectionChanged(::Thread* thread);
void _Init();
void _SetActiveThread(::Thread* thread);
void _UpdateRunButtons();
private:
::Team* fTeam;
TeamDebugModel* fDebugModel;
::Thread* fActiveThread;
Listener* fListener;
BTabView* fTabView;
ThreadListView* fThreadListView;
ImageListView* fImageListView;
BButton* fRunButton;
BButton* fStepOverButton;
BButton* fStepIntoButton;
BButton* fStepOutButton;
};
@@ -129,12 +129,13 @@ private:
// #pragma mark - ThreadListView
ThreadListView::ThreadListView()
ThreadListView::ThreadListView(Listener* listener)
:
BGroupView(B_VERTICAL),
fTeam(NULL),
fThreadsTable(NULL),
fThreadsTableModel(NULL)
fThreadsTableModel(NULL),
fListener(listener)
{
SetName("Threads");
}
@@ -149,9 +150,9 @@ ThreadListView::~ThreadListView()
/*static*/ ThreadListView*
ThreadListView::Create()
ThreadListView::Create(Listener* listener)
{
ThreadListView* self = new ThreadListView;
ThreadListView* self = new ThreadListView(listener);
try {
self->_Init();
@@ -204,19 +205,33 @@ ThreadListView::MessageReceived(BMessage* message)
void
ThreadListView::ThreadAdded(Team* team, Thread* thread)
ThreadListView::ThreadAdded(const Team::ThreadEvent& event)
{
Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this);
}
void
ThreadListView::ThreadRemoved(Team* team, Thread* thread)
ThreadListView::ThreadRemoved(const Team::ThreadEvent& event)
{
Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this);
}
void
ThreadListView::TableSelectionChanged(Table* table)
{
Thread* thread = NULL;
if (fThreadsTableModel != NULL) {
TableSelectionModel* selectionModel = table->SelectionModel();
thread = fThreadsTableModel->ThreadAt(selectionModel->RowAt(0));
}
fListener->ThreadSelectionChanged(thread);
}
void
ThreadListView::TableRowInvoked(Table* table, int32 rowIndex)
{
@@ -233,12 +248,21 @@ ThreadListView::_Init()
{
fThreadsTable = new Table("threads list", 0);
AddChild(fThreadsTable->ToView());
// columns
fThreadsTable->AddColumn(new Int32TableColumn(0, "ID", 40, 20, 1000,
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT));
fThreadsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT));
fThreadsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST);
fThreadsTable->AddTableListener(this);
}
// #pragma mark - Listener
ThreadListView::Listener::~Listener()
{
}
@@ -11,13 +11,19 @@
#include "Team.h"
class Thread;
class ThreadListView : public BGroupView, private Team::Listener,
private TableListener {
public:
ThreadListView();
class Listener;
public:
ThreadListView(Listener* listener);
~ThreadListView();
static ThreadListView* Create();
static ThreadListView* Create(Listener* listener);
// throws
void SetTeam(Team* team);
@@ -29,10 +35,11 @@ private:
private:
// Team::Listener
virtual void ThreadAdded(Team* team, Thread* thread);
virtual void ThreadRemoved(Team* team, Thread* thread);
virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(const Team::ThreadEvent& event);
// TableListener
virtual void TableSelectionChanged(Table* table);
virtual void TableRowInvoked(Table* table, int32 rowIndex);
void _Init();
@@ -41,6 +48,15 @@ private:
Team* fTeam;
Table* fThreadsTable;
ThreadsTableModel* fThreadsTableModel;
Listener* fListener;
};
class ThreadListView::Listener {
public:
virtual ~Listener();
virtual void ThreadSelectionChanged(Thread* thread) = 0;
};