1 /*****************************************************************************/ 2 // SGIView 3 // Adopted by Stephan Aßmus, <stippi@yellowbites.com> 4 // from TIFFView written by 5 // Picking the compression method added by Stephan Aßmus, <stippi@yellowbites.com> 6 // 7 // SGIView.cpp 8 // 9 // This BView based object displays information about the SGITranslator. 10 // 11 // 12 // Copyright (c) 2003 OpenBeOS Project 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining a 15 // copy of this software and associated documentation files (the "Software"), 16 // to deal in the Software without restriction, including without limitation 17 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 18 // and/or sell copies of the Software, and to permit persons to whom the 19 // Software is furnished to do so, subject to the following conditions: 20 // 21 // The above copyright notice and this permission notice shall be included 22 // in all copies or substantial portions of the Software. 23 // 24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 30 // DEALINGS IN THE SOFTWARE. 31 /*****************************************************************************/ 32 33 #include <stdio.h> 34 #include <string.h> 35 36 #include <MenuBar.h> 37 #include <MenuField.h> 38 #include <MenuItem.h> 39 #include <PopUpMenu.h> 40 #include <Window.h> 41 42 #include "SGIImage.h" 43 #include "SGITranslator.h" 44 #include "SGIView.h" 45 46 const char* author = "Stephan Aßmus, <stippi@yellowbites.com>"; 47 48 // add_menu_item 49 void 50 add_menu_item(BMenu* menu, 51 uint32 compression, 52 const char* label, 53 uint32 currentCompression) 54 { 55 BMessage* message = new BMessage(SGIView::MSG_COMPRESSION_CHANGED); 56 message->AddInt32("value", compression); 57 BMenuItem* item = new BMenuItem(label, message); 58 item->SetMarked(currentCompression == compression); 59 menu->AddItem(item); 60 } 61 62 // --------------------------------------------------------------- 63 // Constructor 64 // 65 // Sets up the view settings 66 // 67 // Preconditions: 68 // 69 // Parameters: 70 // 71 // Postconditions: 72 // 73 // Returns: 74 // --------------------------------------------------------------- 75 SGIView::SGIView(const BRect &frame, const char *name, 76 uint32 resize, uint32 flags, TranslatorSettings *settings) 77 : BView(frame, name, resize, flags), 78 fSettings(settings) 79 { 80 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 81 SetLowColor(ViewColor()); 82 83 BPopUpMenu* menu = new BPopUpMenu("pick compression"); 84 85 uint32 currentCompression = fSettings->SetGetInt32(SGI_SETTING_COMPRESSION); 86 // create the menu items with the various compression methods 87 add_menu_item(menu, SGI_COMP_NONE, "None", currentCompression); 88 // menu->AddSeparatorItem(); 89 add_menu_item(menu, SGI_COMP_RLE, "RLE", currentCompression); 90 91 // DON'T turn this on, it's so slow that I didn't wait long enough 92 // the one time I tested this. So I don't know if the code even works. 93 // Supposedly, this would look for an already written scanline, and 94 // modify the scanline tables so that the current row is not written 95 // at all... 96 97 // add_menu_item(menu, SGI_COMP_ARLE, "Agressive RLE", currentCompression); 98 99 BRect menuFrame = Bounds(); 100 menuFrame.bottom = menuFrame.top + menu->Bounds().Height(); 101 fCompressionMF = new BMenuField(menuFrame, "compression", 102 "Use Compression:", menu, true/*, 103 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP*/); 104 if (fCompressionMF->MenuBar()) 105 fCompressionMF->MenuBar()->ResizeToPreferred(); 106 fCompressionMF->ResizeToPreferred(); 107 108 // figure out where the text ends 109 font_height fh; 110 be_bold_font->GetHeight(&fh); 111 float xbold, ybold; 112 xbold = fh.descent + 1; 113 ybold = fh.ascent + fh.descent * 2 + fh.leading; 114 115 font_height plainh; 116 be_plain_font->GetHeight(&plainh); 117 float yplain; 118 yplain = plainh.ascent + plainh.descent * 2 + plainh.leading; 119 120 // position the menu field below all the text we draw in Draw() 121 BPoint textOffset(0.0, yplain * 2 + ybold); 122 fCompressionMF->MoveTo(textOffset); 123 124 AddChild(fCompressionMF); 125 126 ResizeToPreferred(); 127 } 128 129 // --------------------------------------------------------------- 130 // Destructor 131 // 132 // Does nothing 133 // 134 // Preconditions: 135 // 136 // Parameters: 137 // 138 // Postconditions: 139 // 140 // Returns: 141 // --------------------------------------------------------------- 142 SGIView::~SGIView() 143 { 144 fSettings->Release(); 145 } 146 147 // --------------------------------------------------------------- 148 // MessageReceived 149 // 150 // Handles state changes of the Compression menu field 151 // 152 // Preconditions: 153 // 154 // Parameters: area, not used 155 // 156 // Postconditions: 157 // 158 // Returns: 159 // --------------------------------------------------------------- 160 void 161 SGIView::MessageReceived(BMessage* message) 162 { 163 switch (message->what) { 164 case MSG_COMPRESSION_CHANGED: { 165 int32 value; 166 if (message->FindInt32("value", &value) >= B_OK) { 167 fSettings->SetGetInt32(SGI_SETTING_COMPRESSION, &value); 168 fSettings->SaveSettings(); 169 } 170 fCompressionMF->ResizeToPreferred(); 171 break; 172 } 173 default: 174 BView::MessageReceived(message); 175 } 176 } 177 178 // --------------------------------------------------------------- 179 // AllAttached 180 // 181 // sets the target for the controls controlling the configuration 182 // 183 // Preconditions: 184 // 185 // Parameters: area, not used 186 // 187 // Postconditions: 188 // 189 // Returns: 190 // --------------------------------------------------------------- 191 void 192 SGIView::AllAttached() 193 { 194 fCompressionMF->Menu()->SetTargetForItems(this); 195 fCompressionMF->ResizeToPreferred(); 196 fCompressionMF->SetDivider(fCompressionMF->StringWidth(fCompressionMF->Label()) + 3); 197 } 198 199 // --------------------------------------------------------------- 200 // AttachedToWindow 201 // 202 // hack to make the window recognize our size 203 // 204 // Preconditions: 205 // 206 // Parameters: area, not used 207 // 208 // Postconditions: 209 // 210 // Returns: 211 // --------------------------------------------------------------- 212 void 213 SGIView::AttachedToWindow() 214 { 215 // Hack for DataTranslations which doesn't resize visible area to requested by view 216 // which makes some parts of bigger than usual translationviews out of visible area 217 // so if it was loaded to DataTranslations resize window if needed 218 BWindow *window = Window(); 219 if (!strcmp(window->Name(), "DataTranslations")) { 220 BView *view = Parent(); 221 if (view) { 222 BRect frame = view->Frame(); 223 float x, y; 224 GetPreferredSize(&x, &y); 225 if (frame.Width() < x || (frame.Height() - 48) < y) { 226 x -= frame.Width(); 227 y -= frame.Height() - 48; 228 if (x < 0) x = 0; 229 if (y < 0) y = 0; 230 231 // DataTranslations has main view called "Background" 232 // change it's resizing mode so it will always resize with window 233 // also make sure view will be redrawed after resize 234 view = window->FindView("Background"); 235 if (view) { 236 view->SetResizingMode(B_FOLLOW_ALL); 237 view->SetFlags(B_FULL_UPDATE_ON_RESIZE); 238 } 239 240 // The same with "Info..." button, except redrawing, which isn't needed 241 view = window->FindView("Info" B_UTF8_ELLIPSIS); 242 if (view) 243 view->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 244 245 window->ResizeBy( x, y); 246 } 247 } 248 } 249 } 250 251 // --------------------------------------------------------------- 252 // Draw 253 // 254 // Draws information about the SGITranslator to this view. 255 // 256 // Preconditions: 257 // 258 // Parameters: area, not used 259 // 260 // Postconditions: 261 // 262 // Returns: 263 // --------------------------------------------------------------- 264 void 265 SGIView::Draw(BRect area) 266 { 267 SetFont(be_bold_font); 268 font_height fh; 269 GetFontHeight(&fh); 270 float xbold, ybold; 271 xbold = fh.descent + 1; 272 ybold = fh.ascent + fh.descent * 2 + fh.leading; 273 274 const char* text = "SGI Image Translator"; 275 DrawString(text, BPoint(xbold, ybold)); 276 277 SetFont(be_plain_font); 278 font_height plainh; 279 GetFontHeight(&plainh); 280 float yplain; 281 yplain = plainh.ascent + plainh.descent * 2 + plainh.leading; 282 283 char detail[100]; 284 sprintf(detail, "Version %d.%d.%d %s", 285 static_cast<int>(B_TRANSLATION_MAJOR_VERSION(SGI_TRANSLATOR_VERSION)), 286 static_cast<int>(B_TRANSLATION_MINOR_VERSION(SGI_TRANSLATOR_VERSION)), 287 static_cast<int>(B_TRANSLATION_REVISION_VERSION(SGI_TRANSLATOR_VERSION)), 288 __DATE__); 289 DrawString(detail, BPoint(xbold, yplain + ybold)); 290 291 BPoint offset = fCompressionMF->Frame().LeftBottom(); 292 offset.x += xbold; 293 offset.y += 2 * ybold; 294 295 text = "written by:"; 296 DrawString(text, offset); 297 offset.y += ybold; 298 299 DrawString(author, offset); 300 offset.y += 2 * ybold; 301 302 text = "based on GIMP SGI plugin v1.5:"; 303 DrawString(text, offset); 304 offset.y += ybold; 305 306 DrawString(kSGICopyright, offset); 307 } 308 309 // --------------------------------------------------------------- 310 // Draw 311 // 312 // calculated the preferred size of this view 313 // 314 // Preconditions: 315 // 316 // Parameters: width and height 317 // 318 // Postconditions: 319 // 320 // Returns: in width and height, the preferred size... 321 // --------------------------------------------------------------- 322 void 323 SGIView::GetPreferredSize(float* width, float* height) 324 { 325 *width = fCompressionMF->Bounds().Width(); 326 // look at the two biggest strings 327 float width1 = StringWidth(kSGICopyright) + 15.0; 328 if (*width < width1) 329 *width = width1; 330 float width2 = be_plain_font->StringWidth(author) + 15.0; 331 if (*width < width2) 332 *width = width2; 333 334 font_height fh; 335 be_bold_font->GetHeight(&fh); 336 float ybold = fh.ascent + fh.descent * 2 + fh.leading; 337 338 *height = fCompressionMF->Bounds().bottom + 7 * ybold; 339 } 340