xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 13afa64231695bfa50edd375d99fa850ece3a156)
1*13afa642SPhil Greenway /*
2*13afa642SPhil Greenway     OBOS ShowImage 0.1 - 17/02/2002 - 22:22 - Fernando Francisco de Oliveira
3*13afa642SPhil Greenway */
4*13afa642SPhil Greenway 
5*13afa642SPhil Greenway #include <algobase.h>
6*13afa642SPhil Greenway #include <Application.h>
7*13afa642SPhil Greenway #include <Bitmap.h>
8*13afa642SPhil Greenway #include <Entry.h>
9*13afa642SPhil Greenway #include <Menu.h>
10*13afa642SPhil Greenway #include <MenuBar.h>
11*13afa642SPhil Greenway #include <MenuItem.h>
12*13afa642SPhil Greenway #include <Path.h>
13*13afa642SPhil Greenway #include <ScrollView.h>
14*13afa642SPhil Greenway #include <TranslationUtils.h>
15*13afa642SPhil Greenway #include <TranslatorRoster.h>
16*13afa642SPhil Greenway #include <Locker.h>
17*13afa642SPhil Greenway #include <Alert.h>
18*13afa642SPhil Greenway 
19*13afa642SPhil Greenway #include "ShowImageConstants.h"
20*13afa642SPhil Greenway #include "ShowImageWindow.h"
21*13afa642SPhil Greenway #include "ShowImageView.h"
22*13afa642SPhil Greenway #include "ShowImageStatusView.h"
23*13afa642SPhil Greenway 
24*13afa642SPhil Greenway BLocker ShowImageWindow::s_winListLocker("ShowImageWindow list lock");
25*13afa642SPhil Greenway BList ShowImageWindow::s_winList;
26*13afa642SPhil Greenway 
27*13afa642SPhil Greenway status_t ShowImageWindow::NewWindow(const entry_ref* ref)
28*13afa642SPhil Greenway {
29*13afa642SPhil Greenway 	BEntry entry(ref);
30*13afa642SPhil Greenway 	if (entry.InitCheck() == B_OK) {
31*13afa642SPhil Greenway 		BPath path;
32*13afa642SPhil Greenway 		entry.GetPath(&path);
33*13afa642SPhil Greenway 		if (path.InitCheck() == B_OK) {
34*13afa642SPhil Greenway 			BBitmap* pBitmap = BTranslationUtils::GetBitmap(path.Path());
35*13afa642SPhil Greenway 			if (pBitmap) {
36*13afa642SPhil Greenway 				ShowImageWindow* pWin = new ShowImageWindow(ref, pBitmap);
37*13afa642SPhil Greenway 				return pWin->InitCheck();
38*13afa642SPhil Greenway 			}
39*13afa642SPhil Greenway 		}
40*13afa642SPhil Greenway 	}
41*13afa642SPhil Greenway 	return B_ERROR;
42*13afa642SPhil Greenway }
43*13afa642SPhil Greenway 
44*13afa642SPhil Greenway int32 ShowImageWindow::CountWindows()
45*13afa642SPhil Greenway {
46*13afa642SPhil Greenway 	int32 count = -1;
47*13afa642SPhil Greenway 	if (s_winListLocker.Lock()) {
48*13afa642SPhil Greenway 		count = s_winList.CountItems();
49*13afa642SPhil Greenway 		s_winListLocker.Unlock();
50*13afa642SPhil Greenway 	}
51*13afa642SPhil Greenway 	return count;
52*13afa642SPhil Greenway }
53*13afa642SPhil Greenway 
54*13afa642SPhil Greenway ShowImageWindow::ShowImageWindow(const entry_ref* ref, BBitmap* pBitmap)
55*13afa642SPhil Greenway 	: BWindow(BRect(50, 50, 350, 250), "", B_DOCUMENT_WINDOW, 0),
56*13afa642SPhil Greenway 	m_pReferences(0)
57*13afa642SPhil Greenway {
58*13afa642SPhil Greenway 	SetPulseRate( 200000.0 );
59*13afa642SPhil Greenway 
60*13afa642SPhil Greenway 	// create menu bar
61*13afa642SPhil Greenway 	pBar = new BMenuBar( BRect(0,0, Bounds().right, 20), "menu_bar");
62*13afa642SPhil Greenway 	LoadMenus(pBar);
63*13afa642SPhil Greenway 	AddChild(pBar);
64*13afa642SPhil Greenway 
65*13afa642SPhil Greenway 	BRect viewFrame = Bounds();
66*13afa642SPhil Greenway //	viewFrame.left      += 20;
67*13afa642SPhil Greenway 	viewFrame.top		= pBar->Bounds().bottom+1;
68*13afa642SPhil Greenway 	viewFrame.right		-= B_V_SCROLL_BAR_WIDTH;
69*13afa642SPhil Greenway 	viewFrame.bottom	-= B_H_SCROLL_BAR_HEIGHT;
70*13afa642SPhil Greenway 
71*13afa642SPhil Greenway 	// create the image view
72*13afa642SPhil Greenway 	m_PrivateView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
73*13afa642SPhil Greenway 										B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED);
74*13afa642SPhil Greenway 	m_PrivateView->SetBitmap(pBitmap);
75*13afa642SPhil Greenway 
76*13afa642SPhil Greenway 	// wrap a scroll view around the view
77*13afa642SPhil Greenway 	BScrollView* pScrollView = new BScrollView("image_scroller", m_PrivateView, B_FOLLOW_ALL,
78*13afa642SPhil Greenway 		0, false, false, B_PLAIN_BORDER);
79*13afa642SPhil Greenway 
80*13afa642SPhil Greenway 	AddChild(pScrollView);
81*13afa642SPhil Greenway 
82*13afa642SPhil Greenway 	BScrollBar *hor_scroll;
83*13afa642SPhil Greenway 
84*13afa642SPhil Greenway 	BRect rect;
85*13afa642SPhil Greenway 
86*13afa642SPhil Greenway 	rect = Bounds();
87*13afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
88*13afa642SPhil Greenway 	rect.left 	= viewFrame.left   + 160;
89*13afa642SPhil Greenway 	rect.right	= viewFrame.right;
90*13afa642SPhil Greenway 
91*13afa642SPhil Greenway 	hor_scroll = new BScrollBar( rect, "hor_scroll", m_PrivateView, 0,150, B_HORIZONTAL );
92*13afa642SPhil Greenway 	AddChild( hor_scroll );
93*13afa642SPhil Greenway 
94*13afa642SPhil Greenway 	ShowImageStatusView * status_bar;
95*13afa642SPhil Greenway 
96*13afa642SPhil Greenway 	rect.left = 0;
97*13afa642SPhil Greenway 	rect.right = 159;
98*13afa642SPhil Greenway 
99*13afa642SPhil Greenway 	status_bar = new ShowImageStatusView( rect, "status_bar", B_FOLLOW_BOTTOM, B_WILL_DRAW );
100*13afa642SPhil Greenway 	status_bar->SetViewColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
101*13afa642SPhil Greenway 	status_bar->SetCaption( "ImageShow" );
102*13afa642SPhil Greenway 
103*13afa642SPhil Greenway 	AddChild( status_bar );
104*13afa642SPhil Greenway 
105*13afa642SPhil Greenway 	BScrollBar *vert_scroll;
106*13afa642SPhil Greenway 
107*13afa642SPhil Greenway 	rect = Bounds();
108*13afa642SPhil Greenway 	rect.top    = viewFrame.top;
109*13afa642SPhil Greenway 	rect.left 	= viewFrame.right + 1;
110*13afa642SPhil Greenway 	rect.bottom	= viewFrame.bottom;
111*13afa642SPhil Greenway 
112*13afa642SPhil Greenway 	vert_scroll = new BScrollBar( rect, "vert_scroll", m_PrivateView, 0,150, B_VERTICAL );
113*13afa642SPhil Greenway 	AddChild( vert_scroll );
114*13afa642SPhil Greenway 
115*13afa642SPhil Greenway 	WindowRedimension( pBitmap );
116*13afa642SPhil Greenway 
117*13afa642SPhil Greenway 	// finish creating window
118*13afa642SPhil Greenway 	SetRef(ref);
119*13afa642SPhil Greenway 	UpdateTitle();
120*13afa642SPhil Greenway 	if (s_winListLocker.Lock()) {
121*13afa642SPhil Greenway 		s_winList.AddItem(this);
122*13afa642SPhil Greenway 		s_winListLocker.Unlock();
123*13afa642SPhil Greenway 	}
124*13afa642SPhil Greenway 
125*13afa642SPhil Greenway 	m_PrivateView->pBar = pBar;
126*13afa642SPhil Greenway 
127*13afa642SPhil Greenway 	Show();
128*13afa642SPhil Greenway }
129*13afa642SPhil Greenway 
130*13afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
131*13afa642SPhil Greenway {
132*13afa642SPhil Greenway 	if (m_pReferences) {
133*13afa642SPhil Greenway 		delete m_pReferences;
134*13afa642SPhil Greenway 	}
135*13afa642SPhil Greenway 
136*13afa642SPhil Greenway 	if (s_winListLocker.Lock()) {
137*13afa642SPhil Greenway 		s_winList.RemoveItem(this);
138*13afa642SPhil Greenway 		s_winListLocker.Unlock();
139*13afa642SPhil Greenway 	}
140*13afa642SPhil Greenway 	if (CountWindows() < 1) {
141*13afa642SPhil Greenway 		be_app->PostMessage(B_QUIT_REQUESTED);
142*13afa642SPhil Greenway 	}
143*13afa642SPhil Greenway }
144*13afa642SPhil Greenway 
145*13afa642SPhil Greenway void ShowImageWindow::WindowActivated(bool active)
146*13afa642SPhil Greenway {
147*13afa642SPhil Greenway //	WindowRedimension( pBitmap );
148*13afa642SPhil Greenway }
149*13afa642SPhil Greenway 
150*13afa642SPhil Greenway status_t ShowImageWindow::InitCheck()
151*13afa642SPhil Greenway {
152*13afa642SPhil Greenway 	if (! m_pReferences) {
153*13afa642SPhil Greenway 		return B_ERROR;
154*13afa642SPhil Greenway 	} else {
155*13afa642SPhil Greenway 		return B_OK;
156*13afa642SPhil Greenway 	}
157*13afa642SPhil Greenway }
158*13afa642SPhil Greenway 
159*13afa642SPhil Greenway void ShowImageWindow::SetRef(const entry_ref* ref)
160*13afa642SPhil Greenway {
161*13afa642SPhil Greenway 	if (! m_pReferences) {
162*13afa642SPhil Greenway 		m_pReferences = new entry_ref(*ref);
163*13afa642SPhil Greenway 	} else {
164*13afa642SPhil Greenway 		*m_pReferences = *ref;
165*13afa642SPhil Greenway 	}
166*13afa642SPhil Greenway }
167*13afa642SPhil Greenway 
168*13afa642SPhil Greenway void ShowImageWindow::UpdateTitle()
169*13afa642SPhil Greenway {
170*13afa642SPhil Greenway 	BEntry entry(m_pReferences);
171*13afa642SPhil Greenway 	if (entry.InitCheck() == B_OK) {
172*13afa642SPhil Greenway 		BPath path;
173*13afa642SPhil Greenway 		entry.GetPath(&path);
174*13afa642SPhil Greenway 		if (path.InitCheck() == B_OK) {
175*13afa642SPhil Greenway 			SetTitle(path.Path());
176*13afa642SPhil Greenway 		}
177*13afa642SPhil Greenway 	}
178*13afa642SPhil Greenway }
179*13afa642SPhil Greenway 
180*13afa642SPhil Greenway void ShowImageWindow::LoadMenus(BMenuBar* pBar)
181*13afa642SPhil Greenway {
182*13afa642SPhil Greenway 	long unsigned int MSG_QUIT  = B_QUIT_REQUESTED;
183*13afa642SPhil Greenway 	long unsigned int MSG_ABOUT = B_ABOUT_REQUESTED;
184*13afa642SPhil Greenway 
185*13afa642SPhil Greenway 	BMenu* pMenu = new BMenu("File");
186*13afa642SPhil Greenway 
187*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Open", MSG_FILE_OPEN, 'O', 0, 'A', true );
188*13afa642SPhil Greenway 	pMenu->AddSeparatorItem();
189*13afa642SPhil Greenway 
190*13afa642SPhil Greenway //	BMenuItem * pMenuSaveAs = AddItemMenu( pMenu, "Save As...", MSG_FILE_SAVE, 'S', 0, 'W', true);
191*13afa642SPhil Greenway 
192*13afa642SPhil Greenway 	BMenu* pMenuSaveAs = new BMenu( "Save As...", B_ITEMS_IN_COLUMN );
193*13afa642SPhil Greenway 
194*13afa642SPhil Greenway 	pMenu->AddItem( pMenuSaveAs );
195*13afa642SPhil Greenway 
196*13afa642SPhil Greenway 
197*13afa642SPhil Greenway 	BTranslatorRoster *roster = BTranslatorRoster::Default();
198*13afa642SPhil Greenway 
199*13afa642SPhil Greenway 	int32 num_translators, i;
200*13afa642SPhil Greenway 	translator_id *translators;
201*13afa642SPhil Greenway 	const char *translator_name, *translator_info;
202*13afa642SPhil Greenway 	int32 translator_version;
203*13afa642SPhil Greenway 
204*13afa642SPhil Greenway 	roster->GetAllTranslators(&translators, &num_translators);
205*13afa642SPhil Greenway 
206*13afa642SPhil Greenway 	for (i=0;i<num_translators;i++) {
207*13afa642SPhil Greenway 
208*13afa642SPhil Greenway 		roster->GetTranslatorInfo(translators[i], &translator_name,
209*13afa642SPhil Greenway 			&translator_info, &translator_version);
210*13afa642SPhil Greenway 
211*13afa642SPhil Greenway 		BMenuItem * pSubMenu = new BMenuItem( translator_name , NULL );
212*13afa642SPhil Greenway 
213*13afa642SPhil Greenway 		pMenuSaveAs->AddItem( pSubMenu );
214*13afa642SPhil Greenway 		//printf("%s: %s (%.2f)n", translator_name, translator_info, translator_version/100.);
215*13afa642SPhil Greenway 	}
216*13afa642SPhil Greenway 
217*13afa642SPhil Greenway 	delete [] translators; // clean up our droppings
218*13afa642SPhil Greenway 
219*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Close", MSG_QUIT, 'W', 0, 'A', true);
220*13afa642SPhil Greenway 	pMenu->AddSeparatorItem();
221*13afa642SPhil Greenway 	AddItemMenu( pMenu, "About ShowImage...", MSG_ABOUT, 0, 0, 'A', true);
222*13afa642SPhil Greenway 	pMenu->AddSeparatorItem();
223*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Quit", MSG_QUIT, 'Q', 0, 'A', true);
224*13afa642SPhil Greenway 
225*13afa642SPhil Greenway 	pBar->AddItem(pMenu);
226*13afa642SPhil Greenway 
227*13afa642SPhil Greenway 	pMenu = new BMenu("Edit");
228*13afa642SPhil Greenway 
229*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Undo", B_UNDO, 'Z', 0, 'W', false);
230*13afa642SPhil Greenway 	pMenu->AddSeparatorItem();
231*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Cut", B_CUT, 'X', 0, 'W', false);
232*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Copy", B_COPY, 'C', 0, 'W', false);
233*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Paste", B_PASTE, 'V', 0, 'W', false);
234*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
235*13afa642SPhil Greenway 	pMenu->AddSeparatorItem();
236*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
237*13afa642SPhil Greenway 
238*13afa642SPhil Greenway 	pBar->AddItem(pMenu);
239*13afa642SPhil Greenway 
240*13afa642SPhil Greenway 	pMenu = new BMenu("Image");
241*13afa642SPhil Greenway 	AddItemMenu( pMenu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true);
242*13afa642SPhil Greenway 	pBar->AddItem(pMenu);
243*13afa642SPhil Greenway }
244*13afa642SPhil Greenway 
245*13afa642SPhil Greenway BMenuItem * ShowImageWindow::AddItemMenu( BMenu *pMenu, char *Caption, long unsigned int msg,
246*13afa642SPhil Greenway 		char shortcut, uint32 modifier, char target, bool enabled ) {
247*13afa642SPhil Greenway 
248*13afa642SPhil Greenway 	BMenuItem* pItem;
249*13afa642SPhil Greenway 
250*13afa642SPhil Greenway 	pItem = new BMenuItem( Caption, new BMessage(msg), shortcut );
251*13afa642SPhil Greenway 
252*13afa642SPhil Greenway 	if ( target == 'A' )
253*13afa642SPhil Greenway 	   pItem->SetTarget(be_app);
254*13afa642SPhil Greenway 
255*13afa642SPhil Greenway 	pItem->SetEnabled( enabled );
256*13afa642SPhil Greenway 	pMenu->AddItem(pItem);
257*13afa642SPhil Greenway 
258*13afa642SPhil Greenway 	return( pItem );
259*13afa642SPhil Greenway }
260*13afa642SPhil Greenway 
261*13afa642SPhil Greenway void ShowImageWindow::WindowRedimension( BBitmap *pBitmap )
262*13afa642SPhil Greenway {
263*13afa642SPhil Greenway 	// set the window's min & max size limits
264*13afa642SPhil Greenway 	// based on document's data bounds
265*13afa642SPhil Greenway 	float maxWidth = pBitmap->Bounds().Width() + B_V_SCROLL_BAR_WIDTH;
266*13afa642SPhil Greenway 	float maxHeight = pBitmap->Bounds().Height()
267*13afa642SPhil Greenway 		+ pBar->Frame().Height()
268*13afa642SPhil Greenway 		+ B_H_SCROLL_BAR_HEIGHT + 1;
269*13afa642SPhil Greenway 	float minWidth = min(maxWidth, 100.0f);
270*13afa642SPhil Greenway 	float minHeight = min(maxHeight, 100.0f);
271*13afa642SPhil Greenway 
272*13afa642SPhil Greenway 	// adjust the window's current size based on new min/max values
273*13afa642SPhil Greenway 	float curWidth = Bounds().Width();
274*13afa642SPhil Greenway 	float curHeight = Bounds().Height();
275*13afa642SPhil Greenway 	if (curWidth < minWidth) {
276*13afa642SPhil Greenway 		curWidth = minWidth;
277*13afa642SPhil Greenway 	} else if (curWidth > maxWidth) {
278*13afa642SPhil Greenway 		curWidth = maxWidth;
279*13afa642SPhil Greenway 	}
280*13afa642SPhil Greenway 	if (curHeight < minHeight) {
281*13afa642SPhil Greenway 		curHeight = minHeight;
282*13afa642SPhil Greenway 	} else if (curHeight > maxHeight) {
283*13afa642SPhil Greenway 		curHeight = maxHeight;
284*13afa642SPhil Greenway 	}
285*13afa642SPhil Greenway 	if ( minWidth < 250 ) {
286*13afa642SPhil Greenway 		minWidth = 250;
287*13afa642SPhil Greenway 	}
288*13afa642SPhil Greenway 	SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
289*13afa642SPhil Greenway 	ResizeTo(curWidth, curHeight);
290*13afa642SPhil Greenway }
291*13afa642SPhil Greenway 
292*13afa642SPhil Greenway void ShowImageWindow::FrameResized( float new_width, float new_height )
293*13afa642SPhil Greenway {
294*13afa642SPhil Greenway }
295*13afa642SPhil Greenway 
296*13afa642SPhil Greenway void ShowImageWindow::MessageReceived(BMessage* message)
297*13afa642SPhil Greenway {
298*13afa642SPhil Greenway 	BAlert* pAlert;
299*13afa642SPhil Greenway 
300*13afa642SPhil Greenway 	switch (message->what) {
301*13afa642SPhil Greenway 	case MSG_FILE_SAVE :
302*13afa642SPhil Greenway 	     pAlert = new BAlert( "File/Save",
303*13afa642SPhil Greenway 				  			  "File/Save not implemented yet", "OK");
304*13afa642SPhil Greenway   		 pAlert->Go();
305*13afa642SPhil Greenway 		 break;
306*13afa642SPhil Greenway 	case B_UNDO :
307*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Undo",
308*13afa642SPhil Greenway 				  			  "Edit/Undo not implemented yet", "OK");
309*13afa642SPhil Greenway   		 pAlert->Go();
310*13afa642SPhil Greenway 		break;
311*13afa642SPhil Greenway 	case B_CUT :
312*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Cut",
313*13afa642SPhil Greenway 				  			  "Edit/Cut not implemented yet", "OK");
314*13afa642SPhil Greenway   		 pAlert->Go();
315*13afa642SPhil Greenway 		break;
316*13afa642SPhil Greenway 	case B_COPY :
317*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Copy",
318*13afa642SPhil Greenway 				  			  "Edit/Copy not implemented yet", "OK");
319*13afa642SPhil Greenway   		 pAlert->Go();
320*13afa642SPhil Greenway 		break;
321*13afa642SPhil Greenway 	case B_PASTE :
322*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Paste",
323*13afa642SPhil Greenway 				  			  "Edit/Paste not implemented yet", "OK");
324*13afa642SPhil Greenway   		 pAlert->Go();
325*13afa642SPhil Greenway 		break;
326*13afa642SPhil Greenway 	case MSG_CLEAR_SELECT :
327*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Clear Select",
328*13afa642SPhil Greenway 				  			  "Edit/Clear Select not implemented yet", "OK");
329*13afa642SPhil Greenway   		 pAlert->Go();
330*13afa642SPhil Greenway 		break;
331*13afa642SPhil Greenway 	case MSG_SELECT_ALL :
332*13afa642SPhil Greenway 	     pAlert = new BAlert( "Edit/Select All",
333*13afa642SPhil Greenway 				  			  "Edit/Select All not implemented yet", "OK");
334*13afa642SPhil Greenway   		 pAlert->Go();
335*13afa642SPhil Greenway 		break;
336*13afa642SPhil Greenway 	case MSG_DITHER_IMAGE :
337*13afa642SPhil Greenway 	     BMenuItem   * pMenuDither;
338*13afa642SPhil Greenway 	     pMenuDither = pBar->FindItem( message->what );
339*13afa642SPhil Greenway 	     pMenuDither->SetMarked( ! pMenuDither->IsMarked() );
340*13afa642SPhil Greenway 
341*13afa642SPhil Greenway 		 break;
342*13afa642SPhil Greenway 
343*13afa642SPhil Greenway 	default:
344*13afa642SPhil Greenway 		BWindow::MessageReceived(message);
345*13afa642SPhil Greenway 		break;
346*13afa642SPhil Greenway 	}
347*13afa642SPhil Greenway }
348*13afa642SPhil Greenway // 		BMenu* pMenuDither = ;
349