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