xref: /haiku/src/apps/showimage/PrintOptionsWindow.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 /*****************************************************************************/
2 // PrintOptionsWindow
3 // Written by Michael Pfeiffer
4 //
5 // PrintOptionsWindow.cpp
6 //
7 //
8 // Copyright (c) 2003 OpenBeOS Project
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 /*****************************************************************************/
28 
29 #include <Box.h>
30 #include <Button.h>
31 #include <String.h>
32 #include <stdio.h> // for sprintf
33 #include <stdlib.h> // for atof
34 
35 #include "PrintOptionsWindow.h"
36 #include "ShowImageConstants.h"
37 
38 PrintOptions::PrintOptions()
39 	: fOption(kFitToPage)
40 	, fZoomFactor(1.0)
41 	, fDPI(72.0)
42 	, fWidth(1024 / 72.0)
43 	, fHeight(768 / 72.0)
44 {
45 }
46 
47 void
48 PrintOptions::SetBounds(BRect rect)
49 {
50 	fBounds = rect;
51 }
52 
53 void
54 PrintOptions::SetZoomFactor(float f)
55 {
56 	fZoomFactor = f;
57 	fDPI = 72.0 / fZoomFactor;
58 }
59 
60 void
61 PrintOptions::SetDPI(float dpi)
62 {
63 	fDPI = dpi;
64 	fZoomFactor = 72.0 / dpi;
65 }
66 
67 void
68 PrintOptions::SetWidth(float w)
69 {
70 	fWidth = w;
71 	fHeight = (fBounds.Height()+1) * w / (fBounds.Width()+1);
72 }
73 
74 void
75 PrintOptions::SetHeight(float h)
76 {
77 	fWidth = (fBounds.Width()+1) * h / (fBounds.Height()+1);
78 	fHeight = h;
79 }
80 
81 PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions *options, BWindow* listener)
82 	: BWindow(BRect(at.x, at.y, at.x+300, at.y+200), "Print Options",
83 	B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
84 	B_NOT_ZOOMABLE | B_NOT_RESIZABLE)
85 	, fPrintOptions(options)
86 	, fCurrentOptions(*options)
87 	, fListener(listener)
88 	, fStatus(B_ERROR)
89 {
90 	AddToSubset(listener);
91 	Setup();
92 	Show();
93 }
94 
95 PrintOptionsWindow::~PrintOptionsWindow()
96 {
97 	BMessage msg(MSG_PRINT);
98 	msg.AddInt32("status", fStatus);
99 	fListener.SendMessage(&msg);
100 }
101 
102 BRadioButton*
103 PrintOptionsWindow::AddRadioButton(BView* view, BPoint& at, const char* name, const char* label, uint32 what, bool selected)
104 {
105 	BRect rect(0, 0, 100, 20);
106 	BRadioButton* button;
107 	rect.OffsetBy(at);
108 	button = new BRadioButton(rect, name, label, new BMessage(what));
109 	view->AddChild(button);
110 	button->ResizeToPreferred();
111 	at.y += button->Bounds().Height() + kLineSkip;
112 	button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF);
113 	return button;
114 }
115 
116 BTextControl*
117 PrintOptionsWindow::AddTextControl(BView* view, BPoint& at, const char* name, const char* label, float value, float divider, uint32 what)
118 {
119 	BRect rect(0, 0, divider + 45, 20);
120 	BTextControl* text;
121 	rect.OffsetBy(at);
122 	text = new BTextControl(rect, name, label, "", new BMessage(what));
123 	view->AddChild(text);
124 	text->SetModificationMessage(new BMessage(what));
125 	text->SetDivider(divider);
126 	text->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT);
127 	SetValue(text, value);
128 	at.y += text->Bounds().Height() + kLineSkip;
129 	return text;
130 }
131 
132 void
133 PrintOptionsWindow::Setup()
134 {
135 	BRect rect(Bounds());
136 	BPoint at(kIndent, kIndent), textAt;
137 	BString value;
138 	enum PrintOptions::Option op = fCurrentOptions.Option();
139 	BRadioButton* rb;
140 	BBox* line;
141 	BButton* button;
142 
143 	BBox *panel = new BBox(rect, "top_panel", B_FOLLOW_ALL,
144 		B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
145 		B_PLAIN_BORDER);
146 	AddChild(panel);
147 
148 	AddRadioButton(panel, at, "fit_to_page", "Fit Image to Page", kMsgFitToPageSelected, op == PrintOptions::kFitToPage);
149 	textAt = at;
150 	rb = AddRadioButton(panel, at, "zoom_factor", "Zoom Factor in %: ", kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor);
151 	textAt.x = rb->Bounds().right + 5;
152 	fZoomFactor = AddTextControl(panel, textAt, "zoom_factor_text", "", fCurrentOptions.ZoomFactor()*100, 0, kMsgZoomFactorChanged);
153 
154 	textAt = at;
155 	rb = AddRadioButton(panel, at, "dpi", "DPI: ", kMsgDPISelected, op == PrintOptions::kDPI);
156 	textAt.x = rb->Bounds().right + 5;
157 	fDPI = AddTextControl(panel, textAt, "dpi_text", "", fCurrentOptions.DPI(), 0, kMsgDPIChanged);
158 
159 	rb = AddRadioButton(panel, at, "width_and_height", "Resize To (in 1/72 Inches):", kMsgWidthAndHeightSelected, op == PrintOptions::kWidth || op == PrintOptions::kHeight);
160 	at.x += 15;
161 	textAt = at;
162 	fWidth = AddTextControl(panel, textAt, "width", "Width: ", fCurrentOptions.Width(), 40, kMsgWidthChanged);
163 	textAt = at;
164 	textAt.x += fWidth->Bounds().Width() + 5;
165 	fHeight = AddTextControl(panel, textAt, "height", "Height: ", fCurrentOptions.Height(), 40, kMsgHeightChanged);
166 
167 	at.x = 0;
168 	at.y = textAt.y;
169 	line = new BBox(BRect(rect.left+3, at.y, rect.right-3, at.y + 1), NULL,
170 		B_FOLLOW_LEFT | B_FOLLOW_TOP);
171 	panel->AddChild(line);
172 
173 	at.y += 10;
174 	rect.OffsetBy(at);
175 	button = new BButton(rect, "job setup", "Job Setup", new BMessage(kMsgJobSetup));
176 	panel->AddChild(button);
177 	button->ResizeToPreferred();
178 
179 	SetDefaultButton(button);
180 
181 	// resize window
182 	ResizeTo(fHeight->Frame().right + kIndent, button->Frame().bottom + kIndent);
183 
184 	// center button
185 	button->MoveTo((Bounds().Width()-button->Bounds().Width())/2, button->Frame().top);
186 }
187 
188 enum PrintOptions::Option
189 PrintOptionsWindow::MsgToOption(uint32 what) {
190 	switch (what) {
191 		case kMsgFitToPageSelected: return PrintOptions::kFitToPage;
192 		case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor;
193 		case kMsgDPISelected: return PrintOptions::kDPI;
194 		case kMsgWidthAndHeightSelected: return PrintOptions::kWidth;
195 	}
196 	return PrintOptions::kFitToPage;
197 }
198 
199 bool
200 PrintOptionsWindow::GetValue(BTextControl* text, float* value)
201 {
202 	*value = atof(text->Text());
203 	return true;
204 }
205 
206 void
207 PrintOptionsWindow::SetValue(BTextControl* text, float value)
208 {
209 	BMessage* msg;
210 	char s[80];
211 	sprintf(s, "%0.0f", value);
212 	// prevent sending a notification when text is set
213 	msg = new BMessage(*text->ModificationMessage());
214 	text->SetModificationMessage(NULL);
215 	text->SetText(s);
216 	text->SetModificationMessage(msg);
217 }
218 
219 void
220 PrintOptionsWindow::MessageReceived(BMessage* msg)
221 {
222 	float value;
223 	switch (msg->what) {
224 		case kMsgFitToPageSelected:
225 		case kMsgZoomFactorSelected:
226 		case kMsgDPISelected:
227 		case kMsgWidthAndHeightSelected:
228 			fCurrentOptions.SetOption(MsgToOption(msg->what));
229 			break;
230 
231 		case kMsgZoomFactorChanged:
232 			if (GetValue(fZoomFactor, &value) && fCurrentOptions.ZoomFactor() != value) {
233 				fCurrentOptions.SetZoomFactor(value/100);
234 				SetValue(fDPI, fCurrentOptions.DPI());
235 			}
236 			break;
237 		case kMsgDPIChanged:
238 			if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) {
239 				fCurrentOptions.SetDPI(value);
240 				SetValue(fZoomFactor, 100*fCurrentOptions.ZoomFactor());
241 			}
242 			break;
243 		case kMsgWidthChanged:
244 			if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) {
245 				fCurrentOptions.SetWidth(value);
246 				SetValue(fHeight, fCurrentOptions.Height());
247 			}
248 			break;
249 		case kMsgHeightChanged:
250 			if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) {
251 				fCurrentOptions.SetHeight(value);
252 				SetValue(fWidth, fCurrentOptions.Width());
253 			}
254 			break;
255 
256 		case kMsgJobSetup:
257 			*fPrintOptions = fCurrentOptions;
258 			fStatus = B_OK;
259 			PostMessage(B_QUIT_REQUESTED);
260 			break;
261 
262 		default:
263 			BWindow::MessageReceived(msg);
264 	}
265 }
266