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 // Maxime Simon, <maxime.simon@gmail.com> 18 // Philippe Saint-Pierre, <stpere@gmail.com> 19 20 #include "GIFView.h" 21 #include "GIFTranslator.h" 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 26 #include <Catalog.h> 27 #include <InterfaceKit.h> 28 #include <LayoutBuilder.h> 29 #include <String.h> 30 31 #include "SavePalette.h" 32 33 #undef B_TRANSLATION_CONTEXT 34 #define B_TRANSLATION_CONTEXT "GIFView" 35 36 37 // constructor 38 GIFView::GIFView(TranslatorSettings* settings) 39 : 40 BView("GIFView", B_WILL_DRAW), 41 fSettings(settings) 42 { 43 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 44 45 BStringView *title = new BStringView("Title", B_TRANSLATE("GIF image translator")); 46 title->SetFont(be_bold_font); 47 48 char version_string[100]; 49 snprintf(version_string, sizeof(version_string), B_TRANSLATE("v%d.%d.%d %s"), 50 int(B_TRANSLATION_MAJOR_VERSION(GIF_TRANSLATOR_VERSION)), 51 int(B_TRANSLATION_MINOR_VERSION(GIF_TRANSLATOR_VERSION)), 52 int(B_TRANSLATION_REVISION_VERSION(GIF_TRANSLATOR_VERSION)), 53 __DATE__); 54 55 BStringView *version = new BStringView("Version", version_string); 56 57 const char *copyrightString = "©2003 Daniel Switkin, software@switkin.com"; 58 BStringView *copyright = new BStringView("Copyright", copyrightString); 59 60 // menu fields (Palette & Colors) 61 fWebSafeMI = new BMenuItem(B_TRANSLATE("Websafe"), 62 new BMessage(GV_WEB_SAFE), 0, 0); 63 fBeOSSystemMI = new BMenuItem(B_TRANSLATE("BeOS system"), 64 new BMessage(GV_BEOS_SYSTEM), 0, 0); 65 fGreyScaleMI = new BMenuItem(B_TRANSLATE("Greyscale"), 66 new BMessage(GV_GREYSCALE), 0, 0); 67 fOptimalMI = new BMenuItem(B_TRANSLATE("Optimal"), 68 new BMessage(GV_OPTIMAL), 0, 0); 69 fPaletteM = new BPopUpMenu("PalettePopUpMenu", true, true, B_ITEMS_IN_COLUMN); 70 fPaletteM->AddItem(fWebSafeMI); 71 fPaletteM->AddItem(fBeOSSystemMI); 72 fPaletteM->AddItem(fGreyScaleMI); 73 fPaletteM->AddItem(fOptimalMI); 74 75 fColorCountM = new BPopUpMenu("ColorCountPopUpMenu", true, true, 76 B_ITEMS_IN_COLUMN); 77 int32 count = 2; 78 for (int32 i = 0; i < 8; i++) { 79 BMessage* message = new BMessage(GV_SET_COLOR_COUNT); 80 message->AddInt32(GIF_SETTING_PALETTE_SIZE, i + 1); 81 BString label; 82 label << count; 83 fColorCountMI[i] = new BMenuItem(label.String(), message, 0, 0); 84 fColorCountM->AddItem(fColorCountMI[i]); 85 count *= 2; 86 } 87 fColorCount256MI = fColorCountMI[7]; 88 89 fPaletteMF = new BMenuField(B_TRANSLATE("Palette"), fPaletteM); 90 fColorCountMF = new BMenuField(B_TRANSLATE("Colors"), fColorCountM); 91 92 // check boxes 93 fUseDitheringCB = new BCheckBox(B_TRANSLATE("Use dithering"), 94 new BMessage(GV_USE_DITHERING)); 95 96 fInterlacedCB = new BCheckBox(B_TRANSLATE("Write interlaced images"), 97 new BMessage(GV_INTERLACED)); 98 99 fUseTransparentCB = new BCheckBox(B_TRANSLATE("Write transparent images"), 100 new BMessage(GV_USE_TRANSPARENT)); 101 102 // radio buttons 103 fUseTransparentAutoRB = new BRadioButton( 104 B_TRANSLATE("Automatic (from alpha channel)"), 105 new BMessage(GV_USE_TRANSPARENT_AUTO)); 106 107 fUseTransparentColorRB = new BRadioButton(B_TRANSLATE("Use RGB color"), 108 new BMessage(GV_USE_TRANSPARENT_COLOR)); 109 110 fTransparentRedTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_RED)); 111 fTransparentGreenTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_GREEN)); 112 fTransparentBlueTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_BLUE)); 113 114 BTextView *tr = fTransparentRedTC->TextView(); 115 BTextView *tg = fTransparentGreenTC->TextView(); 116 BTextView *tb = fTransparentBlueTC->TextView(); 117 118 for (uint32 x = 0; x < 256; x++) { 119 if (x < '0' || x > '9') { 120 tr->DisallowChar(x); 121 tg->DisallowChar(x); 122 tb->DisallowChar(x); 123 } 124 } 125 126 BLayoutBuilder::Group<>(this, B_VERTICAL, 7) 127 .SetInsets(5) 128 .AddGrid(10, 10) 129 .Add(title, 0, 0) 130 .Add(version, 1, 0) 131 .End() 132 .Add(copyright) 133 .AddGlue() 134 135 .AddGrid(10, 10) 136 .Add(fPaletteMF->CreateLabelLayoutItem(), 0, 0) 137 .Add(fPaletteMF->CreateMenuBarLayoutItem(), 1, 0) 138 139 .Add(fColorCountMF->CreateLabelLayoutItem(), 0, 1) 140 .Add(fColorCountMF->CreateMenuBarLayoutItem(), 1, 1) 141 .End() 142 .AddGlue() 143 144 .Add(fUseDitheringCB) 145 .Add(fInterlacedCB) 146 .Add(fUseTransparentCB) 147 148 .Add(fUseTransparentAutoRB) 149 .AddGrid(10, 10) 150 .Add(fUseTransparentColorRB, 0, 0) 151 .Add(fTransparentRedTC, 1, 0) 152 .Add(fTransparentGreenTC, 2, 0) 153 .Add(fTransparentBlueTC, 3, 0) 154 .End() 155 .AddGlue(); 156 157 BFont font; 158 GetFont(&font); 159 SetExplicitPreferredSize(BSize((font.Size() * 400)/12, (font.Size() * 300)/12)); 160 161 RestorePrefs(); 162 } 163 164 165 GIFView::~GIFView() 166 { 167 fSettings->Release(); 168 } 169 170 171 void 172 GIFView::RestorePrefs() 173 { 174 fColorCountMF->SetEnabled(false); 175 fUseDitheringCB->SetEnabled(true); 176 177 switch (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE)) { 178 case WEB_SAFE_PALETTE: 179 fWebSafeMI->SetMarked(true); 180 break; 181 case BEOS_SYSTEM_PALETTE: 182 fBeOSSystemMI->SetMarked(true); 183 break; 184 case GREYSCALE_PALETTE: 185 fGreyScaleMI->SetMarked(true); 186 fUseDitheringCB->SetEnabled(false); 187 break; 188 case OPTIMAL_PALETTE: 189 fOptimalMI->SetMarked(true); 190 fColorCountMF->SetEnabled(true); 191 break; 192 default: 193 int32 value = WEB_SAFE_PALETTE; 194 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 195 fSettings->SaveSettings(); 196 fWebSafeMI->SetMarked(true); 197 break; 198 } 199 200 if (fColorCountMF->IsEnabled() 201 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) > 0 202 && fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) <= 8) { 203 // display the stored color count 204 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 205 ->SetMarked(true); 206 } else { 207 // display 256 colors 208 fColorCount256MI->SetMarked(true); 209 int32 value = 8; 210 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, &value); 211 fSettings->SaveSettings(); 212 } 213 214 fInterlacedCB->SetValue(fSettings->SetGetBool(GIF_SETTING_INTERLACED)); 215 216 if (fGreyScaleMI->IsMarked()) 217 fUseDitheringCB->SetValue(false); 218 else 219 fUseDitheringCB->SetValue( 220 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)); 221 fUseTransparentCB->SetValue( 222 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)); 223 fUseTransparentAutoRB->SetValue( 224 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 225 fUseTransparentColorRB->SetValue( 226 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 227 if (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)) { 228 fUseTransparentAutoRB->SetEnabled(true); 229 fUseTransparentColorRB->SetEnabled(true); 230 fTransparentRedTC->SetEnabled( 231 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 232 fTransparentGreenTC->SetEnabled( 233 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 234 fTransparentBlueTC->SetEnabled( 235 !fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)); 236 } else { 237 fUseTransparentAutoRB->SetEnabled(false); 238 fUseTransparentColorRB->SetEnabled(false); 239 fTransparentRedTC->SetEnabled(false); 240 fTransparentGreenTC->SetEnabled(false); 241 fTransparentBlueTC->SetEnabled(false); 242 } 243 244 char temp[4]; 245 sprintf(temp, "%d", 246 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED)); 247 fTransparentRedTC->SetText(temp); 248 sprintf(temp, "%d", 249 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN)); 250 fTransparentGreenTC->SetText(temp); 251 sprintf(temp, "%d", 252 (int)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE)); 253 fTransparentBlueTC->SetText(temp); 254 } 255 256 257 // AllAttached 258 void 259 GIFView::AllAttached() 260 { 261 BView::AllAttached(); 262 BMessenger msgr(this); 263 fInterlacedCB->SetTarget(msgr); 264 fUseDitheringCB->SetTarget(msgr); 265 fUseTransparentCB->SetTarget(msgr); 266 fUseTransparentAutoRB->SetTarget(msgr); 267 fUseTransparentColorRB->SetTarget(msgr); 268 fTransparentRedTC->SetTarget(msgr); 269 fTransparentGreenTC->SetTarget(msgr); 270 fTransparentBlueTC->SetTarget(msgr); 271 fPaletteM->SetTargetForItems(msgr); 272 fColorCountM->SetTargetForItems(msgr); 273 } 274 275 276 // MessageReceived 277 void 278 GIFView::MessageReceived(BMessage *message) 279 { 280 switch (message->what) { 281 case GV_WEB_SAFE: 282 { 283 int32 value = WEB_SAFE_PALETTE; 284 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 285 fUseDitheringCB->SetEnabled(true); 286 fColorCountMF->SetEnabled(false); 287 fColorCount256MI->SetMarked(true); 288 break; 289 } 290 case GV_BEOS_SYSTEM: 291 { 292 int32 value = BEOS_SYSTEM_PALETTE; 293 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 294 fUseDitheringCB->SetEnabled(true); 295 fColorCountMF->SetEnabled(false); 296 fColorCount256MI->SetMarked(true); 297 break; 298 } 299 case GV_GREYSCALE: 300 { 301 int32 value = GREYSCALE_PALETTE; 302 bool usedithering = false; 303 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 304 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &usedithering); 305 fUseDitheringCB->SetEnabled(false); 306 fUseDitheringCB->SetValue(false); 307 fColorCountMF->SetEnabled(false); 308 fColorCount256MI->SetMarked(true); 309 break; 310 } 311 case GV_OPTIMAL: 312 { 313 int32 value = OPTIMAL_PALETTE; 314 fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); 315 fUseDitheringCB->SetEnabled(true); 316 fColorCountMF->SetEnabled(true); 317 fColorCountMI[fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE) - 1] 318 ->SetMarked(true); 319 break; 320 } 321 case GV_SET_COLOR_COUNT: 322 if (fColorCountMF->IsEnabled()) { 323 int32 sizeInBits; 324 if (message->FindInt32(GIF_SETTING_PALETTE_SIZE, &sizeInBits) 325 >= B_OK) { 326 if (sizeInBits > 0 && sizeInBits <= 8) 327 fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE, 328 &sizeInBits); 329 } 330 } 331 break; 332 case GV_INTERLACED: 333 { 334 bool value = fInterlacedCB->Value(); 335 fSettings->SetGetBool(GIF_SETTING_INTERLACED, &value); 336 break; 337 } 338 case GV_USE_DITHERING: 339 { 340 bool value = fUseDitheringCB->Value(); 341 fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &value); 342 break; 343 } 344 case GV_USE_TRANSPARENT: 345 { 346 bool value = fUseTransparentCB->Value(); 347 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT, &value); 348 if (value) { 349 fUseTransparentAutoRB->SetEnabled(true); 350 fUseTransparentColorRB->SetEnabled(true); 351 fTransparentRedTC->SetEnabled(fUseTransparentColorRB->Value()); 352 fTransparentGreenTC->SetEnabled(fUseTransparentColorRB->Value()); 353 fTransparentBlueTC->SetEnabled(fUseTransparentColorRB->Value()); 354 } else { 355 fUseTransparentAutoRB->SetEnabled(false); 356 fUseTransparentColorRB->SetEnabled(false); 357 fTransparentRedTC->SetEnabled(false); 358 fTransparentGreenTC->SetEnabled(false); 359 fTransparentBlueTC->SetEnabled(false); 360 } 361 break; 362 } 363 case GV_USE_TRANSPARENT_AUTO: 364 { 365 bool value = true; 366 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 367 fTransparentRedTC->SetEnabled(false); 368 fTransparentGreenTC->SetEnabled(false); 369 fTransparentBlueTC->SetEnabled(false); 370 break; 371 } 372 case GV_USE_TRANSPARENT_COLOR: 373 { 374 bool value = false; 375 fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO, &value); 376 fTransparentRedTC->SetEnabled(true); 377 fTransparentGreenTC->SetEnabled(true); 378 fTransparentBlueTC->SetEnabled(true); 379 break; 380 } 381 case GV_TRANSPARENT_RED: 382 { 383 int32 value = CheckInput(fTransparentRedTC); 384 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED, &value); 385 break; 386 } 387 case GV_TRANSPARENT_GREEN: 388 { 389 int32 value = CheckInput(fTransparentGreenTC); 390 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN, &value); 391 break; 392 } 393 case GV_TRANSPARENT_BLUE: 394 { 395 int32 value = CheckInput(fTransparentBlueTC); 396 fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE, &value); 397 break; 398 } 399 default: 400 BView::MessageReceived(message); 401 break; 402 } 403 fSettings->SaveSettings(); 404 } 405 406 407 int GIFView::CheckInput(BTextControl *control) { 408 int value = atoi(control->Text()); 409 if (value < 0 || value > 255) { 410 value = (value < 0) ? 0 : 255; 411 char temp[4]; 412 sprintf(temp, "%d", value); 413 control->SetText(temp); 414 } 415 return value; 416 } 417 418