xref: /haiku/src/add-ons/translators/sgi/SGIView.cpp (revision 90ca02568835b140b0e59de496a7f1f1d3513f67)
1 /*****************************************************************************/
2 // SGIView
3 // Adopted by Stephan Aßmus, <stippi@yellowbites.com>
4 // from TIFFView written by
5 // Picking the compression method added by Stephan Aßmus, <stippi@yellowbites.com>
6 //
7 // SGIView.cpp
8 //
9 // This BView based object displays information about the SGITranslator.
10 //
11 //
12 // Copyright (c) 2003 OpenBeOS Project
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 /*****************************************************************************/
32 
33 #include <stdio.h>
34 #include <string.h>
35 
36 #include <MenuBar.h>
37 #include <MenuField.h>
38 #include <MenuItem.h>
39 #include <PopUpMenu.h>
40 #include <Window.h>
41 
42 #include "SGIImage.h"
43 #include "SGITranslator.h"
44 #include "SGIView.h"
45 
46 const char* author = "Stephan Aßmus, <stippi@yellowbites.com>";
47 
48 // add_menu_item
49 void
50 add_menu_item(BMenu* menu,
51 			  uint32 compression,
52 			  const char* label,
53 			  uint32 currentCompression)
54 {
55 	BMessage* message = new BMessage(SGIView::MSG_COMPRESSION_CHANGED);
56 	message->AddInt32("value", compression);
57 	BMenuItem* item = new BMenuItem(label, message);
58 	item->SetMarked(currentCompression == compression);
59 	menu->AddItem(item);
60 }
61 
62 // ---------------------------------------------------------------
63 // Constructor
64 //
65 // Sets up the view settings
66 //
67 // Preconditions:
68 //
69 // Parameters:
70 //
71 // Postconditions:
72 //
73 // Returns:
74 // ---------------------------------------------------------------
75 SGIView::SGIView(const BRect &frame, const char *name,
76 	uint32 resize, uint32 flags, TranslatorSettings *settings)
77 	:	BView(frame, name, resize, flags),
78 		fSettings(settings)
79 {
80 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
81 	SetLowColor(ViewColor());
82 
83 	BPopUpMenu* menu = new BPopUpMenu("pick compression");
84 
85 	uint32 currentCompression = fSettings->SetGetInt32(SGI_SETTING_COMPRESSION);
86 	// create the menu items with the various compression methods
87 	add_menu_item(menu, SGI_COMP_NONE, "None", currentCompression);
88 //	menu->AddSeparatorItem();
89 	add_menu_item(menu, SGI_COMP_RLE, "RLE", currentCompression);
90 
91 // DON'T turn this on, it's so slow that I didn't wait long enough
92 // the one time I tested this. So I don't know if the code even works.
93 // Supposedly, this would look for an already written scanline, and
94 // modify the scanline tables so that the current row is not written
95 // at all...
96 
97 //	add_menu_item(menu, SGI_COMP_ARLE, "Agressive RLE", currentCompression);
98 
99 	BRect menuFrame = Bounds();
100 	menuFrame.bottom = menuFrame.top + menu->Bounds().Height();
101 	fCompressionMF = new BMenuField(menuFrame, "compression",
102 									"Use Compression:", menu, true/*,
103 									B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP*/);
104 	if (fCompressionMF->MenuBar())
105 		fCompressionMF->MenuBar()->ResizeToPreferred();
106 	fCompressionMF->ResizeToPreferred();
107 
108 	// figure out where the text ends
109 	font_height fh;
110 	be_bold_font->GetHeight(&fh);
111 	float xbold, ybold;
112 	xbold = fh.descent + 1;
113 	ybold = fh.ascent + fh.descent * 2 + fh.leading;
114 
115 	font_height plainh;
116 	be_plain_font->GetHeight(&plainh);
117 	float yplain;
118 	yplain = plainh.ascent + plainh.descent * 2 + plainh.leading;
119 
120 	// position the menu field below all the text we draw in Draw()
121 	BPoint textOffset(0.0, yplain * 2 + ybold);
122 	fCompressionMF->MoveTo(textOffset);
123 
124 	AddChild(fCompressionMF);
125 
126 	ResizeToPreferred();
127 }
128 
129 // ---------------------------------------------------------------
130 // Destructor
131 //
132 // Does nothing
133 //
134 // Preconditions:
135 //
136 // Parameters:
137 //
138 // Postconditions:
139 //
140 // Returns:
141 // ---------------------------------------------------------------
142 SGIView::~SGIView()
143 {
144 	fSettings->Release();
145 }
146 
147 // ---------------------------------------------------------------
148 // MessageReceived
149 //
150 // Handles state changes of the Compression menu field
151 //
152 // Preconditions:
153 //
154 // Parameters: area,	not used
155 //
156 // Postconditions:
157 //
158 // Returns:
159 // ---------------------------------------------------------------
160 void
161 SGIView::MessageReceived(BMessage* message)
162 {
163 	switch (message->what) {
164 		case MSG_COMPRESSION_CHANGED: {
165 			int32 value;
166 			if (message->FindInt32("value", &value) >= B_OK) {
167 				fSettings->SetGetInt32(SGI_SETTING_COMPRESSION, &value);
168 				fSettings->SaveSettings();
169 			}
170 			fCompressionMF->ResizeToPreferred();
171 			break;
172 		}
173 		default:
174 			BView::MessageReceived(message);
175 	}
176 }
177 
178 // ---------------------------------------------------------------
179 // AllAttached
180 //
181 // sets the target for the controls controlling the configuration
182 //
183 // Preconditions:
184 //
185 // Parameters: area,	not used
186 //
187 // Postconditions:
188 //
189 // Returns:
190 // ---------------------------------------------------------------
191 void
192 SGIView::AllAttached()
193 {
194 	fCompressionMF->Menu()->SetTargetForItems(this);
195 	fCompressionMF->ResizeToPreferred();
196 	fCompressionMF->SetDivider(fCompressionMF->StringWidth(fCompressionMF->Label()) + 3);
197 }
198 
199 // ---------------------------------------------------------------
200 // AttachedToWindow
201 //
202 // hack to make the window recognize our size
203 //
204 // Preconditions:
205 //
206 // Parameters: area,	not used
207 //
208 // Postconditions:
209 //
210 // Returns:
211 // ---------------------------------------------------------------
212 void
213 SGIView::AttachedToWindow()
214 {
215 	// Hack for DataTranslations which doesn't resize visible area to requested by view
216 	// which makes some parts of bigger than usual translationviews out of visible area
217 	// so if it was loaded to DataTranslations resize window if needed
218 	BWindow *window = Window();
219 	if (!strcmp(window->Name(), "DataTranslations")) {
220 		BView *view = Parent();
221 		if (view) {
222 			BRect frame = view->Frame();
223 			float x, y;
224 			GetPreferredSize(&x, &y);
225 			if (frame.Width() < x || (frame.Height() - 48) < y) {
226 				x -= frame.Width();
227 				y -= frame.Height() - 48;
228 				if (x < 0) x = 0;
229 				if (y < 0) y = 0;
230 
231 				// DataTranslations has main view called "Background"
232 				// change it's resizing mode so it will always resize with window
233 				// also make sure view will be redrawed after resize
234 				view = window->FindView("Background");
235 				if (view) {
236 					view->SetResizingMode(B_FOLLOW_ALL);
237 					view->SetFlags(B_FULL_UPDATE_ON_RESIZE);
238 				}
239 
240 				// The same with "Info..." button, except redrawing, which isn't needed
241 				view = window->FindView("Info" B_UTF8_ELLIPSIS);
242 				if (view)
243 					view->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
244 
245 				window->ResizeBy( x, y);
246 			}
247 		}
248 	}
249 }
250 
251 // ---------------------------------------------------------------
252 // Draw
253 //
254 // Draws information about the SGITranslator to this view.
255 //
256 // Preconditions:
257 //
258 // Parameters: area,	not used
259 //
260 // Postconditions:
261 //
262 // Returns:
263 // ---------------------------------------------------------------
264 void
265 SGIView::Draw(BRect area)
266 {
267 	SetFont(be_bold_font);
268 	font_height fh;
269 	GetFontHeight(&fh);
270 	float xbold, ybold;
271 	xbold = fh.descent + 1;
272 	ybold = fh.ascent + fh.descent * 2 + fh.leading;
273 
274 	const char* text = "SGI Image Translator";
275 	DrawString(text, BPoint(xbold, ybold));
276 
277 	SetFont(be_plain_font);
278 	font_height plainh;
279 	GetFontHeight(&plainh);
280 	float yplain;
281 	yplain = plainh.ascent + plainh.descent * 2 + plainh.leading;
282 
283 	char detail[100];
284 	sprintf(detail, "Version %d.%d.%d %s",
285 		static_cast<int>(B_TRANSLATION_MAJOR_VERSION(SGI_TRANSLATOR_VERSION)),
286 		static_cast<int>(B_TRANSLATION_MINOR_VERSION(SGI_TRANSLATOR_VERSION)),
287 		static_cast<int>(B_TRANSLATION_REVISION_VERSION(SGI_TRANSLATOR_VERSION)),
288 		__DATE__);
289 	DrawString(detail, BPoint(xbold, yplain + ybold));
290 
291 	BPoint offset = fCompressionMF->Frame().LeftBottom();
292 	offset.x += xbold;
293 	offset.y += 2 * ybold;
294 
295 	text = "written by:";
296 	DrawString(text, offset);
297 	offset.y += ybold;
298 
299 	DrawString(author, offset);
300 	offset.y += 2 * ybold;
301 
302 	text = "based on GIMP SGI plugin v1.5:";
303 	DrawString(text, offset);
304 	offset.y += ybold;
305 
306 	DrawString(kSGICopyright, offset);
307 }
308 
309 // ---------------------------------------------------------------
310 // Draw
311 //
312 // calculated the preferred size of this view
313 //
314 // Preconditions:
315 //
316 // Parameters: width and height
317 //
318 // Postconditions:
319 //
320 // Returns: in width and height, the preferred size...
321 // ---------------------------------------------------------------
322 void
323 SGIView::GetPreferredSize(float* width, float* height)
324 {
325 	*width = fCompressionMF->Bounds().Width();
326 	// look at the two biggest strings
327 	float width1 = StringWidth(kSGICopyright) + 15.0;
328 	if (*width < width1)
329 		*width = width1;
330 	float width2 = be_plain_font->StringWidth(author) + 15.0;
331 	if (*width < width2)
332 		*width = width2;
333 
334 	font_height fh;
335 	be_bold_font->GetHeight(&fh);
336 	float ybold = fh.ascent + fh.descent * 2 + fh.leading;
337 
338 	*height = fCompressionMF->Bounds().bottom + 7 * ybold;
339 }
340