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 <String.h> 17 18 #include "ShowImageConstants.h" 19 20 21 PrintOptions::PrintOptions() 22 : 23 fOption(kFitToPage), 24 fZoomFactor(1.0), 25 fDPI(72.0), 26 fWidth(1024/72.0), 27 fHeight(768/72.0) 28 { 29 } 30 31 32 void 33 PrintOptions::SetBounds(BRect rect) 34 { 35 fBounds = rect; 36 } 37 38 39 void 40 PrintOptions::SetZoomFactor(float f) 41 { 42 fZoomFactor = f; 43 fDPI = 72.0 / fZoomFactor; 44 } 45 46 47 void 48 PrintOptions::SetDPI(float dpi) 49 { 50 fDPI = dpi; 51 fZoomFactor = 72.0 / dpi; 52 } 53 54 55 void 56 PrintOptions::SetWidth(float w) 57 { 58 fWidth = w; 59 fHeight = (fBounds.Height() + 1) * w / (fBounds.Width() + 1); 60 } 61 62 63 void 64 PrintOptions::SetHeight(float h) 65 { 66 fWidth = (fBounds.Width()+1) * h / (fBounds.Height()+1); 67 fHeight = h; 68 } 69 70 71 PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions *options, 72 BWindow* listener) 73 : 74 BWindow(BRect(at.x, at.y, at.x + 300, at.y + 200), "Print options", 75 B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL, 76 B_NOT_ZOOMABLE | B_NOT_RESIZABLE), 77 fPrintOptions(options), 78 fCurrentOptions(*options), 79 fListener(listener), 80 fStatus(B_ERROR) 81 { 82 AddToSubset(listener); 83 Setup(); 84 Show(); 85 } 86 87 88 PrintOptionsWindow::~PrintOptionsWindow() 89 { 90 BMessage msg(MSG_PRINT); 91 msg.AddInt32("status", fStatus); 92 fListener.SendMessage(&msg); 93 } 94 95 96 BRadioButton* 97 PrintOptionsWindow::AddRadioButton(BView* view, BPoint& at, const char* name, 98 const char* label, uint32 what, bool selected) 99 { 100 BRect rect(0, 0, 100, 20); 101 BRadioButton* button; 102 rect.OffsetBy(at); 103 button = new BRadioButton(rect, name, label, new BMessage(what)); 104 view->AddChild(button); 105 button->ResizeToPreferred(); 106 at.y += button->Bounds().Height() + kLineSkip; 107 button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF); 108 return button; 109 } 110 111 112 BTextControl* 113 PrintOptionsWindow::AddTextControl(BView* view, BPoint& at, const char* name, 114 const char* label, float value, float divider, uint32 what) 115 { 116 BRect rect(0, 0, divider + 45, 20); 117 BTextControl* text; 118 rect.OffsetBy(at); 119 text = new BTextControl(rect, name, label, "", new BMessage(what)); 120 view->AddChild(text); 121 text->SetModificationMessage(new BMessage(what)); 122 text->SetDivider(divider); 123 text->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); 124 SetValue(text, value); 125 at.y += text->Bounds().Height() + kLineSkip; 126 return text; 127 } 128 129 130 void 131 PrintOptionsWindow::Setup() 132 { 133 BRect rect(Bounds()); 134 BPoint at(kIndent, kIndent), textAt; 135 BString value; 136 enum PrintOptions::Option op = fCurrentOptions.Option(); 137 BRadioButton* rb; 138 BBox* line; 139 BButton* button; 140 141 BBox *panel = new BBox(rect, "top_panel", B_FOLLOW_ALL, 142 B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP, 143 B_PLAIN_BORDER); 144 AddChild(panel); 145 146 AddRadioButton(panel, at, "fit_to_page", "Fit image to page", 147 kMsgFitToPageSelected, op == PrintOptions::kFitToPage); 148 textAt = at; 149 rb = AddRadioButton(panel, at, "zoom_factor", "Zoom factor in %: ", 150 kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor); 151 textAt.x = rb->Bounds().right + 5; 152 fZoomFactor = AddTextControl(panel, textAt, "zoom_factor_text", "", 153 fCurrentOptions.ZoomFactor()*100, 0, kMsgZoomFactorChanged); 154 155 textAt = at; 156 rb = AddRadioButton(panel, at, "dpi", "DPI: ", kMsgDPISelected, 157 op == PrintOptions::kDPI); 158 textAt.x = rb->Bounds().right + 5; 159 fDPI = AddTextControl(panel, textAt, "dpi_text", "", fCurrentOptions.DPI(), 160 0, kMsgDPIChanged); 161 162 rb = AddRadioButton(panel, at, "width_and_height", 163 "Resize to (in 1/72 inches):", kMsgWidthAndHeightSelected, 164 op == PrintOptions::kWidth || op == PrintOptions::kHeight); 165 at.x += 15; 166 textAt = at; 167 fWidth = AddTextControl(panel, textAt, "width", "Width: ", 168 fCurrentOptions.Width(), 40, kMsgWidthChanged); 169 textAt = at; 170 textAt.x += fWidth->Bounds().Width() + 5; 171 fHeight = AddTextControl(panel, textAt, "height", "Height: ", 172 fCurrentOptions.Height(), 40, kMsgHeightChanged); 173 174 at.x = 0; 175 at.y = textAt.y; 176 line = new BBox(BRect(rect.left+3, at.y, rect.right-3, at.y + 1), NULL, 177 B_FOLLOW_LEFT | B_FOLLOW_TOP); 178 panel->AddChild(line); 179 180 at.y += 10; 181 rect.OffsetBy(at); 182 button = new BButton(rect, "job setup", "Job setup", 183 new BMessage(kMsgJobSetup)); 184 panel->AddChild(button); 185 button->ResizeToPreferred(); 186 187 SetDefaultButton(button); 188 189 // resize window 190 ResizeTo(fHeight->Frame().right + kIndent, button->Frame().bottom + kIndent); 191 192 // center button 193 button->MoveTo((Bounds().Width()-button->Bounds().Width())/2, 194 button->Frame().top); 195 } 196 197 198 enum PrintOptions::Option 199 PrintOptionsWindow::MsgToOption(uint32 what) 200 { 201 switch (what) { 202 case kMsgFitToPageSelected: return PrintOptions::kFitToPage; 203 case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor; 204 case kMsgDPISelected: return PrintOptions::kDPI; 205 case kMsgWidthAndHeightSelected: return PrintOptions::kWidth; 206 } 207 return PrintOptions::kFitToPage; 208 } 209 210 211 bool 212 PrintOptionsWindow::GetValue(BTextControl* text, float* value) 213 { 214 *value = atof(text->Text()); 215 return true; 216 } 217 218 219 void 220 PrintOptionsWindow::SetValue(BTextControl* text, float value) 221 { 222 BMessage* msg; 223 char s[80]; 224 sprintf(s, "%0.0f", value); 225 // prevent sending a notification when text is set 226 msg = new BMessage(*text->ModificationMessage()); 227 text->SetModificationMessage(NULL); 228 text->SetText(s); 229 text->SetModificationMessage(msg); 230 } 231 232 233 void 234 PrintOptionsWindow::MessageReceived(BMessage* msg) 235 { 236 float value; 237 switch (msg->what) { 238 case kMsgFitToPageSelected: 239 case kMsgZoomFactorSelected: 240 case kMsgDPISelected: 241 case kMsgWidthAndHeightSelected: 242 fCurrentOptions.SetOption(MsgToOption(msg->what)); 243 break; 244 245 case kMsgZoomFactorChanged: 246 if (GetValue(fZoomFactor, &value) 247 && fCurrentOptions.ZoomFactor() != value) { 248 fCurrentOptions.SetZoomFactor(value/100); 249 SetValue(fDPI, fCurrentOptions.DPI()); 250 } 251 break; 252 case kMsgDPIChanged: 253 if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) { 254 fCurrentOptions.SetDPI(value); 255 SetValue(fZoomFactor, 100*fCurrentOptions.ZoomFactor()); 256 } 257 break; 258 case kMsgWidthChanged: 259 if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) { 260 fCurrentOptions.SetWidth(value); 261 SetValue(fHeight, fCurrentOptions.Height()); 262 } 263 break; 264 case kMsgHeightChanged: 265 if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) { 266 fCurrentOptions.SetHeight(value); 267 SetValue(fWidth, fCurrentOptions.Width()); 268 } 269 break; 270 271 case kMsgJobSetup: 272 *fPrintOptions = fCurrentOptions; 273 fStatus = B_OK; 274 PostMessage(B_QUIT_REQUESTED); 275 break; 276 277 default: 278 BWindow::MessageReceived(msg); 279 } 280 } 281 282