xref: /haiku/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
1 /*
2  * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved.
3  * Copyright 2013, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include <new>
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdarg.h>
13 
14 #include <Application.h>
15 #include <Button.h>
16 #include <File.h>
17 #include <FindDirectory.h>
18 #include <LayoutBuilder.h>
19 #include <ListView.h>
20 #include <Path.h>
21 #include <Screen.h>
22 #include <ScrollView.h>
23 
24 #include "MessageCodes.h"
25 #include "SettingsManager.h"
26 #include "StartTeamWindow.h"
27 #include "TeamsWindow.h"
28 #include "TeamsListView.h"
29 
30 
31 enum {
32 	MSG_TEAM_SELECTION_CHANGED = 'tesc'
33 };
34 
35 
36 TeamsWindow::TeamsWindow(SettingsManager* settingsManager)
37 	:
38 	BWindow(BRect(100, 100, 500, 250), "Teams", B_DOCUMENT_WINDOW,
39 		B_ASYNCHRONOUS_CONTROLS),
40 	fTeamsListView(NULL),
41 	fStartTeamWindow(NULL),
42 	fAttachTeamButton(NULL),
43 	fCreateTeamButton(NULL),
44 	fSettingsManager(settingsManager)
45 {
46 	team_info info;
47 	get_team_info(B_CURRENT_TEAM, &info);
48 	fCurrentTeam = info.team;
49 }
50 
51 
52 TeamsWindow::~TeamsWindow()
53 {
54 	BMessenger(fStartTeamWindow).SendMessage(B_QUIT_REQUESTED);
55 }
56 
57 
58 /*static*/ TeamsWindow*
59 TeamsWindow::Create(SettingsManager* settingsManager)
60 {
61 	TeamsWindow* self = new TeamsWindow(settingsManager);
62 
63 	try {
64 		self->_Init();
65 	} catch (...) {
66 		delete self;
67 		throw;
68 	}
69 
70 	return self;
71 }
72 
73 
74 void
75 TeamsWindow::Zoom(BPoint, float, float)
76 {
77 	BSize preferredSize = fTeamsListView->PreferredSize();
78 	ResizeBy(preferredSize.Width() - Bounds().Width(),
79 		0.0);
80 
81 	// if the new size would extend us past the screen border,
82 	// move sufficiently to the left to bring us back within the bounds
83 	// + a bit of extra margin so we're not flush against the edge.
84 	BScreen screen;
85 	float offset = screen.Frame().right - Frame().right;
86 	if (offset < 0)
87 		MoveBy(offset - 5.0, 0.0);
88 }
89 
90 
91 void
92 TeamsWindow::MessageReceived(BMessage* message)
93 {
94 	switch (message->what) {
95 		case MSG_START_NEW_TEAM:
96 		{
97 			BMessenger messenger(fStartTeamWindow);
98 			if (!messenger.IsValid()) {
99 				fStartTeamWindow = StartTeamWindow::Create();
100 				if (fStartTeamWindow == NULL)
101 					break;
102 			}
103 
104 			fStartTeamWindow->Show();
105 			break;
106 		}
107 
108 		case MSG_DEBUG_THIS_TEAM:
109 		{
110 			TeamRow* row = dynamic_cast<TeamRow*>(
111 				fTeamsListView->CurrentSelection());
112 			if (row != NULL) {
113 				BMessage message(MSG_DEBUG_THIS_TEAM);
114 				message.AddInt32("team", row->TeamID());
115 				be_app_messenger.SendMessage(&message);
116 			}
117 			break;
118 		}
119 
120 		case MSG_TEAM_SELECTION_CHANGED:
121 		{
122 			TeamRow* row = dynamic_cast<TeamRow*>(
123 				fTeamsListView->CurrentSelection());
124 			bool enabled = false;
125 			if (row != NULL) {
126 				team_id id = row->TeamID();
127 				if (id != fCurrentTeam && id != B_SYSTEM_TEAM)
128 					enabled = true;
129 			}
130 
131 			fAttachTeamButton->SetEnabled(enabled);
132 			break;
133 		}
134 
135 		default:
136 			BWindow::MessageReceived(message);
137 			break;
138 	}
139 }
140 
141 
142 bool
143 TeamsWindow::QuitRequested()
144 {
145 	_SaveSettings();
146 
147 	be_app_messenger.SendMessage(MSG_TEAMS_WINDOW_CLOSED);
148 	return true;
149 }
150 
151 
152 // #pragma mark --
153 
154 
155 void
156 TeamsWindow::_Init()
157 {
158 	BMessage settings;
159 	_LoadSettings(settings);
160 
161 	BRect frame;
162 	if (settings.FindRect("teams window frame", &frame) == B_OK) {
163 		MoveTo(frame.LeftTop());
164 		ResizeTo(frame.Width(), frame.Height());
165 	}
166 
167 	BLayoutBuilder::Group<>(this, B_VERTICAL)
168 		.Add(fTeamsListView = new TeamsListView("TeamsList", fCurrentTeam))
169 		.SetInsets(1.0f, 1.0f, 1.0f, 1.0f)
170 		.AddGroup(B_HORIZONTAL)
171 			.SetInsets(B_USE_DEFAULT_SPACING)
172 			.Add(fAttachTeamButton = new BButton("Attach", new BMessage(
173 						MSG_DEBUG_THIS_TEAM)))
174 			.Add(fCreateTeamButton = new BButton("Start new team"
175 					B_UTF8_ELLIPSIS, new BMessage(MSG_START_NEW_TEAM)))
176 			.End()
177 		.End();
178 
179 	fTeamsListView->SetInvocationMessage(new BMessage(MSG_DEBUG_THIS_TEAM));
180 	fTeamsListView->SetSelectionMessage(new BMessage(
181 			MSG_TEAM_SELECTION_CHANGED));
182 
183 	fAttachTeamButton->SetEnabled(false);
184 }
185 
186 
187 status_t
188 TeamsWindow::_OpenSettings(BFile& file, uint32 mode)
189 {
190 	BPath path;
191 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
192 		return B_ERROR;
193 
194 	path.Append("Debugger settings");
195 
196 	return file.SetTo(path.Path(), mode);
197 }
198 
199 
200 status_t
201 TeamsWindow::_LoadSettings(BMessage& settings)
202 {
203 	BFile file;
204 	status_t status = _OpenSettings(file, B_READ_ONLY);
205 	if (status < B_OK)
206 		return status;
207 
208 	return settings.Unflatten(&file);
209 }
210 
211 
212 status_t
213 TeamsWindow::_SaveSettings()
214 {
215 	BFile file;
216 	status_t status = _OpenSettings(file,
217 		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
218 
219 	if (status < B_OK)
220 		return status;
221 
222 	BMessage settings('hdbg');
223 	status = settings.AddRect("teams window frame", Frame());
224 	if (status != B_OK)
225 		return status;
226 
227 	if (status == B_OK)
228 		status = settings.Flatten(&file);
229 
230 	return status;
231 }
232