xref: /haiku/src/add-ons/translators/sgi/SGIView.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
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 
82 	BPopUpMenu* menu = new BPopUpMenu("pick compression");
83 
84 	uint32 currentCompression = fSettings->SetGetInt32(SGI_SETTING_COMPRESSION);
85 	// create the menu items with the various compression methods
86 	add_menu_item(menu, SGI_COMP_NONE, "None", currentCompression);
87 //	menu->AddSeparatorItem();
88 	add_menu_item(menu, SGI_COMP_RLE, "RLE", currentCompression);
89 
90 // DON'T turn this on, it's so slow that I didn't wait long enough
91 // the one time I tested this. So I don't know if the code even works.
92 // Supposedly, this would look for an already written scanline, and
93 // modify the scanline tables so that the current row is not written
94 // at all...
95 
96 //	add_menu_item(menu, SGI_COMP_ARLE, "Agressive RLE", currentCompression);
97 
98 	BRect menuFrame = Bounds();
99 	menuFrame.bottom = menuFrame.top + menu->Bounds().Height();
100 	fCompressionMF = new BMenuField(menuFrame, "compression",
101 									"Use Compression:", menu, true/*,
102 									B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP*/);
103 	if (fCompressionMF->MenuBar())
104 		fCompressionMF->MenuBar()->ResizeToPreferred();
105 	fCompressionMF->ResizeToPreferred();
106 
107 	// figure out where the text ends
108 	font_height fh;
109 	be_bold_font->GetHeight(&fh);
110 	float xbold, ybold;
111 	xbold = fh.descent + 1;
112 	ybold = fh.ascent + fh.descent * 2 + fh.leading;
113 
114 	font_height plainh;
115 	be_plain_font->GetHeight(&plainh);
116 	float yplain;
117 	yplain = plainh.ascent + plainh.descent * 2 + plainh.leading;
118 
119 	// position the menu field below all the text we draw in Draw()
120 	BPoint textOffset(0.0, yplain * 2 + ybold);
121 	fCompressionMF->MoveTo(textOffset);
122 
123 	AddChild(fCompressionMF);
124 
125 	ResizeToPreferred();
126 }
127 
128 // ---------------------------------------------------------------
129 // Destructor
130 //
131 // Does nothing
132 //
133 // Preconditions:
134 //
135 // Parameters:
136 //
137 // Postconditions:
138 //
139 // Returns:
140 // ---------------------------------------------------------------
141 SGIView::~SGIView()
142 {
143 	fSettings->Release();
144 }
145 
146 // ---------------------------------------------------------------
147 // MessageReceived
148 //
149 // Handles state changes of the Compression menu field
150 //
151 // Preconditions:
152 //
153 // Parameters: area,	not used
154 //
155 // Postconditions:
156 //
157 // Returns:
158 // ---------------------------------------------------------------
159 void
160 SGIView::MessageReceived(BMessage* message)
161 {
162 	switch (message->what) {
163 		case MSG_COMPRESSION_CHANGED: {
164 			int32 value;
165 			if (message->FindInt32("value", &value) >= B_OK) {
166 				fSettings->SetGetInt32(SGI_SETTING_COMPRESSION, &value);
167 				fSettings->SaveSettings();
168 			}
169 			fCompressionMF->ResizeToPreferred();
170 			break;
171 		}
172 		default:
173 			BView::MessageReceived(message);
174 	}
175 }
176 
177 // ---------------------------------------------------------------
178 // AllAttached
179 //
180 // sets the target for the controls controlling the configuration
181 //
182 // Preconditions:
183 //
184 // Parameters: area,	not used
185 //
186 // Postconditions:
187 //
188 // Returns:
189 // ---------------------------------------------------------------
190 void
191 SGIView::AllAttached()
192 {
193 	fCompressionMF->Menu()->SetTargetForItems(this);
194 	fCompressionMF->ResizeToPreferred();
195 	fCompressionMF->SetDivider(fCompressionMF->StringWidth(fCompressionMF->Label()) + 3);
196 }
197 
198 // ---------------------------------------------------------------
199 // AttachedToWindow
200 //
201 // hack to make the window recognize our size
202 //
203 // Preconditions:
204 //
205 // Parameters: area,	not used
206 //
207 // Postconditions:
208 //
209 // Returns:
210 // ---------------------------------------------------------------
211 void
212 SGIView::AttachedToWindow()
213 {
214 	// Hack for DataTranslations which doesn't resize visible area to requested by view
215 	// which makes some parts of bigger than usual translationviews out of visible area
216 	// so if it was loaded to DataTranslations resize window if needed
217 	BWindow *window = Window();
218 	if (!strcmp(window->Name(), "DataTranslations")) {
219 		BView *view = Parent();
220 		if (view) {
221 			BRect frame = view->Frame();
222 			float x, y;
223 			GetPreferredSize(&x, &y);
224 			if (frame.Width() < x || (frame.Height() - 48) < y) {
225 				x -= frame.Width();
226 				y -= frame.Height() - 48;
227 				if (x < 0) x = 0;
228 				if (y < 0) y = 0;
229 
230 				// DataTranslations has main view called "Background"
231 				// change it's resizing mode so it will always resize with window
232 				// also make sure view will be redrawed after resize
233 				view = window->FindView("Background");
234 				if (view) {
235 					view->SetResizingMode(B_FOLLOW_ALL);
236 					view->SetFlags(B_FULL_UPDATE_ON_RESIZE);
237 				}
238 
239 				// The same with "Info..." button, except redrawing, which isn't needed
240 				view = window->FindView("Info…");
241 				if (view)
242 					view->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
243 
244 				window->ResizeBy( x, y);
245 			}
246 		}
247 	}
248 }
249 
250 // ---------------------------------------------------------------
251 // Draw
252 //
253 // Draws information about the SGITranslator to this view.
254 //
255 // Preconditions:
256 //
257 // Parameters: area,	not used
258 //
259 // Postconditions:
260 //
261 // Returns:
262 // ---------------------------------------------------------------
263 void
264 SGIView::Draw(BRect area)
265 {
266 	SetFont(be_bold_font);
267 	font_height fh;
268 	GetFontHeight(&fh);
269 	float xbold, ybold;
270 	xbold = fh.descent + 1;
271 	ybold = fh.ascent + fh.descent * 2 + fh.leading;
272 
273 	const char* text = "SGI Image Translator";
274 	DrawString(text, BPoint(xbold, ybold));
275 
276 	SetFont(be_plain_font);
277 	font_height plainh;
278 	GetFontHeight(&plainh);
279 	float yplain;
280 	yplain = plainh.ascent + plainh.descent * 2 + plainh.leading;
281 
282 	char detail[100];
283 	sprintf(detail, "Version %d.%d.%d %s",
284 		static_cast<int>(B_TRANSLATION_MAJOR_VERSION(SGI_TRANSLATOR_VERSION)),
285 		static_cast<int>(B_TRANSLATION_MINOR_VERSION(SGI_TRANSLATOR_VERSION)),
286 		static_cast<int>(B_TRANSLATION_REVISION_VERSION(SGI_TRANSLATOR_VERSION)),
287 		__DATE__);
288 	DrawString(detail, BPoint(xbold, yplain + ybold));
289 
290 	BPoint offset = fCompressionMF->Frame().LeftBottom();
291 	offset.x += xbold;
292 	offset.y += 2 * ybold;
293 
294 	text = "written by:";
295 	DrawString(text, offset);
296 	offset.y += ybold;
297 
298 	DrawString(author, offset);
299 	offset.y += 2 * ybold;
300 
301 	text = "based on GIMP SGI plugin v1.5:";
302 	DrawString(text, offset);
303 	offset.y += ybold;
304 
305 	DrawString(kSGICopyright, offset);
306 }
307 
308 // ---------------------------------------------------------------
309 // Draw
310 //
311 // calculated the preferred size of this view
312 //
313 // Preconditions:
314 //
315 // Parameters: width and height
316 //
317 // Postconditions:
318 //
319 // Returns: in width and height, the preferred size...
320 // ---------------------------------------------------------------
321 void
322 SGIView::GetPreferredSize(float* width, float* height)
323 {
324 	*width = fCompressionMF->Bounds().Width();
325 	// look at the two biggest strings
326 	float width1 = StringWidth(kSGICopyright) + 15.0;
327 	if (*width < width1)
328 		*width = width1;
329 	float width2 = be_plain_font->StringWidth(author) + 15.0;
330 	if (*width < width2)
331 		*width = width2;
332 
333 	font_height fh;
334 	be_bold_font->GetHeight(&fh);
335 	float ybold = fh.ascent + fh.descent * 2 + fh.leading;
336 
337 	*height = fCompressionMF->Bounds().bottom + 7 * ybold;
338 }
339