1 //////////////////////////////////////////////////////////////////////////////// 2 // 3 // File: GIFView.cpp 4 // 5 // Date: December 1999 6 // 7 // Author: Daniel Switkin 8 // 9 // Copyright 2003 (c) by Daniel Switkin. This file is made publically available 10 // under the BSD license, with the stipulations that this complete header must 11 // remain at the top of the file indefinitely, and credit must be given to the 12 // original author in any about box using this software. 13 // 14 //////////////////////////////////////////////////////////////////////////////// 15 16 // Additional authors: Stephan Aßmus, <superstippi@gmx.de> 17 // Philippe Saint-Pierre, <stpere@gmail.com> 18 // Maxime Simon, <maxime.simon@gmail.com> 19 // John Scipione, <jscipione@gmail.com> 20 21 #include "GIFView.h" 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 26 #include <Box.h> 27 #include <Catalog.h> 28 #include <CheckBox.h> 29 #include <LayoutBuilder.h> 30 #include <MenuField.h> 31 #include <MenuItem.h> 32 #include <PopUpMenu.h> 33 #include <RadioButton.h> 34 #include <SpaceLayoutItem.h> 35 #include <StringView.h> 36 #include <String.h> 37 #include <TextControl.h> 38 39 #include "GIFTranslator.h" 40 #include "SavePalette.h" 41 42 43 #undef B_TRANSLATION_CONTEXT 44 #define B_TRANSLATION_CONTEXT "GIFView" 45 46 47 GIFView::GIFView(TranslatorSettings* settings) 48 : 49 BView("GIFView", B_WILL_DRAW), 50 fSettings(settings) 51 { 52 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 53 54 fTitle = new BStringView("Title", B_TRANSLATE("GIF image translator")); 55 fTitle->SetFont(be_bold_font); 56 57 char version_string[100]; 58 snprintf(version_string, sizeof(version_string), 59 B_TRANSLATE("v%d.%d.%d %s"), 60 int(B_TRANSLATION_MAJOR_VERSION(GIF_TRANSLATOR_VERSION)), 61 int(B_TRANSLATION_MINOR_VERSION(GIF_TRANSLATOR_VERSION)), 62 int(B_TRANSLATION_REVISION_VERSION(GIF_TRANSLATOR_VERSION)), 63 __DATE__); 64 fVersion = new BStringView("Version", version_string); 65 66 const char* copyrightString 67 = "©2003 Daniel Switkin, software@switkin.com"; 68 fCopyright = new BStringView("Copyright", copyrightString); 69 70 // menu fields (Palette & Colors) 71 fWebSafeMI = new BMenuItem(B_TRANSLATE("Websafe"), 72 new BMessage(GV_WEB_SAFE), 0, 0); 73 fBeOSSystemMI = new BMenuItem(B_TRANSLATE("BeOS system"), 74 new BMessage(GV_BEOS_SYSTEM), 0, 0); 75 fGreyScaleMI = new BMenuItem(B_TRANSLATE("Greyscale"), 76 new BMessage(GV_GREYSCALE), 0, 0); 77 fOptimalMI = new BMenuItem(B_TRANSLATE("Optimal"), 78 new BMessage(GV_OPTIMAL), 0, 0); 79 fPaletteM = new BPopUpMenu("PalettePopUpMenu", true, true, 80 B_ITEMS_IN_COLUMN); 81 fPaletteM->AddItem(fWebSafeMI); 82 fPaletteM->AddItem(fBeOSSystemMI); 83 fPaletteM->AddItem(fGreyScaleMI); 84 fPaletteM->AddItem(fOptimalMI); 85 86 fColorCountM = new BPopUpMenu("ColorCountPopUpMenu", true, true, 87 B_ITEMS_IN_COLUMN); 88 int32 count = 2; 89 for (int32 i = 0; i < 8; i++) { 90 BMessage* message = new BMessage(GV_SET_COLOR_COUNT); 91 message->AddInt32(GIF_SETTING_PALETTE_SIZE, i + 1); 92 BString label; 93 label << count; 94 fColorCountMI[i] = new BMenuItem(label.String(), message, 0, 0); 95 fColorCountM->AddItem(fColorCountMI[i]); 96 count *= 2; 97 } 98 fColorCount256MI = fColorCountMI[7]; 99 100 fPaletteMF = new BMenuField(B_TRANSLATE("Palette:"), fPaletteM); 101 fPaletteMF->SetAlignment(B_ALIGN_RIGHT); 102 fColorCountMF = new BMenuField(B_TRANSLATE("Colors:"), fColorCountM); 103 fColorCountMF->SetAlignment(B_ALIGN_RIGHT); 104 105 // check boxes 106 fUseDitheringCB = new BCheckBox(B_TRANSLATE("Use dithering"), 107 new BMessage(GV_USE_DITHERING)); 108 fDitheringBox = new BBox("dithering", B_WILL_DRAW, B_NO_BORDER); 109 fDitheringBox->SetLabel(fUseDitheringCB); 110 111 fInterlacedCB = new BCheckBox(B_TRANSLATE("Write interlaced images"), 112 new BMessage(GV_INTERLACED)); 113 fInterlacedBox = new BBox("interlaced", B_WILL_DRAW, B_NO_BORDER); 114 fInterlacedBox->SetLabel(fInterlacedCB); 115 116 fUseTransparentCB = new BCheckBox(B_TRANSLATE("Write transparent images"), 117 new BMessage(GV_USE_TRANSPARENT)); 118 119 // radio buttons 120 fUseTransparentAutoRB = new BRadioButton( 121 B_TRANSLATE("Automatic (from alpha channel)"), 122 new BMessage(GV_USE_TRANSPARENT_AUTO)); 123 124 fUseTransparentColorRB = new BRadioButton(B_TRANSLATE("Use RGB color"), 125 new BMessage(GV_USE_TRANSPARENT_COLOR)); 126 127 // text controls 128 fRedTextControl = new BTextControl("", "0", 129 new BMessage(GV_TRANSPARENT_RED)); 130 fGreenTextControl = new BTextControl("", "0", 131 new BMessage(GV_TRANSPARENT_GREEN)); 132 fBlueTextControl = new BTextControl("", "0", 133 new BMessage(GV_TRANSPARENT_BLUE)); 134 135 fTransparentBox = new BBox(B_FANCY_BORDER, 136 BLayoutBuilder::Grid<>(3.0f, 5.0f) 137 .Add(fUseTransparentAutoRB, 0, 0, 4, 1) 138 .Add(fUseTransparentColorRB, 0, 1) 139 .Add(fRedTextControl, 1, 1) 140 .Add(fGreenTextControl, 2, 1) 141 .Add(fBlueTextControl, 3, 1) 142 .SetInsets(10.0f, 6.0f, 10.0f, 10.0f) 143 .View()); 144 fTransparentBox->SetLabel(fUseTransparentCB); 145 146 BTextView* redTextView = fRedTextControl->TextView(); 147 BTextView* greenTextView = fGreenTextControl->TextView(); 148 BTextView* bluetextView = fBlueTextControl->TextView(); 149 150 for (uint32 x = 0; x < 256; x++) { 151 if (x < '0' || x > '9') { 152 redTextView->DisallowChar(x); 153 greenTextView->DisallowChar(x); 154 bluetextView->DisallowChar(x); 155 } 156 } 157 158 BLayoutBuilder::Group<>(this, B_VERTICAL, 10.0f) 159 .SetInsets(10.0f) 160 .AddGrid(10.0f, 5.0f) 161 .Add(fTitle, 0, 0) 162 .Add(fVersion, 1, 0) 163 .Add(fCopyright, 0, 1, 2, 1) 164 .End() 165 .AddGlue() 166 167 .AddGrid(10.0f, 5.0f) 168 .Add(fPaletteMF->CreateLabelLayoutItem(), 0, 0) 169 .Add(fPaletteMF->CreateMenuBarLayoutItem(), 1, 0) 170 171 .Add(fColorCountMF->CreateLabelLayoutItem(), 0, 1) 172 .Add(fColorCountMF->CreateMenuBarLayoutItem(), 1, 1) 173 174 .Add(BSpaceLayoutItem::CreateHorizontalStrut(10.0f), 1, 2) 175 176 .Add(fDitheringBox, 1, 3) 177 .Add(fInterlacedBox, 1, 4) 178 .Add(fTransparentBox, 1, 5) 179 180 .End() 181 .AddGlue() 182 .End(); 183 184 BFont font; 185 GetFont(&font); 186 SetExplicitPreferredSize(BSize((font.Size() * 400) / 12, 187 (font.Size() * 300) / 12)); 188 189 fSettings->Acquire(); 190 191 RestorePrefs(); 192 } 193 194 195 GIFView::~GIFView() 196 { 197 fSettings->Release(); 198 199 delete fTitle; 200 delete fVersion; 201 delete fCopyright; 202 delete fPaletteMF; 203 delete fColorCountMF; 204 delete fDitheringBox; 205 delete fInterlacedBox; 206 delete fTransparentBox; 207 } 208 209 210 void 211 GIFView::RestorePrefs() 212 { 213 fColorCountMF->SetEnabled(false); 214 fUseDitheringCB->SetEnabled(true); 215 216 switch (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE)) { 217 case WEB_SAFE_PALETTE: 218 fWebSafeMI->SetMarked(true); 219 break; 220 221 case BEOS_SYSTEM_PALETTE: 222 fBeOSSystemMI->SetMarked(true); 223 break; 224 225 case GREYSCALE_PALETTE: 226 fGreyScaleMI->SetMarked(true); 227 fUseDitheringCB->SetEnabled(false); 228 break; 229 230 case OPTIMAL_PALETTE: 231 fOptimalMI->SetMarked(true); 232 fColorCountMF->SetEnabled(true); 233 break; 234 235 default: 236 { 237 int32 value = WEB_SAFE_PALETTE; 238 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 239 fSettings->SaveSettings(); 240 fWebSafeMI->SetMarked(true); 241 } 242 } 243 244 if (fColorCountMF->IsEnabled() 245 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) > 0 246 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) <= 8) { 247 // display the stored color count 248 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 249 ->SetMarked(true); 250 } else { 251 // display 256 colors 252 fColorCount256MI->SetMarked(true); 253 int32 value = 8; 254 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, &value); 255 fSettings->SaveSettings(); 256 } 257 258 fInterlacedCB->SetValue(fSettings->SetGetBool(GIF_SETTING_INTERLACED)); 259 260 if (fGreyScaleMI->IsMarked()) 261 fUseDitheringCB->SetValue(false); 262 else { 263 fUseDitheringCB->SetValue( 264 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)); 265 } 266 fUseTransparentCB->SetValue( 267 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)); 268 fUseTransparentAutoRB->SetValue( 269 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 270 fUseTransparentColorRB->SetValue( 271 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 272 if (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)) { 273 fUseTransparentAutoRB->SetEnabled(true); 274 fUseTransparentColorRB->SetEnabled(true); 275 fRedTextControl->SetEnabled( 276 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 277 fGreenTextControl->SetEnabled( 278 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 279 fBlueTextControl->SetEnabled( 280 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 281 } else { 282 fUseTransparentAutoRB->SetEnabled(false); 283 fUseTransparentColorRB->SetEnabled(false); 284 fRedTextControl->SetEnabled(false); 285 fGreenTextControl->SetEnabled(false); 286 fBlueTextControl->SetEnabled(false); 287 } 288 289 char temp[4]; 290 sprintf(temp, "%d", 291 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED)); 292 fRedTextControl->SetText(temp); 293 sprintf(temp, "%d", 294 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN)); 295 fGreenTextControl->SetText(temp); 296 sprintf(temp, "%d", 297 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE)); 298 fBlueTextControl->SetText(temp); 299 } 300 301 302 void 303 GIFView::AllAttached() 304 { 305 BMessenger messenger(this); 306 fInterlacedCB->SetTarget(messenger); 307 fUseDitheringCB->SetTarget(messenger); 308 fUseTransparentCB->SetTarget(messenger); 309 fUseTransparentAutoRB->SetTarget(messenger); 310 fUseTransparentColorRB->SetTarget(messenger); 311 fRedTextControl->SetTarget(messenger); 312 fGreenTextControl->SetTarget(messenger); 313 fBlueTextControl->SetTarget(messenger); 314 fPaletteM->SetTargetForItems(messenger); 315 fColorCountM->SetTargetForItems(messenger); 316 317 BView::AllAttached(); 318 } 319 320 321 void 322 GIFView::MessageReceived(BMessage* message) 323 { 324 switch (message->what) { 325 case GV_WEB_SAFE: 326 { 327 int32 value = WEB_SAFE_PALETTE; 328 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 329 fUseDitheringCB->SetEnabled(true); 330 fColorCountMF->SetEnabled(false); 331 fColorCount256MI->SetMarked(true); 332 break; 333 } 334 335 case GV_BEOS_SYSTEM: 336 { 337 int32 value = BEOS_SYSTEM_PALETTE; 338 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 339 fUseDitheringCB->SetEnabled(true); 340 fColorCountMF->SetEnabled(false); 341 fColorCount256MI->SetMarked(true); 342 break; 343 } 344 345 case GV_GREYSCALE: 346 { 347 int32 value = GREYSCALE_PALETTE; 348 bool usedithering = false; 349 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 350 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &usedithering); 351 fUseDitheringCB->SetEnabled(false); 352 fUseDitheringCB->SetValue(false); 353 fColorCountMF->SetEnabled(false); 354 fColorCount256MI->SetMarked(true); 355 break; 356 } 357 358 case GV_OPTIMAL: 359 { 360 int32 value = OPTIMAL_PALETTE; 361 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 362 fUseDitheringCB->SetEnabled(true); 363 fColorCountMF->SetEnabled(true); 364 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 365 ->SetMarked(true); 366 break; 367 } 368 369 case GV_SET_COLOR_COUNT: 370 if (fColorCountMF->IsEnabled()) { 371 int32 sizeInBits; 372 if (message->FindInt32(GIF_SETTING_PALETTE_SIZE, &sizeInBits) 373 >= B_OK && sizeInBits > 0 && sizeInBits <= 8) { 374 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, 375 &sizeInBits); 376 } 377 } 378 break; 379 380 case GV_INTERLACED: 381 { 382 bool value = fInterlacedCB->Value(); 383 fSettings->SetGetBool(GIF_SETTING_INTERLACED, &value); 384 break; 385 } 386 387 case GV_USE_DITHERING: 388 { 389 bool value = fUseDitheringCB->Value(); 390 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &value); 391 break; 392 } 393 394 case GV_USE_TRANSPARENT: 395 { 396 bool value = fUseTransparentCB->Value(); 397 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT, &value); 398 if (value) { 399 fUseTransparentAutoRB->SetEnabled(true); 400 fUseTransparentColorRB->SetEnabled(true); 401 fRedTextControl->SetEnabled(fUseTransparentColorRB->Value()); 402 fGreenTextControl->SetEnabled(fUseTransparentColorRB->Value()); 403 fBlueTextControl->SetEnabled(fUseTransparentColorRB->Value()); 404 } else { 405 fUseTransparentAutoRB->SetEnabled(false); 406 fUseTransparentColorRB->SetEnabled(false); 407 fRedTextControl->SetEnabled(false); 408 fGreenTextControl->SetEnabled(false); 409 fBlueTextControl->SetEnabled(false); 410 } 411 break; 412 } 413 414 case GV_USE_TRANSPARENT_AUTO: 415 { 416 bool value = true; 417 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 418 fRedTextControl->SetEnabled(false); 419 fGreenTextControl->SetEnabled(false); 420 fBlueTextControl->SetEnabled(false); 421 break; 422 } 423 424 case GV_USE_TRANSPARENT_COLOR: 425 { 426 bool value = false; 427 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 428 fRedTextControl->SetEnabled(true); 429 fGreenTextControl->SetEnabled(true); 430 fBlueTextControl->SetEnabled(true); 431 break; 432 } 433 434 case GV_TRANSPARENT_RED: 435 { 436 int32 value = CheckInput(fRedTextControl); 437 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED, &value); 438 break; 439 } 440 441 case GV_TRANSPARENT_GREEN: 442 { 443 int32 value = CheckInput(fGreenTextControl); 444 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN, &value); 445 break; 446 } 447 448 case GV_TRANSPARENT_BLUE: 449 { 450 int32 value = CheckInput(fBlueTextControl); 451 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE, &value); 452 break; 453 } 454 455 default: 456 BView::MessageReceived(message); 457 } 458 459 fSettings->SaveSettings(); 460 } 461 462 463 int 464 GIFView::CheckInput(BTextControl* control) 465 { 466 int value = atoi(control->Text()); 467 if (value < 0 || value > 255) { 468 value = (value < 0) ? 0 : 255; 469 char temp[4]; 470 sprintf(temp, "%d", value); 471 control->SetText(temp); 472 } 473 474 return value; 475 } 476