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