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 BGroupView("GIFView", B_VERTICAL), 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("Version %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, 0) 159 .SetInsets(B_USE_DEFAULT_SPACING) 160 .Add(fTitle) 161 .Add(fVersion) 162 .Add(fCopyright) 163 .AddGlue() 164 .AddGrid(10.0f, 5.0f) 165 .Add(fPaletteMF->CreateLabelLayoutItem(), 0, 0) 166 .Add(fPaletteMF->CreateMenuBarLayoutItem(), 1, 0) 167 .Add(fColorCountMF->CreateLabelLayoutItem(), 0, 1) 168 .Add(fColorCountMF->CreateMenuBarLayoutItem(), 1, 1) 169 .End() 170 .AddStrut(B_USE_SMALL_SPACING) 171 .Add(fDitheringBox) 172 .Add(fInterlacedBox) 173 .Add(fTransparentBox) 174 .AddGlue() 175 .End(); 176 177 fSettings->Acquire(); 178 179 RestorePrefs(); 180 } 181 182 183 GIFView::~GIFView() 184 { 185 fSettings->Release(); 186 187 delete fTitle; 188 delete fVersion; 189 delete fCopyright; 190 delete fPaletteMF; 191 delete fColorCountMF; 192 delete fDitheringBox; 193 delete fInterlacedBox; 194 delete fTransparentBox; 195 } 196 197 198 void 199 GIFView::RestorePrefs() 200 { 201 fColorCountMF->SetEnabled(false); 202 fUseDitheringCB->SetEnabled(true); 203 204 switch (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE)) { 205 case WEB_SAFE_PALETTE: 206 fWebSafeMI->SetMarked(true); 207 break; 208 209 case BEOS_SYSTEM_PALETTE: 210 fBeOSSystemMI->SetMarked(true); 211 break; 212 213 case GREYSCALE_PALETTE: 214 fGreyScaleMI->SetMarked(true); 215 fUseDitheringCB->SetEnabled(false); 216 break; 217 218 case OPTIMAL_PALETTE: 219 fOptimalMI->SetMarked(true); 220 fColorCountMF->SetEnabled(true); 221 break; 222 223 default: 224 { 225 int32 value = WEB_SAFE_PALETTE; 226 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 227 fSettings->SaveSettings(); 228 fWebSafeMI->SetMarked(true); 229 } 230 } 231 232 if (fColorCountMF->IsEnabled() 233 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) > 0 234 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) <= 8) { 235 // display the stored color count 236 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 237 ->SetMarked(true); 238 } else { 239 // display 256 colors 240 fColorCount256MI->SetMarked(true); 241 int32 value = 8; 242 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, &value); 243 fSettings->SaveSettings(); 244 } 245 246 fInterlacedCB->SetValue(fSettings->SetGetBool(GIF_SETTING_INTERLACED)); 247 248 if (fGreyScaleMI->IsMarked()) 249 fUseDitheringCB->SetValue(false); 250 else { 251 fUseDitheringCB->SetValue( 252 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)); 253 } 254 fUseTransparentCB->SetValue( 255 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)); 256 fUseTransparentAutoRB->SetValue( 257 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 258 fUseTransparentColorRB->SetValue( 259 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 260 if (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)) { 261 fUseTransparentAutoRB->SetEnabled(true); 262 fUseTransparentColorRB->SetEnabled(true); 263 fRedTextControl->SetEnabled( 264 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 265 fGreenTextControl->SetEnabled( 266 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 267 fBlueTextControl->SetEnabled( 268 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 269 } else { 270 fUseTransparentAutoRB->SetEnabled(false); 271 fUseTransparentColorRB->SetEnabled(false); 272 fRedTextControl->SetEnabled(false); 273 fGreenTextControl->SetEnabled(false); 274 fBlueTextControl->SetEnabled(false); 275 } 276 277 char temp[4]; 278 sprintf(temp, "%d", 279 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED)); 280 fRedTextControl->SetText(temp); 281 sprintf(temp, "%d", 282 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN)); 283 fGreenTextControl->SetText(temp); 284 sprintf(temp, "%d", 285 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE)); 286 fBlueTextControl->SetText(temp); 287 } 288 289 290 void 291 GIFView::AllAttached() 292 { 293 BMessenger messenger(this); 294 fInterlacedCB->SetTarget(messenger); 295 fUseDitheringCB->SetTarget(messenger); 296 fUseTransparentCB->SetTarget(messenger); 297 fUseTransparentAutoRB->SetTarget(messenger); 298 fUseTransparentColorRB->SetTarget(messenger); 299 fRedTextControl->SetTarget(messenger); 300 fGreenTextControl->SetTarget(messenger); 301 fBlueTextControl->SetTarget(messenger); 302 fPaletteM->SetTargetForItems(messenger); 303 fColorCountM->SetTargetForItems(messenger); 304 305 BView::AllAttached(); 306 307 if (Parent() == NULL && Window()->GetLayout() == NULL) { 308 Window()->SetLayout(new BGroupLayout(B_VERTICAL)); 309 Window()->ResizeTo(PreferredSize().Width(), PreferredSize().Height()); 310 } 311 } 312 313 314 void 315 GIFView::MessageReceived(BMessage* message) 316 { 317 switch (message->what) { 318 case GV_WEB_SAFE: 319 { 320 int32 value = WEB_SAFE_PALETTE; 321 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 322 fUseDitheringCB->SetEnabled(true); 323 fColorCountMF->SetEnabled(false); 324 fColorCount256MI->SetMarked(true); 325 break; 326 } 327 328 case GV_BEOS_SYSTEM: 329 { 330 int32 value = BEOS_SYSTEM_PALETTE; 331 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 332 fUseDitheringCB->SetEnabled(true); 333 fColorCountMF->SetEnabled(false); 334 fColorCount256MI->SetMarked(true); 335 break; 336 } 337 338 case GV_GREYSCALE: 339 { 340 int32 value = GREYSCALE_PALETTE; 341 bool usedithering = false; 342 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 343 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &usedithering); 344 fUseDitheringCB->SetEnabled(false); 345 fUseDitheringCB->SetValue(false); 346 fColorCountMF->SetEnabled(false); 347 fColorCount256MI->SetMarked(true); 348 break; 349 } 350 351 case GV_OPTIMAL: 352 { 353 int32 value = OPTIMAL_PALETTE; 354 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 355 fUseDitheringCB->SetEnabled(true); 356 fColorCountMF->SetEnabled(true); 357 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 358 ->SetMarked(true); 359 break; 360 } 361 362 case GV_SET_COLOR_COUNT: 363 if (fColorCountMF->IsEnabled()) { 364 int32 sizeInBits; 365 if (message->FindInt32(GIF_SETTING_PALETTE_SIZE, &sizeInBits) 366 >= B_OK && sizeInBits > 0 && sizeInBits <= 8) { 367 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, 368 &sizeInBits); 369 } 370 } 371 break; 372 373 case GV_INTERLACED: 374 { 375 bool value = fInterlacedCB->Value(); 376 fSettings->SetGetBool(GIF_SETTING_INTERLACED, &value); 377 break; 378 } 379 380 case GV_USE_DITHERING: 381 { 382 bool value = fUseDitheringCB->Value(); 383 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &value); 384 break; 385 } 386 387 case GV_USE_TRANSPARENT: 388 { 389 bool value = fUseTransparentCB->Value(); 390 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT, &value); 391 if (value) { 392 fUseTransparentAutoRB->SetEnabled(true); 393 fUseTransparentColorRB->SetEnabled(true); 394 fRedTextControl->SetEnabled(fUseTransparentColorRB->Value()); 395 fGreenTextControl->SetEnabled(fUseTransparentColorRB->Value()); 396 fBlueTextControl->SetEnabled(fUseTransparentColorRB->Value()); 397 } else { 398 fUseTransparentAutoRB->SetEnabled(false); 399 fUseTransparentColorRB->SetEnabled(false); 400 fRedTextControl->SetEnabled(false); 401 fGreenTextControl->SetEnabled(false); 402 fBlueTextControl->SetEnabled(false); 403 } 404 break; 405 } 406 407 case GV_USE_TRANSPARENT_AUTO: 408 { 409 bool value = true; 410 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 411 fRedTextControl->SetEnabled(false); 412 fGreenTextControl->SetEnabled(false); 413 fBlueTextControl->SetEnabled(false); 414 break; 415 } 416 417 case GV_USE_TRANSPARENT_COLOR: 418 { 419 bool value = false; 420 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 421 fRedTextControl->SetEnabled(true); 422 fGreenTextControl->SetEnabled(true); 423 fBlueTextControl->SetEnabled(true); 424 break; 425 } 426 427 case GV_TRANSPARENT_RED: 428 { 429 int32 value = CheckInput(fRedTextControl); 430 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED, &value); 431 break; 432 } 433 434 case GV_TRANSPARENT_GREEN: 435 { 436 int32 value = CheckInput(fGreenTextControl); 437 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN, &value); 438 break; 439 } 440 441 case GV_TRANSPARENT_BLUE: 442 { 443 int32 value = CheckInput(fBlueTextControl); 444 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE, &value); 445 break; 446 } 447 448 default: 449 BView::MessageReceived(message); 450 } 451 452 fSettings->SaveSettings(); 453 } 454 455 456 int 457 GIFView::CheckInput(BTextControl* control) 458 { 459 int value = atoi(control->Text()); 460 if (value < 0 || value > 255) { 461 value = (value < 0) ? 0 : 255; 462 char temp[4]; 463 sprintf(temp, "%d", value); 464 control->SetText(temp); 465 } 466 467 return value; 468 } 469