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