xref: /haiku/src/add-ons/translators/gif/GIFView.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
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 
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #include <InterfaceKit.h>
22 #include <String.h>
23 
24 #include "Prefs.h"
25 #include "SavePalette.h"
26 
27 #include "GIFView.h"
28 
29 extern int32 translatorVersion;
30 extern char translatorName[];
31 
32 // constructor
33 GIFView::GIFView(BRect rect, const char *name)
34 	: BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW)
35 {
36 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
37 
38 	font_height fh;
39 	be_bold_font->GetHeight(&fh);
40 	BRect r(10, 15, 10 + be_bold_font->StringWidth(translatorName), 15 + fh.ascent + fh.descent);
41 
42 	BStringView *title = new BStringView(r, "Title", translatorName);
43 	title->SetFont(be_bold_font);
44 	AddChild(title);
45 
46 	char version_string[100];
47 	sprintf(version_string, "v%d.%d.%d %s", (int)(translatorVersion >> 8), (int)((translatorVersion >> 4) & 0xf),
48 		(int)(translatorVersion & 0xf), __DATE__);
49 	be_plain_font->GetHeight(&fh);
50 	r.bottom = r.top + fh.ascent + fh.descent;
51 	r.left = r.right + 2.0 * r.Height();
52 	r.right = r.left + be_plain_font->StringWidth(version_string);
53 
54 	BStringView *version = new BStringView(r, "Version", version_string);
55 	version->SetFont(be_plain_font);
56 	AddChild(version);
57 
58 	BFont small(be_plain_font);
59 	small.SetSize(max_c(7.0, small.Size() * 0.7));
60 	const char *copyright_string = "© 2003 Daniel Switkin, software@switkin.com";
61 	r.top = r.bottom + 5;
62 	r.left = 10;
63 	r.bottom = r.top + fh.ascent + fh.descent;
64 	r.right = rect.right - 10;
65 
66 	BStringView *copyright = new BStringView(r, "Copyright", copyright_string);
67 	copyright->SetFont(&small);
68 	AddChild(copyright);
69 
70 	//menu fields (Palette & Colors)
71 	fWebSafeMI = new BMenuItem("Websafe", new BMessage(GV_WEB_SAFE), 0, 0);
72 	fBeOSSystemMI = new BMenuItem("BeOS System", new BMessage(GV_BEOS_SYSTEM), 0, 0);
73 	fGreyScaleMI = new BMenuItem("Greyscale", new BMessage(GV_GREYSCALE), 0, 0);
74 	fOptimalMI = new BMenuItem("Optimal", new BMessage(GV_OPTIMAL), 0, 0);
75 	fPaletteM = new BPopUpMenu("PalettePopUpMenu", true, true, B_ITEMS_IN_COLUMN);
76 	fPaletteM->AddItem(fWebSafeMI);
77 	fPaletteM->AddItem(fBeOSSystemMI);
78 	fPaletteM->AddItem(fGreyScaleMI);
79 	fPaletteM->AddItem(fOptimalMI);
80 
81 	fColorCountM = new BPopUpMenu("ColorCountPopUpMenu", true, true, B_ITEMS_IN_COLUMN);
82 	int32 count = 2;
83 	for (int32 i = 0; i < 8; i++) {
84 		BMessage* message = new BMessage(GV_SET_COLOR_COUNT);
85 		message->AddInt32("size in bits", i + 1);
86 		BString label;
87 		label << count;
88 		fColorCountMI[i] = new BMenuItem(label.String(), message, 0, 0);
89 		fColorCountM->AddItem(fColorCountMI[i]);
90 		count *= 2;
91 	}
92 	fColorCount256MI = fColorCountMI[7];
93 
94 	r.top = r.bottom + 5;
95 	r.bottom = r.top + 24;
96 	fPaletteMF = new BMenuField(r, "PaletteMenuField", "Palette",
97 		fPaletteM, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
98 	AddChild(fPaletteMF);
99 
100 	r.top = r.bottom + 5;
101 	r.bottom = r.top + 24;
102 	fColorCountMF = new BMenuField(r, "ColorCountMenuField", "Colors",
103 		fColorCountM, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
104 	AddChild(fColorCountMF);
105 
106 	// align menu fields
107 	float maxLabelWidth = ceilf(max_c(be_plain_font->StringWidth("Colors"),
108 									  be_plain_font->StringWidth("Palette")));
109 	fPaletteMF->SetDivider(maxLabelWidth + 7);
110 	fColorCountMF->SetDivider(maxLabelWidth + 7);
111 
112 	// check boxen
113 	r.top = fColorCountMF->Frame().bottom + 5;
114 	r.bottom = r.top + 10;
115 	fUseDitheringCB = new BCheckBox(r, "UseDithering", "Use dithering",
116 		new BMessage(GV_USE_DITHERING));
117 	AddChild(fUseDitheringCB);
118 
119 	r.top = fUseDitheringCB->Frame().bottom + 2;
120 	r.bottom = r.top + 10;
121 	fInterlacedCB = new BCheckBox(r, "Interlaced", "Write interlaced images",
122 		new BMessage(GV_INTERLACED));
123 	AddChild(fInterlacedCB);
124 
125 	r.top = fInterlacedCB->Frame().bottom + 2;
126 	r.bottom = r.top + 10;
127 	fUseTransparentCB = new BCheckBox(r, "UseTransparent", "Write transparent images",
128 		new BMessage(GV_USE_TRANSPARENT));
129 	AddChild(fUseTransparentCB);
130 
131 	// radio buttons
132 	r.top = fUseTransparentCB->Frame().bottom + 2;
133 	r.bottom = r.top + 10;
134 	r.right = r.left + be_plain_font->StringWidth("Automatic (from alpha channel)") + 20;
135 	fUseTransparentAutoRB = new BRadioButton(r, "UseTransparentAuto", "Automatic (from alpha channel)",
136 		new BMessage(GV_USE_TRANSPARENT_AUTO));
137 	AddChild(fUseTransparentAutoRB);
138 
139 	r.top = fUseTransparentAutoRB->Frame().bottom + 0;
140 	r.bottom = r.top + 10;
141 	r.left = 10;
142 	r.right = r.left + be_plain_font->StringWidth("Use RGB color") + 20;
143 	fUseTransparentColorRB = new BRadioButton(r, "UseTransparentColor", "Use RGB color",
144 		new BMessage(GV_USE_TRANSPARENT_COLOR));
145 	AddChild(fUseTransparentColorRB);
146 
147 	r.left = r.right + 1;
148 	r.right = r.left + 30;
149 	fTransparentRedTC = new BTextControl(r, "TransparentRed", "", "0",
150 		new BMessage(GV_TRANSPARENT_RED));
151 	AddChild(fTransparentRedTC);
152 	fTransparentRedTC->SetDivider(0);
153 
154 	r.left = r.right + 5;
155 	r.right = r.left + 30;
156 	fTransparentGreenTC = new BTextControl(r, "TransparentGreen", "", "0",
157 		new BMessage(GV_TRANSPARENT_GREEN));
158 	AddChild(fTransparentGreenTC);
159 	fTransparentGreenTC->SetDivider(0);
160 
161 	r.left = r.right + 5;
162 	r.right = r.left + 30;
163 	fTransparentBlueTC = new BTextControl(r, "TransparentBlue", "", "0",
164 		new BMessage(GV_TRANSPARENT_BLUE));
165 	AddChild(fTransparentBlueTC);
166 	fTransparentBlueTC->SetDivider(0);
167 
168 	BTextView *tr = fTransparentRedTC->TextView();
169 	BTextView *tg = fTransparentGreenTC->TextView();
170 	BTextView *tb = fTransparentBlueTC->TextView();
171 
172 	for (uint32 x = 0; x < 256; x++) {
173 		if (x < '0' || x > '9') {
174 			tr->DisallowChar(x);
175 			tg->DisallowChar(x);
176 			tb->DisallowChar(x);
177 		}
178 	}
179 
180 	RestorePrefs();
181 }
182 
183 // destructor
184 GIFView::~GIFView()
185 {
186 	delete fPrefs;
187 }
188 
189 // RestorePrefs
190 void
191 GIFView::RestorePrefs()
192 {
193 	fPrefs = new Prefs();
194 
195 	fColorCountMF->SetEnabled(false);
196 	fUseDitheringCB->SetEnabled(true);
197 
198 	switch (fPrefs->palettemode) {
199 		case WEB_SAFE_PALETTE:
200 			fWebSafeMI->SetMarked(true);
201 			break;
202 		case BEOS_SYSTEM_PALETTE:
203 			fBeOSSystemMI->SetMarked(true);
204 			break;
205 		case GREYSCALE_PALETTE:
206 			fGreyScaleMI->SetMarked(true);
207 			fUseDitheringCB->SetEnabled(false);
208 			break;
209 		case OPTIMAL_PALETTE:
210 			fOptimalMI->SetMarked(true);
211 			fColorCountMF->SetEnabled(true);
212 			break;
213 		default:
214 			fPrefs->palettemode = WEB_SAFE_PALETTE;
215 			fWebSafeMI->SetMarked(true);
216 			break;
217 	}
218 
219 	if (fColorCountMF->IsEnabled() &&
220 		fPrefs->palette_size_in_bits > 0 &&
221 		fPrefs->palette_size_in_bits <= 8) {
222 		// display the stored color count
223 		fColorCountMI[fPrefs->palette_size_in_bits - 1]->SetMarked(true);
224 	} else {
225 		// display 256 colors
226 		fColorCount256MI->SetMarked(true);
227 		fPrefs->palette_size_in_bits = 8;
228 	}
229 
230 	fInterlacedCB->SetValue(fPrefs->interlaced);
231 
232 	if (fGreyScaleMI->IsMarked()) fUseDitheringCB->SetValue(false);
233 	else fUseDitheringCB->SetValue(fPrefs->usedithering);
234 	fUseTransparentCB->SetValue(fPrefs->usetransparent);
235 	fUseTransparentAutoRB->SetValue(fPrefs->usetransparentauto);
236 	fUseTransparentColorRB->SetValue(!fPrefs->usetransparentauto);
237 	if (fPrefs->usetransparent) {
238 		fUseTransparentAutoRB->SetEnabled(true);
239 		fUseTransparentColorRB->SetEnabled(true);
240 		fTransparentRedTC->SetEnabled(!fPrefs->usetransparentauto);
241 		fTransparentGreenTC->SetEnabled(!fPrefs->usetransparentauto);
242 		fTransparentBlueTC->SetEnabled(!fPrefs->usetransparentauto);
243 	} else {
244 		fUseTransparentAutoRB->SetEnabled(false);
245 		fUseTransparentColorRB->SetEnabled(false);
246 		fTransparentRedTC->SetEnabled(false);
247 		fTransparentGreenTC->SetEnabled(false);
248 		fTransparentBlueTC->SetEnabled(false);
249 	}
250 
251 	char temp[4];
252 	sprintf(temp, "%d", fPrefs->transparentred);
253 	fTransparentRedTC->SetText(temp);
254 	sprintf(temp, "%d", fPrefs->transparentgreen);
255 	fTransparentGreenTC->SetText(temp);
256 	sprintf(temp, "%d", fPrefs->transparentblue);
257 	fTransparentBlueTC->SetText(temp);
258 }
259 
260 // AllAttached
261 void
262 GIFView::AllAttached()
263 {
264 	BView::AllAttached();
265 	BMessenger msgr(this);
266 	fInterlacedCB->SetTarget(msgr);
267 	fUseDitheringCB->SetTarget(msgr);
268 	fUseTransparentCB->SetTarget(msgr);
269 	fUseTransparentAutoRB->SetTarget(msgr);
270 	fUseTransparentColorRB->SetTarget(msgr);
271 	fTransparentRedTC->SetTarget(msgr);
272 	fTransparentGreenTC->SetTarget(msgr);
273 	fTransparentBlueTC->SetTarget(msgr);
274 	fPaletteM->SetTargetForItems(msgr);
275 	fColorCountM->SetTargetForItems(msgr);
276 }
277 
278 // MessageReceived
279 void
280 GIFView::MessageReceived(BMessage *message)
281 {
282 	switch (message->what) {
283 		case GV_WEB_SAFE:
284 			fPrefs->palettemode = WEB_SAFE_PALETTE;
285 			fUseDitheringCB->SetEnabled(true);
286 			fColorCountMF->SetEnabled(false);
287 			fColorCount256MI->SetMarked(true);
288 			break;
289 		case GV_BEOS_SYSTEM:
290 			fPrefs->palettemode = BEOS_SYSTEM_PALETTE;
291 			fUseDitheringCB->SetEnabled(true);
292 			fColorCountMF->SetEnabled(false);
293 			fColorCount256MI->SetMarked(true);
294 			break;
295 		case GV_GREYSCALE:
296 			fPrefs->palettemode = GREYSCALE_PALETTE;
297 			fUseDitheringCB->SetEnabled(false);
298 			fUseDitheringCB->SetValue(false);
299 			fColorCountMF->SetEnabled(false);
300 			fColorCount256MI->SetMarked(true);
301 			fPrefs->usedithering = false;
302 			break;
303 		case GV_OPTIMAL:
304 			fPrefs->palettemode = OPTIMAL_PALETTE;
305 			fUseDitheringCB->SetEnabled(true);
306 			fColorCountMF->SetEnabled(true);
307 			fColorCountMI[fPrefs->palette_size_in_bits - 1]->SetMarked(true);
308 			break;
309 		case GV_SET_COLOR_COUNT:
310 			if (fColorCountMF->IsEnabled()) {
311 				int32 sizeInBits;
312 				if (message->FindInt32("size in bits", &sizeInBits) >= B_OK) {
313 					if (sizeInBits > 0 && sizeInBits <= 8)
314 						fPrefs->palette_size_in_bits = sizeInBits;
315 				}
316 			}
317 			break;
318 		case GV_INTERLACED:
319 			fPrefs->interlaced = fInterlacedCB->Value();
320 			break;
321 		case GV_USE_DITHERING:
322 			fPrefs->usedithering = fUseDitheringCB->Value();
323 			break;
324 		case GV_USE_TRANSPARENT:
325 			fPrefs->usetransparent = fUseTransparentCB->Value();
326 			if (fPrefs->usetransparent) {
327 				fUseTransparentAutoRB->SetEnabled(true);
328 				fUseTransparentColorRB->SetEnabled(true);
329 				fTransparentRedTC->SetEnabled(fUseTransparentColorRB->Value());
330 				fTransparentGreenTC->SetEnabled(fUseTransparentColorRB->Value());
331 				fTransparentBlueTC->SetEnabled(fUseTransparentColorRB->Value());
332 			} else {
333 				fUseTransparentAutoRB->SetEnabled(false);
334 				fUseTransparentColorRB->SetEnabled(false);
335 				fTransparentRedTC->SetEnabled(false);
336 				fTransparentGreenTC->SetEnabled(false);
337 				fTransparentBlueTC->SetEnabled(false);
338 			}
339 			break;
340 		case GV_USE_TRANSPARENT_AUTO:
341 			fPrefs->usetransparentauto = true;
342 			fTransparentRedTC->SetEnabled(false);
343 			fTransparentGreenTC->SetEnabled(false);
344 			fTransparentBlueTC->SetEnabled(false);
345 			break;
346 		case GV_USE_TRANSPARENT_COLOR:
347 			fPrefs->usetransparentauto = false;
348 			fTransparentRedTC->SetEnabled(true);
349 			fTransparentGreenTC->SetEnabled(true);
350 			fTransparentBlueTC->SetEnabled(true);
351 			break;
352 		case GV_TRANSPARENT_RED:
353 			fPrefs->transparentred = CheckInput(fTransparentRedTC);
354 			break;
355 		case GV_TRANSPARENT_GREEN:
356 			fPrefs->transparentgreen = CheckInput(fTransparentGreenTC);
357 			break;
358 		case GV_TRANSPARENT_BLUE:
359 			fPrefs->transparentblue = CheckInput(fTransparentBlueTC);
360 			break;
361 		default:
362 			BView::MessageReceived(message);
363 			break;
364 	}
365 	fPrefs->Save();
366 }
367 
368 int GIFView::CheckInput(BTextControl *control) {
369 	int value = atoi(control->Text());
370 	if (value < 0 || value > 255) {
371 		value = (value < 0) ? 0 : 255;
372 		char temp[4];
373 		sprintf(temp, "%d", value);
374 		control->SetText(temp);
375 	}
376 	return value;
377 }
378 
379