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