2 * Copyright 2005-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
11 #include <Application.h>
13 #include <MenuField.h>
15 #include <PopUpMenu.h>
19 #include <WindowPrivate.h>
25 const uint32 kMsgUpdateLook
= 'uplk';
26 const uint32 kMsgUpdateFeel
= 'upfe';
27 const uint32 kMsgUpdateFlags
= 'upfl';
29 const uint32 kMsgAddWindow
= 'adwn';
30 const uint32 kMsgAddSubsetWindow
= 'adsw';
33 int32 gNormalWindowCount
= 0;
36 class Window
: public BWindow
{
38 Window(BRect frame
, window_look look
, window_feel feel
);
41 virtual void MessageReceived(BMessage
* message
);
42 virtual bool QuitRequested();
45 BMessage
* AddWindowMessage(window_look look
, window_feel feel
);
46 BString
TitleForFeel(window_feel feel
);
47 void _UpdateFlagsMenuLabel();
49 BMenuField
* fFlagsField
;
53 Window::Window(BRect frame
, window_look look
, window_feel feel
)
54 : BWindow(frame
, TitleForFeel(feel
).String(), look
, feel
,
55 B_ASYNCHRONOUS_CONTROLS
)
58 BView
*view
= new BView(rect
, NULL
, B_FOLLOW_ALL
, B_WILL_DRAW
);
59 view
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
62 if (!IsModal() && !IsFloating())
65 float labelWidth
= view
->StringWidth("Flags:") + 5.f
;
67 BPopUpMenu
* menu
= new BPopUpMenu("looks");
68 const struct { const char* name
; int32 look
; } looks
[] = {
69 {"Titled", B_TITLED_WINDOW_LOOK
}, {"Document", B_DOCUMENT_WINDOW_LOOK
},
70 {"Floating", B_FLOATING_WINDOW_LOOK
}, {"Modal", B_MODAL_WINDOW_LOOK
},
71 {"Bordered", B_BORDERED_WINDOW_LOOK
}, {"No Border", B_NO_BORDER_WINDOW_LOOK
},
72 {"Left Titled", kLeftTitledWindowLook
}, {"Desktop", kDesktopWindowLook
}
74 for (uint32 i
= 0; i
< sizeof(looks
) / sizeof(looks
[0]); i
++) {
75 BMessage
* message
= new BMessage(kMsgUpdateLook
);
76 message
->AddInt32("look", looks
[i
].look
);
77 BMenuItem
* item
= new BMenuItem(looks
[i
].name
, message
);
78 if (looks
[i
].look
== (int32
)Look())
79 item
->SetMarked(true);
85 BMenuField
* menuField
= new BMenuField(rect
, "look", "Look:", menu
);
86 menuField
->ResizeToPreferred();
87 menuField
->SetDivider(labelWidth
);
88 view
->AddChild(menuField
);
90 menu
= new BPopUpMenu("feels");
91 const struct { const char* name
; int32 feel
; } feels
[] = {
92 {"Normal", B_NORMAL_WINDOW_FEEL
},
93 {"Modal Subset", B_MODAL_SUBSET_WINDOW_FEEL
},
94 {"App Modal", B_MODAL_APP_WINDOW_FEEL
},
95 {"All Modal", B_MODAL_ALL_WINDOW_FEEL
},
96 {"Floating Subset", B_FLOATING_SUBSET_WINDOW_FEEL
},
97 {"App Floating", B_FLOATING_APP_WINDOW_FEEL
},
98 {"All Floating", B_FLOATING_ALL_WINDOW_FEEL
},
99 {"Menu", kMenuWindowFeel
},
100 {"WindowScreen", kWindowScreenFeel
},
101 {"Desktop", kDesktopWindowFeel
},
103 for (uint32 i
= 0; i
< sizeof(feels
) / sizeof(feels
[0]); i
++) {
104 BMessage
* message
= new BMessage(kMsgUpdateFeel
);
105 message
->AddInt32("feel", feels
[i
].feel
);
106 BMenuItem
* item
= new BMenuItem(feels
[i
].name
, message
);
107 if (feels
[i
].feel
== (int32
)Feel())
108 item
->SetMarked(true);
113 rect
.OffsetBy(0, menuField
->Bounds().Height() + 10);
114 menuField
= new BMenuField(rect
, "feel", "Feel:", menu
);
115 menuField
->ResizeToPreferred();
116 menuField
->SetDivider(labelWidth
);
117 view
->AddChild(menuField
);
119 menu
= new BPopUpMenu("none", false, false);
120 const struct { const char* name
; uint32 flag
; } flags
[] = {
121 {"Not Zoomable", B_NOT_ZOOMABLE
},
122 {"Not Closable", B_NOT_CLOSABLE
},
123 {"Not Movable", B_NOT_MOVABLE
},
124 {"Not Horizontally Resizable", B_NOT_H_RESIZABLE
},
125 {"Not Vertically Resizable", B_NOT_V_RESIZABLE
},
126 {"Outline Resize", B_OUTLINE_RESIZE
},
127 {"Accept First Click", B_WILL_ACCEPT_FIRST_CLICK
},
128 {"Not Anchored On Activate", B_NOT_ANCHORED_ON_ACTIVATE
},
129 {"Avoid Front", B_AVOID_FRONT
},
130 #if defined(__HAIKU__) || defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST)
131 {"Same Position In All Workspaces", B_SAME_POSITION_IN_ALL_WORKSPACES
},
134 for (uint32 i
= 0; i
< sizeof(flags
) / sizeof(flags
[0]); i
++) {
135 BMessage
* message
= new BMessage(kMsgUpdateFlags
);
136 message
->AddInt32("flag", flags
[i
].flag
);
137 BMenuItem
* item
= new BMenuItem(flags
[i
].name
, message
);
142 rect
.OffsetBy(0, menuField
->Bounds().Height() + 10);
143 fFlagsField
= new BMenuField(rect
, "flags", "Flags:", menu
);
144 fFlagsField
->ResizeToPreferred();
145 fFlagsField
->SetDivider(labelWidth
);
146 view
->AddChild(fFlagsField
);
150 rect
.OffsetBy(0, menuField
->Bounds().Height() + 10);
151 BButton
* button
= new BButton(rect
, "normal", "Add Normal Window",
152 AddWindowMessage(B_TITLED_WINDOW_LOOK
, B_NORMAL_WINDOW_FEEL
),
153 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
154 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
156 button
->GetPreferredSize(&width
, &height
);
157 button
->ResizeTo(rect
.Width(), height
);
158 view
->AddChild(button
);
162 rect
= button
->Frame();
163 rect
.OffsetBy(0, rect
.Height() + 5);
164 button
= new BButton(rect
, "modal_subset", "Add Modal Subset",
165 AddWindowMessage(B_MODAL_WINDOW_LOOK
, B_MODAL_SUBSET_WINDOW_FEEL
),
166 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
167 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
168 view
->AddChild(button
);
170 rect
.OffsetBy(0, rect
.Height() + 5);
171 button
= new BButton(rect
, "app_modal", "Add Application Modal",
172 AddWindowMessage(B_MODAL_WINDOW_LOOK
, B_MODAL_APP_WINDOW_FEEL
),
173 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
174 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
175 view
->AddChild(button
);
177 rect
.OffsetBy(0, rect
.Height() + 5);
178 button
= new BButton(rect
, "all_modal", "Add All Modal",
179 AddWindowMessage(B_MODAL_WINDOW_LOOK
, B_MODAL_ALL_WINDOW_FEEL
),
180 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
181 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
182 view
->AddChild(button
);
186 rect
= button
->Frame();
187 rect
.OffsetBy(0, rect
.Height() + 5);
188 button
= new BButton(rect
, "floating_subset", "Add Floating Subset",
189 AddWindowMessage(B_FLOATING_WINDOW_LOOK
, B_FLOATING_SUBSET_WINDOW_FEEL
),
190 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
191 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
192 view
->AddChild(button
);
194 rect
.OffsetBy(0, rect
.Height() + 5);
195 button
= new BButton(rect
, "app_floating", "Add Application Floating",
196 AddWindowMessage(B_FLOATING_WINDOW_LOOK
, B_FLOATING_APP_WINDOW_FEEL
),
197 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
198 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
199 view
->AddChild(button
);
201 rect
.OffsetBy(0, rect
.Height() + 5);
202 button
= new BButton(rect
, "all_floating", "Add All Floating",
203 AddWindowMessage(B_FLOATING_WINDOW_LOOK
, B_FLOATING_ALL_WINDOW_FEEL
),
204 B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
205 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
206 view
->AddChild(button
);
210 rect
.OffsetBy(0, rect
.Height() + 15);
211 button
= new BButton(rect
, "close", "Close Window",
212 new BMessage(B_QUIT_REQUESTED
), B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
,
213 B_WILL_DRAW
| B_NAVIGABLE
| B_FULL_UPDATE_ON_RESIZE
);
214 button
->ResizeToPreferred();
215 button
->MoveTo((rect
.Width() - button
->Bounds().Width()) / 2, rect
.top
);
216 view
->AddChild(button
);
218 ResizeTo(Bounds().Width(), button
->Frame().bottom
+ 10);
228 Window::MessageReceived(BMessage
* message
)
230 switch (message
->what
) {
234 if (message
->FindInt32("look", &look
) != B_OK
)
237 SetLook((window_look
)look
);
244 if (message
->FindInt32("feel", &feel
) != B_OK
)
247 if (!IsModal() && !IsFloating())
248 gNormalWindowCount
--;
250 SetFeel((window_feel
)feel
);
251 SetTitle(TitleForFeel((window_feel
)feel
).String());
253 if (!IsModal() && !IsFloating())
254 gNormalWindowCount
++;
258 case kMsgUpdateFlags
:
261 if (message
->FindInt32("flag", (int32
*)&flag
) != B_OK
)
265 if (message
->FindPointer("source", (void**)&item
) != B_OK
)
268 item
->SetMarked(!item
->IsMarked());
270 uint32 flags
= Flags();
271 if (item
->IsMarked())
277 _UpdateFlagsMenuLabel();
282 case kMsgAddSubsetWindow
:
285 if (message
->FindInt32("look", &look
) != B_OK
286 || message
->FindInt32("feel", &feel
) != B_OK
)
289 BWindow
* window
= new Window(Frame().OffsetByCopy(20, 20),
290 (window_look
)look
, (window_feel
)feel
);
292 if (message
->what
== kMsgAddSubsetWindow
) {
293 status_t status
= window
->AddToSubset(this);
294 if (status
!= B_OK
) {
296 snprintf(text
, sizeof(text
),
297 "Window could not be added to subset:\n\n\%s", strerror(status
));
298 (new BAlert("Alert", text
, "OK"))->Go(NULL
);
310 BWindow::MessageReceived(message
);
316 Window::QuitRequested()
318 if (!IsModal() && !IsFloating())
319 gNormalWindowCount
--;
321 if (gNormalWindowCount
< 1)
322 be_app
->PostMessage(B_QUIT_REQUESTED
);
329 Window::AddWindowMessage(window_look look
, window_feel feel
)
331 BMessage
* message
= new BMessage(kMsgAddWindow
);
333 if (feel
== B_FLOATING_SUBSET_WINDOW_FEEL
334 || feel
== B_MODAL_SUBSET_WINDOW_FEEL
)
335 message
->what
= kMsgAddSubsetWindow
;
337 message
->AddInt32("look", look
);
338 message
->AddInt32("feel", feel
);
345 Window::TitleForFeel(window_feel feel
)
347 BString title
= "Look&Feel - ";
349 switch ((uint32
)feel
) {
350 case B_NORMAL_WINDOW_FEEL
:
356 case B_MODAL_SUBSET_WINDOW_FEEL
:
357 title
+= "Modal Subset";
359 case B_MODAL_APP_WINDOW_FEEL
:
360 title
+= "Application Modal";
362 case B_MODAL_ALL_WINDOW_FEEL
:
363 title
+= "All Modal";
368 case B_FLOATING_SUBSET_WINDOW_FEEL
:
369 title
+= "Floating Subset";
371 case B_FLOATING_APP_WINDOW_FEEL
:
372 title
+= "Application Floating";
374 case B_FLOATING_ALL_WINDOW_FEEL
:
375 title
+= "All Floating";
378 // special/private feels
380 case kMenuWindowFeel
:
383 case kWindowScreenFeel
:
384 title
+= "WindowScreen";
386 case kDesktopWindowFeel
:
396 Window::_UpdateFlagsMenuLabel()
399 BMenu
* menu
= fFlagsField
->Menu();
401 for (int32 i
= 0; i
< menu
->CountItems(); i
++) {
402 BMenuItem
* item
= menu
->ItemAt(i
);
404 if (item
->IsMarked()) {
407 label
+= item
->Label();
414 menu
->Superitem()->SetLabel(label
.String());
421 class Application
: public BApplication
{
425 virtual void ReadyToRun();
429 Application::Application()
430 : BApplication("application/x-vnd.haiku-looknfeel")
436 Application::ReadyToRun()
438 Window
*window
= new Window(BRect(100, 100, 400, 420),
439 B_TITLED_WINDOW_LOOK
, B_NORMAL_WINDOW_FEEL
);
448 main(int argc
, char **argv
)
450 Application app
;// app;