xref: /haiku/src/apps/expander/DirectoryFilePanel.cpp (revision f23596149e0d173463f70629581aa10cc305d32e)
1 /*
2  * Copyright 2004-2006, 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 		fCurrentButton = new BButton(rect, "directoryButton", "Select current",
65 			new BMessage(MSG_DIRECTORY), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
66 		fCurrentButton->ResizeToPreferred();
67 		fCurrentButton->MoveBy(-fCurrentButton->Bounds().Width() - 30, 0);
68 		background->AddChild(fCurrentButton);
69 		fCurrentButton->SetTarget(Messenger());
70 
71 		SetButtonLabel(B_DEFAULT_BUTTON, "Select");
72 		Window()->Unlock();
73 
74 		SelectionChanged();
75 	}
76 
77 	BFilePanel::Show();
78 }
79 
80 
81 void
82 DirectoryFilePanel::SelectionChanged(void)
83 {
84 	Window()->Lock();
85 
86 	char label[64];
87 	entry_ref ref;
88 	GetPanelDirectory(&ref);
89 	if (snprintf(label, sizeof(label), "Select '%s'", ref.name) >= (int)sizeof(label))
90 		strcpy(label + sizeof(label) - 5, B_UTF8_ELLIPSIS "'");
91 
92 	// Resize button so that the label fits
93 	// maximum width is dictated by the window's size limits
94 
95 	float dummy, maxWidth;
96 	Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy);
97 	maxWidth -= Window()->Bounds().Width() + 8 - fCurrentButton->Frame().right;
98 
99 	float oldWidth = fCurrentButton->Bounds().Width();
100 	fCurrentButton->SetLabel(label);
101 	float width, height;
102 	fCurrentButton->GetPreferredSize(&width, &height);
103 	if (width > maxWidth)
104 		width = maxWidth;
105 	fCurrentButton->ResizeTo(width, height);
106 	fCurrentButton->MoveBy(oldWidth - width, 0);
107 
108 	Window()->Unlock();
109 
110 	BFilePanel::SelectionChanged();
111 }
112