1//----------------------------------------------------------------------
2//  This software is part of the OpenBeOS distribution and is covered
3//  by the OpenBeOS license.
4//---------------------------------------------------------------------
5
6#include <algobase.h>
7#include <new.h>
8#include <stdio.h>
9#include <string.h>
10
11#include <Button.h>
12#include <DiskScannerAddOn.h>
13#include <Screen.h>
14#include <View.h>
15
16#include "PartitioningDialog.h"
17
18enum {
19	MSG_OK		= 'okay',
20	MSG_CANCEL	= 'cncl',
21};
22
23// constructor
24PartitioningDialog::PartitioningDialog(BRect dialogCenter)
25	: BWindow(BRect(100, 100, 100, 100), "Partitioning parameters",
26			  B_TITLED_WINDOW,
27			  B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE),
28	  fEditor(NULL),
29	  fEditorView(NULL),
30	  fBlocker(-1),
31	  fCancelled(NULL),
32	  fCenter()
33{
34	fBlocker = create_sem(0, "partitioning dialog blocker");
35	// calculate the dialog center point
36	if (!dialogCenter.IsValid())
37		dialogCenter = BScreen().Frame();
38	fCenter = dialogCenter.LeftTop() + dialogCenter.RightBottom();
39	fCenter.x /= 2;
40	fCenter.y /= 2;
41}
42
43// destructor
44PartitioningDialog::~PartitioningDialog()
45{
46	if (fEditorView)
47		fEditorView->RemoveSelf();
48	if (fBlocker >= 0)
49		delete_sem(fBlocker);
50}
51
52// MessageReceived
53void
54PartitioningDialog::MessageReceived(BMessage *message)
55{
56	switch (message->what) {
57		case MSG_OK:
58		{
59			if (fEditor->EditingDone()) {
60				if (fCancelled)
61					*fCancelled = false;
62				Quit();
63			}
64			break;
65		}
66		case MSG_CANCEL:
67			if (fCancelled)
68				*fCancelled = true;
69			Quit();
70			break;
71		default:
72			BWindow::MessageReceived(message);
73			break;
74	}
75}
76
77// QuitRequested
78bool
79PartitioningDialog::QuitRequested()
80{
81	if (fCancelled)
82		*fCancelled = true;
83	return true;
84}
85
86// Go
87status_t
88PartitioningDialog::Go(BDiskScannerParameterEditor *editor, bool *_cancelled)
89{
90	status_t error = _Init(editor);
91	bool wasRun = false;
92	// fire up the window
93	if (error == B_OK) {
94		if (fBlocker >= 0) {
95			sem_id blocker = fBlocker;
96			bool cancelled = true;
97			fCancelled = &cancelled;
98			Show();
99			wasRun = true;
100			acquire_sem(blocker);
101			if (cancelled)
102				error = B_ERROR;
103			if (_cancelled)
104				*_cancelled = cancelled;
105		} else
106			error = fBlocker;
107	}
108	// delete the window if not run
109	if (!wasRun)
110		delete this;
111	return error;
112}
113
114// _Init
115status_t
116PartitioningDialog::_Init(BDiskScannerParameterEditor *editor)
117{
118	status_t error = (editor ? B_OK : B_BAD_VALUE);
119	// set the parameter editor and view
120	if (error == B_OK) {
121		fEditor = editor;
122		fEditorView = editor->View();
123		if (!fEditorView)
124			error = B_ERROR;
125	}
126	// setup views
127	if (error == B_OK) {
128		BView *mainView = new(nothrow) BView(BRect(0, 0, 1, 1), "main",
129											 B_FOLLOW_ALL, 0);
130		BMessage *okMessage = new BMessage(MSG_OK);
131		BMessage *cancelMessage = new BMessage(MSG_CANCEL);
132		BButton *okButton = new (nothrow) BButton(
133			BRect(0, 0, 1, 1), "ok", "OK", okMessage,
134			B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
135		BButton *cancelButton = new (nothrow) BButton(
136			BRect(0, 0, 1, 1), "cancel", "Cancel", cancelMessage,
137			B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
138		if (okMessage && cancelMessage && okButton && cancelButton) {
139			// add the views to the hierarchy
140			mainView->AddChild(fEditorView);
141			mainView->AddChild(okButton);
142			mainView->AddChild(cancelButton);
143			AddChild(mainView);
144			// set the buttons' preferred size
145			float buttonWidth = 0;
146			float buttonHeight = 0;
147			okButton->GetPreferredSize(&buttonWidth, &buttonHeight);
148			okButton->ResizeTo(buttonWidth, buttonHeight);
149			cancelButton->GetPreferredSize(&buttonWidth, &buttonHeight);
150			cancelButton->ResizeTo(buttonWidth, buttonHeight);
151			// setup their positions and sizes
152			int32 hSpacing = 10;
153			int32 vSpacing = 10;
154			BRect editorRect = fEditorView->Bounds();
155			BRect okRect = okButton->Bounds();
156			BRect cancelRect = cancelButton->Bounds();
157			// compute width and size of the main view
158			int32 width = max(editorRect.IntegerWidth() + 1,
159							  okRect.IntegerWidth() + 1 + hSpacing
160							  + cancelRect.IntegerWidth() + 1)
161						  + 2 * hSpacing;
162			int32 height = editorRect.IntegerHeight() + 1
163						   + max(okRect.IntegerHeight(),
164						   		 cancelRect.IntegerHeight()) + 1
165						   + 3 * vSpacing;
166			mainView->ResizeTo(width - 1, height -1);
167			ResizeTo(width - 1, height -1);
168			// set location of the editor view
169			fEditorView->MoveTo((width - editorRect.IntegerWidth() - 1) / 2,
170								vSpacing - 1);
171			fEditorView->ResizeTo(editorRect.Width(), editorRect.Height());
172			// set the location of the buttons
173			float buttonTop = 2 * vSpacing + editorRect.IntegerHeight();
174			float buttonLeft = width - hSpacing - okRect.IntegerWidth();
175			okButton->MoveTo(buttonLeft, buttonTop);
176			buttonLeft -= hSpacing + cancelRect.IntegerWidth();
177			cancelButton->MoveTo(buttonLeft, buttonTop);
178		} else {
179			// cleanup on error
180			error = B_NO_MEMORY;
181			if (!okButton && okMessage)
182				delete okMessage;
183			if (!cancelButton && cancelMessage)
184				delete cancelMessage;
185			delete okButton;
186			delete cancelButton;
187			delete mainView;
188		}
189	}
190	return error;
191}
192
193