xref: /haiku/src/add-ons/translators/gif/GIFView.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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