xref: /haiku/src/apps/expander/DirectoryFilePanel.cpp (revision 93a78ecaa45114d68952d08c4778f073515102f2)
1 /*
2  * Copyright 2004-2007, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval
7  */
8 
9 
10 #include "DirectoryFilePanel.h"
11 
12 #include <Window.h>
13 
14 #include <stdio.h>
15 #include <string.h>
16 
17 
18 DirectoryRefFilter::DirectoryRefFilter()
19 	: BRefFilter()
20 {
21 }
22 
23 
24 bool
25 DirectoryRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat *st,
26 	const char *filetype)
27 {
28 	return node->IsDirectory();
29 }
30 
31 
32 //	#pragma mark -
33 
34 
35 DirectoryFilePanel::DirectoryFilePanel(file_panel_mode mode, BMessenger *target,
36 		const entry_ref *startDirectory, uint32 nodeFlavors,
37 		bool allowMultipleSelection, BMessage *message, BRefFilter *filter,
38 		bool modal,	bool hideWhenDone)
39 	: BFilePanel(mode, target, startDirectory, nodeFlavors,
40 		allowMultipleSelection, message, filter, modal, hideWhenDone),
41 	fCurrentButton(NULL)
42 {
43 }
44 
45 
46 void
47 DirectoryFilePanel::Show()
48 {
49 	if (fCurrentButton == NULL) {
50 		Window()->Lock();
51 		BView* background = Window()->ChildAt(0);
52 		BView* cancel = background->FindView("cancel button");
53 
54 		BRect rect;
55 		if (cancel != NULL)
56 			rect = cancel->Frame();
57 		else {
58 			rect = background->Bounds();
59 			rect.left = rect.right;
60 			rect.top = rect.bottom - 35;
61 			rect.bottom -= 10;
62 		}
63 
64 		rect.right = rect.left -= 30;
65 		float width = be_plain_font->StringWidth("Select current") + 20;
66 		rect.left = width > 75 ? rect.right - width : rect.right - 75;
67 		fCurrentButton = new BButton(rect, "directoryButton", "Select current",
68 			new BMessage(MSG_DIRECTORY), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
69 
70 		background->AddChild(fCurrentButton);
71 		fCurrentButton->SetTarget(Messenger());
72 
73 		SetButtonLabel(B_DEFAULT_BUTTON, "Select");
74 		Window()->Unlock();
75 
76 		SelectionChanged();
77 	}
78 
79 	BFilePanel::Show();
80 }
81 
82 
83 void
84 DirectoryFilePanel::SelectionChanged()
85 {
86 	Window()->Lock();
87 
88 	char label[64];
89 	entry_ref ref;
90 	GetPanelDirectory(&ref);
91 	if (snprintf(label, sizeof(label), "Select '%s'", ref.name) >= (int)sizeof(label))
92 		strcpy(label + sizeof(label) - 5, B_UTF8_ELLIPSIS "'");
93 
94 	// Resize button so that the label fits
95 	// maximum width is dictated by the window's size limits
96 
97 	float dummy, maxWidth;
98 	Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy);
99 	maxWidth -= Window()->Bounds().Width() + 8 - fCurrentButton->Frame().right;
100 
101 	BRect oldBounds = fCurrentButton->Bounds();
102 	fCurrentButton->SetLabel(label);
103 	float width, height;
104 	fCurrentButton->GetPreferredSize(&width, &height);
105 	if (width > maxWidth)
106 		width = maxWidth;
107 	fCurrentButton->ResizeTo(width, oldBounds.Height());
108 	fCurrentButton->MoveBy(oldBounds.Width() - width, 0);
109 
110 	Window()->Unlock();
111 
112 	BFilePanel::SelectionChanged();
113 }
114