xref: /haiku/src/apps/mediaplayer/playlist/PlaylistWindow.cpp (revision b30304acc8c37e678a1bf66976d15bdab103f931)
1 /*
2  * Copyright 2007, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus 	<superstippi@gmx.de>
7  *		Fredrik Modéen	<fredrik@modeen.se>
8  */
9 
10 #include "PlaylistWindow.h"
11 
12 #include <stdio.h>
13 
14 #include <Application.h>
15 #include <Roster.h>
16 #include <Path.h>
17 #include <Menu.h>
18 #include <MenuBar.h>
19 #include <MenuItem.h>
20 #include <ScrollBar.h>
21 #include <ScrollView.h>
22 #include <String.h>
23 #include <Box.h>
24 #include <Button.h>
25 #include <FilePanel.h>
26 
27 #include "CommandStack.h"
28 #include "PlaylistListView.h"
29 #include "RWLocker.h"
30 
31 #define DEBUG 1
32 
33 enum {
34 	M_PLAYLIST_OPEN		= 'open',
35 	M_PLAYLIST_SAVE		= 'save',
36 	M_PLAYLIST_EMPTY	= 'emty'
37 };
38 
39 #define SPACE 5
40 
41 PlaylistWindow::PlaylistWindow(BRect frame, Playlist* playlist,
42 		Controller* controller)
43 	: BWindow(frame, "Playlist", B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
44 		B_ASYNCHRONOUS_CONTROLS)
45 
46 	, fLocker(new RWLocker("command stack lock"))
47 	, fCommandStack(new CommandStack(fLocker))
48 	, fCommandStackListener(this)
49 {
50 	frame = Bounds();
51 
52 	_CreateMenu(frame);
53 		// will adjust frame to account for menubar
54 
55 	frame.right -= B_V_SCROLL_BAR_WIDTH;
56 	fListView = new PlaylistListView(frame, playlist, controller,
57 		fCommandStack);
58 
59 	BScrollView* scrollView = new BScrollView("playlist scrollview", fListView,
60 		B_FOLLOW_ALL_SIDES, 0, false, true, B_NO_BORDER);
61 
62 	fTopView = 	scrollView;
63 	AddChild(fTopView);
64 
65 	// small visual tweak
66 	if (BScrollBar* scrollBar = scrollView->ScrollBar(B_VERTICAL)) {
67 		// make it so the frame of the menubar is also the frame of
68 		// the scroll bar (appears to be)
69 		scrollBar->MoveBy(0, -1);
70 		scrollBar->ResizeBy(0, 1);
71 	}
72 
73 	fCommandStack->AddListener(&fCommandStackListener);
74 	_ObjectChanged(fCommandStack);
75 }
76 
77 
78 PlaylistWindow::~PlaylistWindow()
79 {
80 	// give listeners a chance to detach themselves
81 	fTopView->RemoveSelf();
82 	delete fTopView;
83 
84 	fCommandStack->RemoveListener(&fCommandStackListener);
85 	delete fCommandStack;
86 	delete fLocker;
87 }
88 
89 
90 bool
91 PlaylistWindow::QuitRequested()
92 {
93 	Hide();
94 	return false;
95 }
96 
97 
98 void
99 PlaylistWindow::MessageReceived(BMessage* message)
100 {
101 	switch (message->what) {
102 		case B_MODIFIERS_CHANGED:
103 			if (LastMouseMovedView())
104 				PostMessage(message, LastMouseMovedView());
105 			break;
106 
107 		case B_UNDO:
108 			fCommandStack->Undo();
109 			break;
110 		case B_REDO:
111 			fCommandStack->Redo();
112 			break;
113 
114 		case MSG_OBJECT_CHANGED: {
115 			Notifier* notifier;
116 			if (message->FindPointer("object", (void**)&notifier) == B_OK)
117 				_ObjectChanged(notifier);
118 			break;
119 		}
120 
121 		case B_REFS_RECEIVED:
122 		case B_SIMPLE_DATA: {
123 			// only accept this message when it comes from the
124 			// player window, _not_ when it is dropped in this window
125 			// outside of the playlist!
126 			int32 appendIndex;
127 			if (message->FindInt32("append_index", &appendIndex) == B_OK) {
128 				fListView->RefsReceived(message, appendIndex);
129 			}
130 			break;
131 		}
132 
133 		case M_PLAYLIST_SAVE:
134 			if (!fSavePanel)
135 				fSavePanel = new BFilePanel(B_SAVE_PANEL);
136 			fSavePanel->Show();
137 			break;
138 		case B_SAVE_REQUESTED:
139 			printf("We are saving\n");
140 			//Use fListView and have a SaveToFile?
141 			break;
142 		case M_PLAYLIST_OPEN:
143 			if (!fOpenPanel)
144 				fOpenPanel = new BFilePanel(B_OPEN_PANEL);
145 			fOpenPanel->Show();
146 			break;
147 		case M_PLAYLIST_EMPTY:
148 			break;
149 		default:
150 			BWindow::MessageReceived(message);
151 			break;
152 	}
153 }
154 
155 
156 // #pragma mark -
157 
158 
159 void
160 PlaylistWindow::_CreateMenu(BRect& frame)
161 {
162 	frame.bottom = 15;
163 	BMenuBar* menuBar = new BMenuBar(frame, "main menu");
164 	BMenu* fileMenu = new BMenu("Playlist");
165 	menuBar->AddItem(fileMenu);
166 //	fileMenu->AddItem(new BMenuItem("Open"B_UTF8_ELLIPSIS,
167 //		new BMessage(M_PLAYLIST_OPEN), 'O'));
168 //	fileMenu->AddItem(new BMenuItem("Save"B_UTF8_ELLIPSIS,
169 //		new BMessage(M_PLAYLIST_SAVE), 'S'));
170 //	fileMenu->AddSeparatorItem();
171 	fileMenu->AddItem(new BMenuItem("Close",
172 		new BMessage(B_QUIT_REQUESTED), 'W'));
173 
174 	BMenu* editMenu = new BMenu("Edit");
175 	fUndoMI = new BMenuItem("Undo", new BMessage(B_UNDO), 'Z');
176 	editMenu->AddItem(fUndoMI);
177 	fRedoMI = new BMenuItem("Redo", new BMessage(B_REDO), 'Z', B_SHIFT_KEY);
178 	editMenu->AddItem(fRedoMI);
179 	editMenu->AddSeparatorItem();
180 	editMenu->AddItem(new BMenuItem("Make Empty",
181 		new BMessage(M_PLAYLIST_EMPTY), 'N'));
182 	menuBar->AddItem(editMenu);
183 
184 	AddChild(menuBar);
185 	fileMenu->SetTargetForItems(this);
186 	editMenu->SetTargetForItems(this);
187 
188 	menuBar->ResizeToPreferred();
189 	frame = Bounds();
190 	frame.top = menuBar->Frame().bottom + 1;
191 }
192 
193 
194 // _ObjectChanged
195 void
196 PlaylistWindow::_ObjectChanged(const Notifier* object)
197 {
198 	if (object == fCommandStack) {
199 		// relable Undo item and update enabled status
200 		BString label("Undo");
201 		fUndoMI->SetEnabled(fCommandStack->GetUndoName(label));
202 		if (fUndoMI->IsEnabled())
203 			fUndoMI->SetLabel(label.String());
204 		else
205 			fUndoMI->SetLabel("<nothing to undo>");
206 
207 		// relable Redo item and update enabled status
208 		label.SetTo("Redo");
209 		fRedoMI->SetEnabled(fCommandStack->GetRedoName(label));
210 		if (fRedoMI->IsEnabled())
211 			fRedoMI->SetLabel(label.String());
212 		else
213 			fRedoMI->SetLabel("<nothing to redo>");
214 	}
215 }
216 
217