xref: /haiku/src/apps/showimage/PrintOptionsWindow.cpp (revision b289aaf66bbf6e173aa90fa194fc256965f1b34d)
1 /*
2  * Copyright 2003-2009, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Pfeiffer, laplace@haiku-os.org
7  */
8 
9 #include "PrintOptionsWindow.h"
10 
11 #include <stdio.h> // for sprintf
12 #include <stdlib.h> // for atof
13 
14 #include <Box.h>
15 #include <Button.h>
16 #include <Catalog.h>
17 #include <ControlLook.h>
18 #include <GroupLayoutBuilder.h>
19 #include <GridLayoutBuilder.h>
20 #include <Locale.h>
21 #include <LayoutBuilder.h>
22 #include <String.h>
23 
24 #include "ShowImageConstants.h"
25 
26 
27 PrintOptions::PrintOptions()
28 	:
29 	fOption(kFitToPage),
30 	fZoomFactor(1.0),
31 	fDPI(72.0),
32 	fWidth(1024 / 72.0),
33 	fHeight(768 / 72.0)
34 {
35 }
36 
37 
38 void
39 PrintOptions::SetBounds(BRect rect)
40 {
41 	fBounds = rect;
42 }
43 
44 
45 void
46 PrintOptions::SetZoomFactor(float f)
47 {
48 	fZoomFactor = f;
49 	fDPI = 72.0 / fZoomFactor;
50 }
51 
52 
53 void
54 PrintOptions::SetDPI(float dpi)
55 {
56 	fDPI = dpi;
57 	fZoomFactor = 72.0 / dpi;
58 }
59 
60 
61 void
62 PrintOptions::SetWidth(float w)
63 {
64 	fWidth = w;
65 	fHeight = (fBounds.Height() + 1) * w / (fBounds.Width() + 1);
66 }
67 
68 
69 void
70 PrintOptions::SetHeight(float h)
71 {
72 	fWidth = (fBounds.Width()+1) * h / (fBounds.Height()+1);
73 	fHeight = h;
74 }
75 
76 
77 #undef TR_CONTEXT
78 #define TR_CONTEXT "PrintOptionsWindow"
79 
80 PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions* options,
81 	BWindow* listener)
82 	:
83 	BWindow(BRect(at.x, at.y, at.x + 300, at.y + 200), TR("Print options"),
84 		B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
85 		B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
86 	fPrintOptions(options),
87 	fCurrentOptions(*options),
88 	fListener(listener),
89 	fStatus(B_ERROR)
90 {
91 	AddToSubset(listener);
92 	Setup();
93 	Show();
94 }
95 
96 
97 PrintOptionsWindow::~PrintOptionsWindow()
98 {
99 	BMessage msg(MSG_PRINT);
100 	msg.AddInt32("status", fStatus);
101 	fListener.SendMessage(&msg);
102 }
103 
104 
105 BRadioButton*
106 PrintOptionsWindow::AddRadioButton(const char* name,
107 	const char* label, uint32 what, bool selected)
108 {
109 	BRadioButton* button;
110 	button = new BRadioButton(name, label, new BMessage(what));
111 	button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF);
112 	return button;
113 }
114 
115 
116 BTextControl*
117 PrintOptionsWindow::AddTextControl(const char* name,
118 	const char* label, float value, uint32 what)
119 {
120 	BTextControl* text;
121 	text = new BTextControl(name, label, "", new BMessage(what));
122 	text->SetModificationMessage(new BMessage(what));
123 	SetValue(text, value);
124 	return text;
125 }
126 
127 
128 void
129 PrintOptionsWindow::Setup()
130 {
131 	BString value;
132 	enum PrintOptions::Option op = fCurrentOptions.Option();
133 	BRadioButton* rbFit;
134 	BRadioButton* rbZoom;
135 	BRadioButton* rbDpi;
136 	BRadioButton* rbResize;
137 	BBox* line;
138 	BButton* button;
139 
140 	rbFit = AddRadioButton("fit_to_page", TR("Fit image to page"),
141 		kMsgFitToPageSelected, op == PrintOptions::kFitToPage);
142 
143 	rbZoom = AddRadioButton("zoom_factor", TR("Zoom factor in %:"),
144 		kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor);
145 
146 	fZoomFactor = AddTextControl("zoom_factor_text", "",
147 		fCurrentOptions.ZoomFactor() * 100, kMsgZoomFactorChanged);
148 
149 	rbDpi = AddRadioButton("dpi", TR("DPI:"), kMsgDPISelected,
150 		op == PrintOptions::kDPI);
151 
152 	fDPI = AddTextControl("dpi_text", "", fCurrentOptions.DPI(),
153 		kMsgDPIChanged);
154 
155 	rbResize = AddRadioButton("width_and_height",
156 		TR("Resize to (in 1/72 inches):"), kMsgWidthAndHeightSelected,
157 		op == PrintOptions::kWidth || op == PrintOptions::kHeight);
158 
159 	fWidth = AddTextControl("width", TR("Width:"),
160 		fCurrentOptions.Width(), kMsgWidthChanged);
161 
162 	fHeight = AddTextControl("height", TR("Height: "),
163 		fCurrentOptions.Height(), kMsgHeightChanged);
164 
165 	line = new BBox(B_EMPTY_STRING, B_WILL_DRAW | B_FRAME_EVENTS,
166 		B_FANCY_BORDER);
167 	line->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
168 
169 	button = new BButton("job setup", TR("Job setup"),
170 		new BMessage(kMsgJobSetup));
171 	SetDefaultButton(button);
172 
173 	const float spacing = be_control_look->DefaultItemSpacing();
174 
175 	SetLayout(new BGroupLayout(B_HORIZONTAL));
176 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
177 		.Add(BGridLayoutBuilder()
178 				.Add(rbFit, 0, 0)
179 				.Add(rbZoom, 0, 1)
180 				.Add(fZoomFactor, 1, 1)
181 				.Add(rbDpi, 0, 2)
182 				.Add(fDPI, 1, 2)
183 				.Add(rbResize, 0, 3)
184 				)
185 		.AddGroup(B_HORIZONTAL, spacing)
186 			.Add(fWidth)
187 			.Add(fHeight)
188 			.AddGlue()
189 			.SetInsets(22, 0, 0, 0)
190 		.End()
191 		.Add(line)
192 		.AddGroup(B_HORIZONTAL, 0)
193 			.Add(button)
194 		.End()
195 		.SetInsets(spacing, spacing, spacing, spacing)
196 	);
197 }
198 
199 
200 enum PrintOptions::Option
201 PrintOptionsWindow::MsgToOption(uint32 what)
202 {
203 	switch (what) {
204 		case kMsgFitToPageSelected: return PrintOptions::kFitToPage;
205 		case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor;
206 		case kMsgDPISelected: return PrintOptions::kDPI;
207 		case kMsgWidthAndHeightSelected: return PrintOptions::kWidth;
208 	}
209 	return PrintOptions::kFitToPage;
210 }
211 
212 
213 bool
214 PrintOptionsWindow::GetValue(BTextControl* text, float* value)
215 {
216 	*value = atof(text->Text());
217 	return true;
218 }
219 
220 
221 void
222 PrintOptionsWindow::SetValue(BTextControl* text, float value)
223 {
224 	BMessage* msg;
225 	char s[80];
226 	sprintf(s, "%0.0f", value);
227 	// prevent sending a notification when text is set
228 	msg = new BMessage(*text->ModificationMessage());
229 	text->SetModificationMessage(NULL);
230 	text->SetText(s);
231 	text->SetModificationMessage(msg);
232 }
233 
234 
235 void
236 PrintOptionsWindow::MessageReceived(BMessage* msg)
237 {
238 	float value;
239 	switch (msg->what) {
240 		case kMsgFitToPageSelected:
241 		case kMsgZoomFactorSelected:
242 		case kMsgDPISelected:
243 		case kMsgWidthAndHeightSelected:
244 			fCurrentOptions.SetOption(MsgToOption(msg->what));
245 			break;
246 
247 		case kMsgZoomFactorChanged:
248 			if (GetValue(fZoomFactor, &value)
249 				&& fCurrentOptions.ZoomFactor() != value) {
250 				fCurrentOptions.SetZoomFactor(value / 100);
251 				SetValue(fDPI, fCurrentOptions.DPI());
252 			}
253 			break;
254 		case kMsgDPIChanged:
255 			if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) {
256 				fCurrentOptions.SetDPI(value);
257 				SetValue(fZoomFactor, 100 * fCurrentOptions.ZoomFactor());
258 			}
259 			break;
260 		case kMsgWidthChanged:
261 			if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) {
262 				fCurrentOptions.SetWidth(value);
263 				SetValue(fHeight, fCurrentOptions.Height());
264 			}
265 			break;
266 		case kMsgHeightChanged:
267 			if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) {
268 				fCurrentOptions.SetHeight(value);
269 				SetValue(fWidth, fCurrentOptions.Width());
270 			}
271 			break;
272 
273 		case kMsgJobSetup:
274 			*fPrintOptions = fCurrentOptions;
275 			fStatus = B_OK;
276 			PostMessage(B_QUIT_REQUESTED);
277 			break;
278 
279 		default:
280 			BWindow::MessageReceived(msg);
281 	}
282 }
283 
284