tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / preferences / backgrounds / BackgroundsView.cpp
blobd80a7e0eb68e9ba25f3a504a4cd2c41fd2547ffd
1 /*
2 * Copyright 2002-2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Jerome Duval, jerome.duval@free.fr
8 * Jonas Sundström, jonas@kirilla.se
9 * John Scipione, jscipione@gmail.com
13 #include "BackgroundsView.h"
15 #include <stdio.h>
16 #include <stdlib.h>
18 #include <Bitmap.h>
19 #include <Catalog.h>
20 #include <ControlLook.h>
21 #include <Cursor.h>
22 #include <Debug.h>
23 #include <File.h>
24 #include <FindDirectory.h>
25 #include <LayoutBuilder.h>
26 #include <Locale.h>
27 #include <MenuField.h>
28 #include <Messenger.h>
29 #include <MimeType.h>
30 #include <Point.h>
31 #include <PopUpMenu.h>
33 #include <be_apps/Tracker/Background.h>
35 #include "ImageFilePanel.h"
38 #undef B_TRANSLATION_CONTEXT
39 #define B_TRANSLATION_CONTEXT "Main View"
42 static const uint32 kMsgApplySettings = 'aply';
43 static const uint32 kMsgRevertSettings = 'rvrt';
45 static const uint32 kMsgUpdateColor = 'upcl';
46 static const uint32 kMsgAllWorkspaces = 'alwk';
47 static const uint32 kMsgCurrentWorkspace = 'crwk';
48 static const uint32 kMsgDefaultFolder = 'dffl';
49 static const uint32 kMsgOtherFolder = 'otfl';
50 static const uint32 kMsgNoImage = 'noim';
51 static const uint32 kMsgOtherImage = 'otim';
52 static const uint32 kMsgImageSelected = 'imsl';
53 static const uint32 kMsgFolderSelected = 'flsl';
55 static const uint32 kMsgCenterPlacement = 'cnpl';
56 static const uint32 kMsgManualPlacement = 'mnpl';
57 static const uint32 kMsgScalePlacement = 'scpl';
58 static const uint32 kMsgTilePlacement = 'tlpl';
59 static const uint32 kMsgIconLabelOutline = 'ilol';
61 static const uint32 kMsgImagePlacement = 'xypl';
62 static const uint32 kMsgUpdatePreviewPlacement = 'pvpl';
65 BackgroundsView::BackgroundsView()
67 BBox("BackgroundsView"),
68 fCurrent(NULL),
69 fCurrentInfo(NULL),
70 fLastImageIndex(-1),
71 fPathList(1, true),
72 fImageList(1, true),
73 fFoundPositionSetting(false)
75 SetBorder(B_NO_BORDER);
77 BBox* previewBox = new BBox("preview");
78 previewBox->SetLabel(B_TRANSLATE("Preview"));
80 fPreview = new Preview();
82 fTopLeft = new FramePart(FRAME_TOP_LEFT);
83 fTop = new FramePart(FRAME_TOP);
84 fTopRight = new FramePart(FRAME_TOP_RIGHT);
85 fLeft = new FramePart(FRAME_LEFT_SIDE);
86 fRight = new FramePart(FRAME_RIGHT_SIDE);
87 fBottomLeft = new FramePart(FRAME_BOTTOM_LEFT);
88 fBottom = new FramePart(FRAME_BOTTOM);
89 fBottomRight = new FramePart(FRAME_BOTTOM_RIGHT);
91 fXPlacementText = new BTextControl(B_TRANSLATE("X:"), NULL,
92 new BMessage(kMsgImagePlacement));
93 fYPlacementText = new BTextControl(B_TRANSLATE("Y:"), NULL,
94 new BMessage(kMsgImagePlacement));
96 fXPlacementText->TextView()->SetMaxBytes(5);
97 fYPlacementText->TextView()->SetMaxBytes(5);
99 for (int32 i = 0; i < 256; i++) {
100 if ((i < '0' || i > '9') && i != '-') {
101 fXPlacementText->TextView()->DisallowChar(i);
102 fYPlacementText->TextView()->DisallowChar(i);
106 previewBox->AddChild(BLayoutBuilder::Group<>()
107 .AddGlue()
108 .AddGroup(B_VERTICAL, 0)
109 .AddGroup(B_HORIZONTAL, 0)
110 .AddGlue()
111 .AddGrid(0, 0, 1)
112 .Add(fTopLeft, 0, 0)
113 .Add(fTop, 1, 0)
114 .Add(fTopRight, 2, 0)
115 .Add(fLeft, 0, 1)
116 .Add(fPreview, 1, 1)
117 .Add(fRight, 2, 1)
118 .Add(fBottomLeft, 0, 2)
119 .Add(fBottom, 1, 2)
120 .Add(fBottomRight, 2, 2)
121 .End()
122 .AddGlue()
123 .End()
124 .AddStrut(be_control_look->DefaultItemSpacing() * 2)
125 .AddGroup(B_HORIZONTAL)
126 .Add(fXPlacementText)
127 .Add(fYPlacementText)
128 .End()
129 .AddGlue()
130 .SetInsets(B_USE_DEFAULT_SPACING)
131 .End()
132 .AddGlue()
133 .View());
135 BBox* rightbox = new BBox("rightbox");
137 fWorkspaceMenu = new BPopUpMenu(B_TRANSLATE("pick one"));
138 fWorkspaceMenu->AddItem(new BMenuItem(B_TRANSLATE("All workspaces"),
139 new BMessage(kMsgAllWorkspaces)));
140 BMenuItem* menuItem;
141 fWorkspaceMenu->AddItem(menuItem = new BMenuItem(
142 B_TRANSLATE("Current workspace"),
143 new BMessage(kMsgCurrentWorkspace)));
144 menuItem->SetMarked(true);
145 fLastWorkspaceIndex =
146 fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked());
147 fWorkspaceMenu->AddSeparatorItem();
148 fWorkspaceMenu->AddItem(new BMenuItem(B_TRANSLATE("Default folder"),
149 new BMessage(kMsgDefaultFolder)));
150 fWorkspaceMenu->AddItem(new BMenuItem(
151 B_TRANSLATE("Other folder" B_UTF8_ELLIPSIS),
152 new BMessage(kMsgOtherFolder)));
154 BMenuField* workspaceMenuField = new BMenuField("workspaceMenuField",
155 NULL, fWorkspaceMenu);
156 workspaceMenuField->ResizeToPreferred();
157 rightbox->SetLabel(workspaceMenuField);
159 fImageMenu = new BPopUpMenu(B_TRANSLATE("pick one"));
160 fImageMenu->AddItem(new BGImageMenuItem(B_TRANSLATE("None"), -1,
161 new BMessage(kMsgNoImage)));
162 fImageMenu->AddSeparatorItem();
163 fImageMenu->AddItem(new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS),
164 new BMessage(kMsgOtherImage)));
166 BMenuField* imageMenuField = new BMenuField("image",
167 B_TRANSLATE("Image:"), fImageMenu);
168 imageMenuField->SetAlignment(B_ALIGN_RIGHT);
170 fPlacementMenu = new BPopUpMenu(B_TRANSLATE("pick one"));
171 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Manual"),
172 new BMessage(kMsgManualPlacement)));
173 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Center"),
174 new BMessage(kMsgCenterPlacement)));
175 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Scale to fit"),
176 new BMessage(kMsgScalePlacement)));
177 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Tile"),
178 new BMessage(kMsgTilePlacement)));
180 BMenuField* placementMenuField = new BMenuField("placement",
181 B_TRANSLATE("Placement:"), fPlacementMenu);
182 placementMenuField->SetAlignment(B_ALIGN_RIGHT);
184 fIconLabelOutline = new BCheckBox(B_TRANSLATE("Icon label outline"),
185 new BMessage(kMsgIconLabelOutline));
186 fIconLabelOutline->SetValue(B_CONTROL_OFF);
188 fPicker = new BColorControl(BPoint(0, 0), B_CELLS_32x8, 8.0, "Picker",
189 new BMessage(kMsgUpdateColor));
191 rightbox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
192 .AddGroup(B_HORIZONTAL, 0.0f)
193 .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
194 .Add(imageMenuField->CreateLabelLayoutItem(), 0, 0)
195 .AddGroup(B_HORIZONTAL, 0.0f, 1, 0)
196 .Add(imageMenuField->CreateMenuBarLayoutItem(), 0.0f)
197 .AddGlue()
198 .End()
199 .Add(placementMenuField->CreateLabelLayoutItem(), 0, 1)
200 .AddGroup(B_HORIZONTAL, 0.0f, 1, 1)
201 .Add(placementMenuField->CreateMenuBarLayoutItem(), 0.0f)
202 .AddGlue()
203 .End()
204 .Add(fIconLabelOutline, 1, 2)
205 .End()
206 .AddGlue()
207 .End()
208 .AddGlue()
209 .Add(fPicker)
210 .SetInsets(B_USE_DEFAULT_SPACING)
211 .View());
213 fRevert = new BButton(B_TRANSLATE("Revert"),
214 new BMessage(kMsgRevertSettings));
215 fApply = new BButton(B_TRANSLATE("Apply"),
216 new BMessage(kMsgApplySettings));
218 fRevert->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT,
219 B_ALIGN_NO_VERTICAL));
220 fApply->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT,
221 B_ALIGN_NO_VERTICAL));
223 AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
224 .AddGroup(B_HORIZONTAL)
225 .AddGroup(B_VERTICAL, 0)
226 .AddStrut(floorf(rightbox->TopBorderOffset()
227 - previewBox->TopBorderOffset()) - 1)
228 .Add(previewBox)
229 .End()
230 .Add(rightbox)
231 .End()
232 .AddGroup(B_HORIZONTAL)
233 .Add(fRevert)
234 .Add(fApply)
235 .End()
236 .SetInsets(B_USE_DEFAULT_SPACING)
237 .View());
239 fApply->MakeDefault(true);
243 BackgroundsView::~BackgroundsView()
245 // The order matter. The last panel saves the state
246 delete fFolderPanel;
247 delete fPanel;
251 void
252 BackgroundsView::AllAttached()
254 fPlacementMenu->SetTargetForItems(this);
255 fImageMenu->SetTargetForItems(this);
256 fWorkspaceMenu->SetTargetForItems(this);
257 fXPlacementText->SetTarget(this);
258 fYPlacementText->SetTarget(this);
259 fIconLabelOutline->SetTarget(this);
260 fPicker->SetTarget(this);
261 fApply->SetTarget(this);
262 fRevert->SetTarget(this);
264 BPath path;
265 entry_ref ref;
266 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) == B_OK) {
267 path.Append("artwork");
268 get_ref_for_path(path.Path(), &ref);
271 BMessenger messenger(this);
272 fPanel = new ImageFilePanel(B_OPEN_PANEL, &messenger, &ref,
273 B_FILE_NODE, false, NULL, new CustomRefFilter(true));
274 fPanel->SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select"));
276 fFolderPanel = new BFilePanel(B_OPEN_PANEL, &messenger, NULL,
277 B_DIRECTORY_NODE, false, NULL, new CustomRefFilter(false));
278 fFolderPanel->SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select"));
280 _LoadSettings();
281 _LoadDesktopFolder();
283 BPoint point;
284 if (fSettings.FindPoint("pos", &point) == B_OK) {
285 fFoundPositionSetting = true;
286 Window()->MoveTo(point);
289 fApply->SetEnabled(false);
290 fRevert->SetEnabled(false);
294 void
295 BackgroundsView::MessageReceived(BMessage* message)
297 // Color drop
298 if (message->WasDropped()) {
299 rgb_color *clr;
300 ssize_t out_size;
301 if (message->FindData("RGBColor", B_RGB_COLOR_TYPE,
302 (const void **)&clr, &out_size) == B_OK) {
303 fPicker->SetValue(*clr);
304 _UpdatePreview();
305 _UpdateButtons();
306 return;
310 switch (message->what) {
311 case B_SIMPLE_DATA:
312 case B_REFS_RECEIVED:
313 RefsReceived(message);
314 break;
316 case kMsgUpdatePreviewPlacement:
318 BString xstring, ystring;
319 xstring << (int)fPreview->fPoint.x;
320 ystring << (int)fPreview->fPoint.y;
321 fXPlacementText->SetText(xstring.String());
322 fYPlacementText->SetText(ystring.String());
323 _UpdatePreview();
324 _UpdateButtons();
325 break;
328 case kMsgManualPlacement:
329 case kMsgTilePlacement:
330 case kMsgScalePlacement:
331 case kMsgCenterPlacement:
332 _UpdatePreview();
333 _UpdateButtons();
334 break;
336 case kMsgIconLabelOutline:
337 _UpdateButtons();
338 break;
340 case kMsgUpdateColor:
341 case kMsgImagePlacement:
342 _UpdatePreview();
343 _UpdateButtons();
344 break;
346 case kMsgCurrentWorkspace:
347 case kMsgAllWorkspaces:
348 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None"));
349 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf(
350 fWorkspaceMenu->FindMarked());
351 if (fCurrent && fCurrent->IsDesktop()) {
352 _UpdateButtons();
353 } else {
354 _SetDesktop(true);
355 _LoadDesktopFolder();
357 break;
359 case kMsgDefaultFolder:
360 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None"));
361 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf(
362 fWorkspaceMenu->FindMarked());
363 _SetDesktop(false);
364 _LoadDefaultFolder();
365 break;
367 case kMsgOtherFolder:
368 fFolderPanel->Show();
369 break;
371 case kMsgOtherImage:
372 fPanel->Show();
373 break;
375 case B_CANCEL:
377 PRINT(("cancel received\n"));
378 void* pointer;
379 message->FindPointer("source", &pointer);
380 if (pointer == fPanel) {
381 if (fLastImageIndex >= 0)
382 _FindImageItem(fLastImageIndex)->SetMarked(true);
383 else
384 fImageMenu->ItemAt(0)->SetMarked(true);
385 } else if (pointer == fFolderPanel) {
386 if (fLastWorkspaceIndex >= 0)
387 fWorkspaceMenu->ItemAt(fLastWorkspaceIndex)
388 ->SetMarked(true);
390 break;
393 case kMsgImageSelected:
394 case kMsgNoImage:
395 fLastImageIndex = ((BGImageMenuItem*)fImageMenu->FindMarked())
396 ->ImageIndex();
397 _UpdatePreview();
398 _UpdateButtons();
399 break;
401 case kMsgFolderSelected:
402 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("Default"));
403 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf(
404 fWorkspaceMenu->FindMarked());
405 _SetDesktop(false);
407 _LoadRecentFolder(*fPathList.ItemAt(fWorkspaceMenu->IndexOf(
408 fWorkspaceMenu->FindMarked()) - 6));
409 break;
411 case kMsgApplySettings:
413 _Save();
415 //_NotifyServer();
416 thread_id notify_thread;
417 notify_thread = spawn_thread(BackgroundsView::_NotifyThread,
418 "notifyServer", B_NORMAL_PRIORITY, this);
419 resume_thread(notify_thread);
420 _UpdateButtons();
421 break;
423 case kMsgRevertSettings:
424 _UpdateWithCurrent();
425 break;
427 default:
428 BView::MessageReceived(message);
429 break;
434 void
435 BackgroundsView::_LoadDesktopFolder()
437 BPath path;
438 if (find_directory(B_DESKTOP_DIRECTORY, &path) == B_OK) {
439 status_t err;
440 err = get_ref_for_path(path.Path(), &fCurrentRef);
441 if (err != B_OK)
442 printf("error in LoadDesktopSettings\n");
443 _LoadFolder(true);
448 void
449 BackgroundsView::_LoadDefaultFolder()
451 BPath path;
452 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
453 BString pathString = path.Path();
454 pathString << "/Tracker/DefaultFolderTemplate";
455 status_t err;
456 err = get_ref_for_path(pathString.String(), &fCurrentRef);
457 if (err != B_OK)
458 printf("error in LoadDefaultFolderSettings\n");
459 _LoadFolder(false);
464 void
465 BackgroundsView::_LoadRecentFolder(BPath path)
467 status_t err;
468 err = get_ref_for_path(path.Path(), &fCurrentRef);
469 if (err != B_OK)
470 printf("error in LoadRecentFolder\n");
471 _LoadFolder(false);
475 void
476 BackgroundsView::_LoadFolder(bool isDesktop)
478 if (fCurrent) {
479 delete fCurrent;
480 fCurrent = NULL;
483 BNode node(&fCurrentRef);
484 if (node.InitCheck() == B_OK)
485 fCurrent = BackgroundImage::GetBackgroundImage(&node, isDesktop, this);
487 _UpdateWithCurrent();
491 void
492 BackgroundsView::_UpdateWithCurrent(void)
494 if (fCurrent == NULL)
495 return;
497 fPlacementMenu->FindItem(kMsgScalePlacement)
498 ->SetEnabled(fCurrent->IsDesktop());
499 fPlacementMenu->FindItem(kMsgCenterPlacement)
500 ->SetEnabled(fCurrent->IsDesktop());
502 if (fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked()) > 5)
503 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("Default"));
504 else
505 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None"));
507 for (int32 i = fImageMenu->CountItems() - 5; i >= 0; i--) {
508 fImageMenu->RemoveItem(2);
511 for (int32 i = fImageList.CountItems() - 1; i >= 0; i--) {
512 BMessage* message = new BMessage(kMsgImageSelected);
513 _AddItem(new BGImageMenuItem(GetImage(i)->GetName(), i, message));
516 fImageMenu->SetTargetForItems(this);
518 fCurrentInfo = fCurrent->ImageInfoForWorkspace(current_workspace());
520 if (!fCurrentInfo) {
521 fImageMenu->FindItem(kMsgNoImage)->SetMarked(true);
522 fPlacementMenu->FindItem(kMsgManualPlacement)->SetMarked(true);
523 fIconLabelOutline->SetValue(B_CONTROL_ON);
524 } else {
525 fIconLabelOutline->SetValue(fCurrentInfo->fTextWidgetLabelOutline
526 ? B_CONTROL_ON : B_CONTROL_OFF);
528 fLastImageIndex = fCurrentInfo->fImageIndex;
529 _FindImageItem(fLastImageIndex)->SetMarked(true);
531 if (fLastImageIndex > -1) {
533 BString xtext, ytext;
534 int32 cmd = 0;
535 switch (fCurrentInfo->fMode) {
536 case BackgroundImage::kCentered:
537 cmd = kMsgCenterPlacement;
538 break;
539 case BackgroundImage::kScaledToFit:
540 cmd = kMsgScalePlacement;
541 break;
542 case BackgroundImage::kAtOffset:
543 cmd = kMsgManualPlacement;
544 xtext << (int)fCurrentInfo->fOffset.x;
545 ytext << (int)fCurrentInfo->fOffset.y;
546 break;
547 case BackgroundImage::kTiled:
548 cmd = kMsgTilePlacement;
549 break;
552 if (cmd != 0)
553 fPlacementMenu->FindItem(cmd)->SetMarked(true);
555 fXPlacementText->SetText(xtext.String());
556 fYPlacementText->SetText(ytext.String());
557 } else {
558 fPlacementMenu->FindItem(kMsgManualPlacement)->SetMarked(true);
562 rgb_color color = {255, 255, 255, 255};
563 if (fCurrent->IsDesktop()) {
564 color = BScreen().DesktopColor();
565 fPicker->SetEnabled(true);
566 } else
567 fPicker->SetEnabled(false);
569 fPicker->SetValue(color);
571 _UpdatePreview();
572 _UpdateButtons();
576 void
577 BackgroundsView::_Save()
579 bool textWidgetLabelOutline
580 = fIconLabelOutline->Value() == B_CONTROL_ON;
582 BackgroundImage::Mode mode = _FindPlacementMode();
583 BPoint offset(atoi(fXPlacementText->Text()), atoi(fYPlacementText->Text()));
585 if (!fCurrent->IsDesktop()) {
586 if (fCurrentInfo == NULL) {
587 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(
588 B_ALL_WORKSPACES, fLastImageIndex, mode, offset,
589 textWidgetLabelOutline, 0, 0);
590 fCurrent->Add(fCurrentInfo);
591 } else {
592 fCurrentInfo->fTextWidgetLabelOutline = textWidgetLabelOutline;
593 fCurrentInfo->fMode = mode;
594 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset)
595 fCurrentInfo->fOffset = offset;
596 fCurrentInfo->fImageIndex = fLastImageIndex;
598 } else {
599 uint32 workspaceMask = 1;
600 int32 workspace = current_workspace();
601 for (; workspace; workspace--)
602 workspaceMask *= 2;
604 if (fCurrentInfo != NULL) {
605 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) {
606 if (fCurrentInfo->fWorkspace & workspaceMask
607 && fCurrentInfo->fWorkspace != workspaceMask) {
608 fCurrentInfo->fWorkspace = fCurrentInfo->fWorkspace
609 ^ workspaceMask;
610 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(
611 workspaceMask, fLastImageIndex, mode, offset,
612 textWidgetLabelOutline, fCurrentInfo->fImageSet,
613 fCurrentInfo->fCacheMode);
614 fCurrent->Add(fCurrentInfo);
615 } else if (fCurrentInfo->fWorkspace == workspaceMask) {
616 fCurrentInfo->fTextWidgetLabelOutline
617 = textWidgetLabelOutline;
618 fCurrentInfo->fMode = mode;
619 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset)
620 fCurrentInfo->fOffset = offset;
622 fCurrentInfo->fImageIndex = fLastImageIndex;
624 } else {
625 fCurrent->RemoveAll();
627 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(
628 B_ALL_WORKSPACES, fLastImageIndex, mode, offset,
629 textWidgetLabelOutline, fCurrent->GetShowingImageSet(),
630 fCurrentInfo->fCacheMode);
631 fCurrent->Add(fCurrentInfo);
633 } else {
634 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) {
635 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(
636 workspaceMask, fLastImageIndex, mode, offset,
637 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0);
638 } else {
639 fCurrent->RemoveAll();
640 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(
641 B_ALL_WORKSPACES, fLastImageIndex, mode, offset,
642 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0);
644 fCurrent->Add(fCurrentInfo);
647 if (!fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) {
648 for (int32 i = 0; i < count_workspaces(); i++) {
649 BScreen().SetDesktopColor(fPicker->ValueAsColor(), i, true);
651 } else
652 BScreen().SetDesktopColor(fPicker->ValueAsColor(), true);
655 BNode node(&fCurrentRef);
657 status_t status = fCurrent->SetBackgroundImage(&node);
658 if (status != B_OK) {
659 // TODO: this should be a BAlert!
660 printf("setting background image failed: %s\n", strerror(status));
665 void
666 BackgroundsView::_NotifyServer()
668 BMessenger tracker("application/x-vnd.Be-TRAK");
670 if (fCurrent->IsDesktop()) {
671 tracker.SendMessage(new BMessage(B_RESTORE_BACKGROUND_IMAGE));
672 } else {
673 int32 i = -1;
674 BMessage reply;
675 int32 err;
676 BEntry currentEntry(&fCurrentRef);
677 BPath currentPath(&currentEntry);
678 bool isCustomFolder
679 = !fWorkspaceMenu->FindItem(kMsgDefaultFolder)->IsMarked();
681 do {
682 BMessage msg(B_GET_PROPERTY);
683 i++;
685 // look at the "Poses" in every Tracker window
686 msg.AddSpecifier("Poses");
687 msg.AddSpecifier("Window", i);
689 reply.MakeEmpty();
690 tracker.SendMessage(&msg, &reply);
692 // break out of the loop when we're at the end of
693 // the windows
694 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD
695 && reply.FindInt32("error", &err) == B_OK
696 && err == B_BAD_INDEX)
697 break;
699 // don't stop for windows that don't understand
700 // a request for "Poses"; they're not displaying
701 // folders
702 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD
703 && reply.FindInt32("error", &err) == B_OK
704 && err != B_BAD_SCRIPT_SYNTAX)
705 continue;
707 BMessenger trackerWindow;
708 if (reply.FindMessenger("result", &trackerWindow) != B_OK)
709 continue;
711 if (isCustomFolder) {
712 // found a window with poses, ask for its path
713 msg.MakeEmpty();
714 msg.what = B_GET_PROPERTY;
715 msg.AddSpecifier("Path");
716 msg.AddSpecifier("Poses");
717 msg.AddSpecifier("Window", i);
719 reply.MakeEmpty();
720 tracker.SendMessage(&msg, &reply);
722 // go on with the next if this din't have a path
723 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD)
724 continue;
726 entry_ref ref;
727 if (reply.FindRef("result", &ref) == B_OK) {
728 BEntry entry(&ref);
729 BPath path(&entry);
731 // these are not the paths you're looking for
732 if (currentPath != path)
733 continue;
737 trackerWindow.SendMessage(B_RESTORE_BACKGROUND_IMAGE);
738 } while (true);
743 int32
744 BackgroundsView::_NotifyThread(void* data)
746 BackgroundsView* view = (BackgroundsView*)data;
748 view->_NotifyServer();
749 return B_OK;
753 void
754 BackgroundsView::SaveSettings(void)
756 BPath path;
757 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
758 path.Append(SETTINGS_FILE);
759 BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
761 BPoint point = Window()->Frame().LeftTop();
762 if (fSettings.ReplacePoint("pos", point) != B_OK)
763 fSettings.AddPoint("pos", point);
765 entry_ref ref;
766 BEntry entry;
768 fPanel->GetPanelDirectory(&ref);
769 entry.SetTo(&ref);
770 entry.GetPath(&path);
771 if (fSettings.ReplaceString("paneldir", path.Path()) != B_OK)
772 fSettings.AddString("paneldir", path.Path());
774 fFolderPanel->GetPanelDirectory(&ref);
775 entry.SetTo(&ref);
776 entry.GetPath(&path);
777 if (fSettings.ReplaceString("folderpaneldir", path.Path()) != B_OK)
778 fSettings.AddString("folderpaneldir", path.Path());
780 fSettings.RemoveName("recentfolder");
781 for (int32 i = 0; i < fPathList.CountItems(); i++) {
782 fSettings.AddString("recentfolder", fPathList.ItemAt(i)->Path());
785 fSettings.Flatten(&file);
790 void
791 BackgroundsView::_LoadSettings()
793 fSettings.MakeEmpty();
795 BPath path;
796 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
797 return;
799 path.Append(SETTINGS_FILE);
800 BFile file(path.Path(), B_READ_ONLY);
801 if (file.InitCheck() != B_OK)
802 return;
804 if (fSettings.Unflatten(&file) != B_OK) {
805 printf("Error unflattening settings file %s\n", path.Path());
806 return;
809 PRINT_OBJECT(fSettings);
811 BString string;
812 if (fSettings.FindString("paneldir", &string) == B_OK)
813 fPanel->SetPanelDirectory(string.String());
815 if (fSettings.FindString("folderpaneldir", &string) == B_OK)
816 fFolderPanel->SetPanelDirectory(string.String());
818 int32 index = 0;
819 while (fSettings.FindString("recentfolder", index, &string) == B_OK) {
820 if (index == 0)
821 fWorkspaceMenu->AddSeparatorItem();
823 path.SetTo(string.String());
824 int32 i = _AddPath(path);
825 BString s;
826 s << B_TRANSLATE("Folder: ") << path.Leaf();
827 BMenuItem* item = new BMenuItem(s.String(),
828 new BMessage(kMsgFolderSelected));
829 fWorkspaceMenu->AddItem(item, -i - 1 + 6);
830 index++;
832 fWorkspaceMenu->SetTargetForItems(this);
834 PRINT(("Settings Loaded\n"));
838 void
839 BackgroundsView::WorkspaceActivated(uint32 oldWorkspaces, bool active)
841 _UpdateWithCurrent();
845 void
846 BackgroundsView::_UpdatePreview()
848 bool imageEnabled = !(fImageMenu->FindItem(kMsgNoImage)->IsMarked());
849 if (fPlacementMenu->IsEnabled() ^ imageEnabled)
850 fPlacementMenu->SetEnabled(imageEnabled);
852 bool textEnabled
853 = (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked())
854 && imageEnabled;
855 if (fXPlacementText->IsEnabled() ^ textEnabled)
856 fXPlacementText->SetEnabled(textEnabled);
857 if (fYPlacementText->IsEnabled() ^ textEnabled)
858 fYPlacementText->SetEnabled(textEnabled);
860 if (textEnabled && (strcmp(fXPlacementText->Text(), "") == 0)) {
861 fXPlacementText->SetText("0");
862 fYPlacementText->SetText("0");
864 if (!textEnabled) {
865 fXPlacementText->SetText(NULL);
866 fYPlacementText->SetText(NULL);
869 fXPlacementText->TextView()->MakeSelectable(textEnabled);
870 fYPlacementText->TextView()->MakeSelectable(textEnabled);
871 fXPlacementText->TextView()->MakeEditable(textEnabled);
872 fYPlacementText->TextView()->MakeEditable(textEnabled);
874 fPreview->ClearViewBitmap();
876 int32 index = ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex();
877 if (index >= 0) {
878 BBitmap* bitmap = GetImage(index)->GetBitmap();
879 if (bitmap) {
880 BackgroundImage::BackgroundImageInfo* info
881 = new BackgroundImage::BackgroundImageInfo(0, index,
882 _FindPlacementMode(), BPoint(atoi(fXPlacementText->Text()),
883 atoi(fYPlacementText->Text())),
884 fIconLabelOutline->Value() == B_CONTROL_ON, 0, 0);
885 if (info->fMode == BackgroundImage::kAtOffset) {
886 fPreview->SetEnabled(true);
887 fPreview->fPoint.x = atoi(fXPlacementText->Text());
888 fPreview->fPoint.y = atoi(fYPlacementText->Text());
889 } else
890 fPreview->SetEnabled(false);
892 fPreview->fImageBounds = BRect(bitmap->Bounds());
893 fCurrent->Show(info, fPreview);
895 delete info;
897 } else
898 fPreview->SetEnabled(false);
900 fPreview->SetViewColor(fPicker->ValueAsColor());
901 fPreview->Invalidate();
905 BackgroundImage::Mode
906 BackgroundsView::_FindPlacementMode()
908 BackgroundImage::Mode mode = BackgroundImage::kAtOffset;
910 if (fPlacementMenu->FindItem(kMsgCenterPlacement)->IsMarked())
911 mode = BackgroundImage::kCentered;
912 if (fPlacementMenu->FindItem(kMsgScalePlacement)->IsMarked())
913 mode = BackgroundImage::kScaledToFit;
914 if (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked())
915 mode = BackgroundImage::kAtOffset;
916 if (fPlacementMenu->FindItem(kMsgTilePlacement)->IsMarked())
917 mode = BackgroundImage::kTiled;
919 return mode;
923 void
924 BackgroundsView::_UpdateButtons()
926 bool hasChanged = false;
927 if (fPicker->IsEnabled()
928 && fPicker->ValueAsColor() != BScreen().DesktopColor()) {
929 hasChanged = true;
930 } else if (fCurrentInfo) {
931 if ((fIconLabelOutline->Value() == B_CONTROL_ON)
932 ^ fCurrentInfo->fTextWidgetLabelOutline) {
933 hasChanged = true;
934 } else if (_FindPlacementMode() != fCurrentInfo->fMode) {
935 hasChanged = true;
936 } else if (fCurrentInfo->fImageIndex
937 != ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex()) {
938 hasChanged = true;
939 } else if (fCurrent->IsDesktop()
940 && ((fCurrentInfo->fWorkspace != B_ALL_WORKSPACES)
941 ^ (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked())))
943 hasChanged = true;
944 } else if (fCurrentInfo->fImageIndex > -1
945 && fCurrentInfo->fMode == BackgroundImage::kAtOffset) {
946 BString oldString, newString;
947 oldString << (int)fCurrentInfo->fOffset.x;
948 if (oldString != BString(fXPlacementText->Text())) {
949 hasChanged = true;
951 oldString = "";
952 oldString << (int)fCurrentInfo->fOffset.y;
953 if (oldString != BString(fYPlacementText->Text())) {
954 hasChanged = true;
957 } else if (fImageMenu->IndexOf(fImageMenu->FindMarked()) > 0) {
958 hasChanged = true;
959 } else if (fIconLabelOutline->Value() == B_CONTROL_OFF) {
960 hasChanged = true;
963 fApply->SetEnabled(hasChanged);
964 fRevert->SetEnabled(hasChanged);
968 void
969 BackgroundsView::RefsReceived(BMessage* message)
971 if (!message->HasRef("refs") && message->HasRef("dir_ref")) {
972 entry_ref dirRef;
973 if (message->FindRef("dir_ref", &dirRef) == B_OK)
974 message->AddRef("refs", &dirRef);
977 entry_ref ref;
978 int32 i = 0;
979 BMimeType imageType("image");
980 BPath desktopPath;
981 find_directory(B_DESKTOP_DIRECTORY, &desktopPath);
983 while (message->FindRef("refs", i++, &ref) == B_OK) {
984 BPath path;
985 BEntry entry(&ref, true);
986 path.SetTo(&entry);
987 BNode node(&entry);
989 if (node.IsFile()) {
990 BMimeType refType;
991 BMimeType::GuessMimeType(&ref, &refType);
992 if (!imageType.Contains(&refType))
993 continue;
995 BGImageMenuItem* item;
996 int32 index = AddImage(path);
997 if (index >= 0) {
998 item = _FindImageItem(index);
999 fLastImageIndex = index;
1000 } else {
1001 const char* name = GetImage(-index - 1)->GetName();
1002 item = new BGImageMenuItem(name, -index - 1,
1003 new BMessage(kMsgImageSelected));
1004 _AddItem(item);
1005 item->SetTarget(this);
1006 fLastImageIndex = -index - 1;
1009 // An optional placement may have been sent
1010 int32 placement = 0;
1011 if (message->FindInt32("placement", &placement) == B_OK) {
1012 BMenuItem* item = fPlacementMenu->FindItem(placement);
1013 if (item)
1014 item->SetMarked(true);
1016 item->SetMarked(true);
1017 BMessenger(this).SendMessage(kMsgImageSelected);
1018 } else if (node.IsDirectory()) {
1019 if (desktopPath == path) {
1020 fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->SetMarked(true);
1021 BMessenger(this).SendMessage(kMsgCurrentWorkspace);
1022 break;
1024 BMenuItem* item;
1025 int32 index = _AddPath(path);
1026 if (index >= 0) {
1027 item = fWorkspaceMenu->ItemAt(index + 6);
1028 fLastWorkspaceIndex = index + 6;
1029 } else {
1030 if (fWorkspaceMenu->CountItems() <= 5)
1031 fWorkspaceMenu->AddSeparatorItem();
1032 BString s;
1033 s << B_TRANSLATE("Folder: ") << path.Leaf();
1034 item = new BMenuItem(s.String(),
1035 new BMessage(kMsgFolderSelected));
1036 fWorkspaceMenu->AddItem(item, -index - 1 + 6);
1037 item->SetTarget(this);
1038 fLastWorkspaceIndex = -index - 1 + 6;
1041 item->SetMarked(true);
1042 BMessenger(this).SendMessage(kMsgFolderSelected);
1048 int32
1049 BackgroundsView::_AddPath(BPath path)
1051 int32 count = fPathList.CountItems();
1052 int32 index = 0;
1053 for (; index < count; index++) {
1054 BPath* p = fPathList.ItemAt(index);
1055 int c = BString(p->Path()).ICompare(path.Path());
1056 if (c == 0)
1057 return index;
1059 if (c > 0)
1060 break;
1062 fPathList.AddItem(new BPath(path), index);
1063 return -index - 1;
1067 int32
1068 BackgroundsView::AddImage(BPath path)
1070 int32 count = fImageList.CountItems();
1071 int32 index = 0;
1072 for (; index < count; index++) {
1073 Image* image = fImageList.ItemAt(index);
1074 if (image->GetPath() == path)
1075 return index;
1078 fImageList.AddItem(new Image(path));
1079 return -index - 1;
1083 Image*
1084 BackgroundsView::GetImage(int32 imageIndex)
1086 return fImageList.ItemAt(imageIndex);
1090 BGImageMenuItem*
1091 BackgroundsView::_FindImageItem(const int32 imageIndex)
1093 if (imageIndex < 0)
1094 return (BGImageMenuItem*)fImageMenu->ItemAt(0);
1096 int32 count = fImageMenu->CountItems() - 2;
1097 int32 index = 2;
1098 for (; index < count; index++) {
1099 BGImageMenuItem* image = (BGImageMenuItem*)fImageMenu->ItemAt(index);
1100 if (image->ImageIndex() == imageIndex)
1101 return image;
1103 return NULL;
1107 bool
1108 BackgroundsView::_AddItem(BGImageMenuItem* item)
1110 int32 count = fImageMenu->CountItems() - 2;
1111 int32 index = 2;
1112 if (count < index) {
1113 fImageMenu->AddItem(new BSeparatorItem(), 1);
1114 count = fImageMenu->CountItems() - 2;
1117 for (; index < count; index++) {
1118 BGImageMenuItem* image = (BGImageMenuItem*)fImageMenu->ItemAt(index);
1119 int c = (BString(image->Label()).ICompare(BString(item->Label())));
1120 if (c > 0)
1121 break;
1123 return fImageMenu->AddItem(item, index);
1127 void
1128 BackgroundsView::_SetDesktop(bool isDesktop)
1130 fTopLeft->SetDesktop(isDesktop);
1131 fTop->SetDesktop(isDesktop);
1132 fTopRight->SetDesktop(isDesktop);
1133 fLeft->SetDesktop(isDesktop);
1134 fRight->SetDesktop(isDesktop);
1135 fBottomLeft->SetDesktop(isDesktop);
1136 fBottom->SetDesktop(isDesktop);
1137 fBottomRight->SetDesktop(isDesktop);
1139 Invalidate();
1143 bool
1144 BackgroundsView::FoundPositionSetting()
1146 return fFoundPositionSetting;
1150 // #pragma mark -
1153 Preview::Preview()
1155 BControl("PreView", NULL, NULL, B_WILL_DRAW | B_SUBPIXEL_PRECISE)
1157 float aspectRatio = BScreen().Frame().Width() / BScreen().Frame().Height();
1158 float previewWidth = 120.0f;
1159 float previewHeight = ceil(previewWidth / aspectRatio);
1161 ResizeTo(previewWidth, previewHeight);
1162 SetExplicitMinSize(BSize(previewWidth, previewHeight));
1163 SetExplicitMaxSize(BSize(previewWidth, previewHeight));
1167 void
1168 Preview::AttachedToWindow()
1170 rgb_color color = ViewColor();
1171 BControl::AttachedToWindow();
1172 SetViewColor(color);
1176 void
1177 Preview::MouseDown(BPoint point)
1179 if (IsEnabled() && Bounds().Contains(point)) {
1180 uint32 buttons;
1181 GetMouse(&point, &buttons);
1182 if (buttons & B_PRIMARY_MOUSE_BUTTON) {
1183 fOldPoint = point;
1184 SetTracking(true);
1185 BScreen().GetMode(&fMode);
1186 fXRatio = Bounds().Width() / fMode.virtual_width;
1187 fYRatio = Bounds().Height() / fMode.virtual_height;
1188 SetMouseEventMask(B_POINTER_EVENTS,
1189 B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
1191 BCursor grabbingCursor(B_CURSOR_ID_GRABBING);
1192 SetViewCursor(&grabbingCursor);
1198 void
1199 Preview::MouseUp(BPoint point)
1201 if (IsTracking()) {
1202 SetTracking(false);
1203 BCursor grabCursor(B_CURSOR_ID_GRAB);
1204 SetViewCursor(&grabCursor);
1209 void
1210 Preview::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
1212 if (!IsTracking()) {
1213 BCursor cursor(IsEnabled()
1214 ? B_CURSOR_ID_GRAB : B_CURSOR_ID_SYSTEM_DEFAULT);
1215 SetViewCursor(&cursor);
1216 } else {
1217 float x, y;
1218 x = fPoint.x + (point.x - fOldPoint.x) / fXRatio;
1219 y = fPoint.y + (point.y - fOldPoint.y) / fYRatio;
1220 bool min, max, mustSend = false;
1221 min = (x > -fImageBounds.Width());
1222 max = (x < fMode.virtual_width);
1223 if (min && max) {
1224 fOldPoint.x = point.x;
1225 fPoint.x = x;
1226 mustSend = true;
1227 } else {
1228 if (!min && fPoint.x > -fImageBounds.Width()) {
1229 fPoint.x = -fImageBounds.Width();
1230 fOldPoint.x = point.x - (x - fPoint.x) * fXRatio;
1231 mustSend = true;
1233 if (!max && fPoint.x < fMode.virtual_width) {
1234 fPoint.x = fMode.virtual_width;
1235 fOldPoint.x = point.x - (x - fPoint.x) * fXRatio;
1236 mustSend = true;
1240 min = (y > -fImageBounds.Height());
1241 max = (y < fMode.virtual_height);
1242 if (min && max) {
1243 fOldPoint.y = point.y;
1244 fPoint.y = y;
1245 mustSend = true;
1246 } else {
1247 if (!min && fPoint.y > -fImageBounds.Height()) {
1248 fPoint.y = -fImageBounds.Height();
1249 fOldPoint.y = point.y - (y - fPoint.y) * fYRatio;
1250 mustSend = true;
1252 if (!max && fPoint.y < fMode.virtual_height) {
1253 fPoint.y = fMode.virtual_height;
1254 fOldPoint.y = point.y - (y - fPoint.y) * fYRatio;
1255 mustSend = true;
1259 if (mustSend) {
1260 BMessenger messenger(Parent());
1261 messenger.SendMessage(kMsgUpdatePreviewPlacement);
1265 BControl::MouseMoved(point, transit, message);
1269 // #pragma mark -
1272 BGImageMenuItem::BGImageMenuItem(const char* label, int32 imageIndex,
1273 BMessage* message, char shortcut, uint32 modifiers)
1274 : BMenuItem(label, message, shortcut, modifiers),
1275 fImageIndex(imageIndex)
1280 // #pragma mark -
1283 FramePart::FramePart(int32 part)
1285 BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS),
1286 fFramePart(part),
1287 fIsDesktop(true)
1289 _SetSizeAndAlignment();
1293 void
1294 FramePart::Draw(BRect rect)
1296 rgb_color color = HighColor();
1297 SetDrawingMode(B_OP_COPY);
1298 SetHighColor(Parent()->ViewColor());
1300 if (fIsDesktop) {
1301 switch (fFramePart) {
1302 case FRAME_TOP_LEFT:
1303 FillRect(rect);
1304 SetHighColor(160, 160, 160);
1305 FillRoundRect(BRect(0, 0, 8, 8), 3, 3);
1306 SetHighColor(96, 96, 96);
1307 StrokeRoundRect(BRect(0, 0, 8, 8), 3, 3);
1308 break;
1310 case FRAME_TOP:
1311 SetHighColor(160, 160, 160);
1312 FillRect(BRect(0, 1, rect.right, 3));
1313 SetHighColor(96, 96, 96);
1314 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0));
1315 SetHighColor(0, 0, 0);
1316 StrokeLine(BPoint(0, 4), BPoint(rect.right, 4));
1317 break;
1319 case FRAME_TOP_RIGHT:
1320 FillRect(rect);
1321 SetHighColor(160, 160, 160);
1322 FillRoundRect(BRect(-4, 0, 4, 8), 3, 3);
1323 SetHighColor(96, 96, 96);
1324 StrokeRoundRect(BRect(-4, 0, 4, 8), 3, 3);
1325 break;
1327 case FRAME_LEFT_SIDE:
1328 SetHighColor(160, 160, 160);
1329 FillRect(BRect(1, 0, 3, rect.bottom));
1330 SetHighColor(96, 96, 96);
1331 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom));
1332 SetHighColor(0, 0, 0);
1333 StrokeLine(BPoint(4, 0), BPoint(4, rect.bottom));
1334 break;
1336 case FRAME_RIGHT_SIDE:
1337 SetHighColor(160, 160, 160);
1338 FillRect(BRect(1, 0, 3, rect.bottom));
1339 SetHighColor(0, 0, 0);
1340 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom));
1341 SetHighColor(96, 96, 96);
1342 StrokeLine(BPoint(4, 0), BPoint(4, rect.bottom));
1343 break;
1345 case FRAME_BOTTOM_LEFT:
1346 FillRect(rect);
1347 SetHighColor(160, 160, 160);
1348 FillRoundRect(BRect(0, -4, 8, 4), 3, 3);
1349 SetHighColor(96, 96, 96);
1350 StrokeRoundRect(BRect(0, -4, 8, 4), 3, 3);
1351 break;
1353 case FRAME_BOTTOM:
1354 SetHighColor(160, 160, 160);
1355 FillRect(BRect(0, 1, rect.right, 3));
1356 SetHighColor(0, 0, 0);
1357 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0));
1358 SetHighColor(96, 96, 96);
1359 StrokeLine(BPoint(0, 4), BPoint(rect.right, 4));
1360 SetHighColor(228, 0, 0);
1361 StrokeLine(BPoint(5, 2), BPoint(7, 2));
1362 break;
1364 case FRAME_BOTTOM_RIGHT:
1365 FillRect(rect);
1366 SetHighColor(160, 160, 160);
1367 FillRoundRect(BRect(-4, -4, 4, 4), 3, 3);
1368 SetHighColor(96, 96, 96);
1369 StrokeRoundRect(BRect(-4, -4, 4, 4), 3, 3);
1370 break;
1372 default:
1373 break;
1375 } else {
1376 switch (fFramePart) {
1377 case FRAME_TOP_LEFT:
1378 SetHighColor(152, 152, 152);
1379 StrokeLine(BPoint(0, 0), BPoint(0, 12));
1380 StrokeLine(BPoint(0, 0), BPoint(4, 0));
1381 StrokeLine(BPoint(3, 12), BPoint(3, 12));
1382 SetHighColor(255, 203, 0);
1383 FillRect(BRect(1, 1, 3, 9));
1384 SetHighColor(240, 240, 240);
1385 StrokeLine(BPoint(1, 12), BPoint(1, 10));
1386 StrokeLine(BPoint(2, 10), BPoint(3, 10));
1387 SetHighColor(200, 200, 200);
1388 StrokeLine(BPoint(2, 12), BPoint(2, 11));
1389 StrokeLine(BPoint(3, 11), BPoint(3, 11));
1390 break;
1392 case FRAME_TOP:
1393 FillRect(BRect(54, 0, rect.right, 8));
1394 SetHighColor(255, 203, 0);
1395 FillRect(BRect(0, 1, 52, 9));
1396 SetHighColor(152, 152, 152);
1397 StrokeLine(BPoint(0, 0), BPoint(53, 0));
1398 StrokeLine(BPoint(53, 1), BPoint(53, 9));
1399 StrokeLine(BPoint(54, 9), BPoint(rect.right, 9));
1400 SetHighColor(240, 240, 240);
1401 StrokeLine(BPoint(0, 10), BPoint(rect.right, 10));
1402 SetHighColor(200, 200, 200);
1403 StrokeLine(BPoint(0, 11), BPoint(rect.right, 11));
1404 SetHighColor(152, 152, 152);
1405 StrokeLine(BPoint(0, 12), BPoint(rect.right, 12));
1406 break;
1408 case FRAME_TOP_RIGHT:
1409 FillRect(BRect(0, 0, 3, 8));
1410 SetHighColor(152, 152, 152);
1411 StrokeLine(BPoint(0, 12), BPoint(0, 12));
1412 StrokeLine(BPoint(0, 9), BPoint(3, 9));
1413 StrokeLine(BPoint(3, 12), BPoint(3, 9));
1414 SetHighColor(240, 240, 240);
1415 StrokeLine(BPoint(0, 10), BPoint(2, 10));
1416 StrokeLine(BPoint(1, 12), BPoint(1, 12));
1417 SetHighColor(200, 200, 200);
1418 StrokeLine(BPoint(2, 12), BPoint(2, 12));
1419 StrokeLine(BPoint(0, 11), BPoint(2, 11));
1420 break;
1422 case FRAME_LEFT_SIDE:
1423 case FRAME_RIGHT_SIDE:
1424 SetHighColor(152, 152, 152);
1425 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom));
1426 SetHighColor(240, 240, 240);
1427 StrokeLine(BPoint(1, 0), BPoint(1, rect.bottom));
1428 SetHighColor(200, 200, 200);
1429 StrokeLine(BPoint(2, 0), BPoint(2, rect.bottom));
1430 SetHighColor(152, 152, 152);
1431 StrokeLine(BPoint(3, 0), BPoint(3, rect.bottom));
1432 break;
1434 case FRAME_BOTTOM_LEFT:
1435 SetHighColor(152, 152, 152);
1436 StrokeLine(BPoint(0, 0), BPoint(0, 3));
1437 StrokeLine(BPoint(0, 3), BPoint(3, 3));
1438 StrokeLine(BPoint(3, 0), BPoint(3, 0));
1439 SetHighColor(240, 240, 240);
1440 StrokeLine(BPoint(1, 0), BPoint(1, 2));
1441 StrokeLine(BPoint(3, 1), BPoint(3, 1));
1442 SetHighColor(200, 200, 200);
1443 StrokeLine(BPoint(2, 0), BPoint(2, 2));
1444 StrokeLine(BPoint(3, 2), BPoint(3, 2));
1445 break;
1447 case FRAME_BOTTOM:
1448 SetHighColor(152, 152, 152);
1449 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0));
1450 SetHighColor(240, 240, 240);
1451 StrokeLine(BPoint(0, 1), BPoint(rect.right, 1));
1452 SetHighColor(200, 200, 200);
1453 StrokeLine(BPoint(0, 2), BPoint(rect.right, 2));
1454 SetHighColor(152, 152, 152);
1455 StrokeLine(BPoint(0, 3), BPoint(rect.right, 3));
1456 break;
1458 case FRAME_BOTTOM_RIGHT:
1459 SetHighColor(152, 152, 152);
1460 StrokeLine(BPoint(0, 0), BPoint(0, 0));
1461 SetHighColor(240, 240, 240);
1462 StrokeLine(BPoint(1, 0), BPoint(1, 1));
1463 StrokeLine(BPoint(0, 1), BPoint(0, 1));
1464 SetHighColor(200, 200, 200);
1465 StrokeLine(BPoint(2, 0), BPoint(2, 2));
1466 StrokeLine(BPoint(0, 2), BPoint(1, 2));
1467 SetHighColor(152, 152, 152);
1468 StrokeLine(BPoint(3, 0), BPoint(3, 3));
1469 StrokeLine(BPoint(0, 3), BPoint(2, 3));
1470 break;
1472 default:
1473 break;
1477 SetHighColor(color);
1481 void
1482 FramePart::SetDesktop(bool isDesktop)
1484 fIsDesktop = isDesktop;
1486 _SetSizeAndAlignment();
1487 Invalidate();
1491 void
1492 FramePart::_SetSizeAndAlignment()
1494 if (fIsDesktop) {
1495 switch (fFramePart) {
1496 case FRAME_TOP_LEFT:
1497 SetExplicitMinSize(BSize(4, 4));
1498 SetExplicitMaxSize(BSize(4, 4));
1499 break;
1501 case FRAME_TOP:
1502 SetExplicitMinSize(BSize(1, 4));
1503 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 4));
1504 break;
1506 case FRAME_TOP_RIGHT:
1507 SetExplicitMinSize(BSize(4, 4));
1508 SetExplicitMaxSize(BSize(4, 4));
1509 break;
1511 case FRAME_LEFT_SIDE:
1512 SetExplicitMinSize(BSize(4, 1));
1513 SetExplicitMaxSize(BSize(4, B_SIZE_UNLIMITED));
1514 break;
1516 case FRAME_RIGHT_SIDE:
1517 SetExplicitMinSize(BSize(4, 1));
1518 SetExplicitMaxSize(BSize(4, B_SIZE_UNLIMITED));
1519 break;
1521 case FRAME_BOTTOM_LEFT:
1522 SetExplicitMinSize(BSize(4, 4));
1523 SetExplicitMaxSize(BSize(4, 4));
1524 break;
1526 case FRAME_BOTTOM:
1527 SetExplicitMinSize(BSize(1, 4));
1528 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 4));
1529 break;
1531 case FRAME_BOTTOM_RIGHT:
1532 SetExplicitMaxSize(BSize(4, 4));
1533 SetExplicitMinSize(BSize(4, 4));
1534 break;
1536 default:
1537 break;
1539 } else {
1540 switch (fFramePart) {
1541 case FRAME_TOP_LEFT:
1542 SetExplicitMinSize(BSize(3, 12));
1543 SetExplicitMaxSize(BSize(3, 12));
1544 break;
1546 case FRAME_TOP:
1547 SetExplicitMinSize(BSize(1, 12));
1548 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 12));
1549 break;
1551 case FRAME_TOP_RIGHT:
1552 SetExplicitMinSize(BSize(3, 12));
1553 SetExplicitMaxSize(BSize(3, 12));
1554 break;
1556 case FRAME_LEFT_SIDE:
1557 SetExplicitMinSize(BSize(3, 1));
1558 SetExplicitMaxSize(BSize(3, B_SIZE_UNLIMITED));
1559 break;
1561 case FRAME_RIGHT_SIDE:
1562 SetExplicitMinSize(BSize(3, 1));
1563 SetExplicitMaxSize(BSize(3, B_SIZE_UNLIMITED));
1564 break;
1566 case FRAME_BOTTOM_LEFT:
1567 SetExplicitMinSize(BSize(3, 3));
1568 SetExplicitMaxSize(BSize(3, 3));
1569 break;
1571 case FRAME_BOTTOM:
1572 SetExplicitMinSize(BSize(1, 3));
1573 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 3));
1574 break;
1576 case FRAME_BOTTOM_RIGHT:
1577 SetExplicitMaxSize(BSize(3, 3));
1578 SetExplicitMinSize(BSize(3, 3));
1579 break;
1581 default:
1582 break;
1586 switch (fFramePart) {
1587 case FRAME_TOP_LEFT:
1588 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM));
1589 break;
1591 case FRAME_TOP:
1592 SetExplicitAlignment(BAlignment(B_ALIGN_CENTER, B_ALIGN_BOTTOM));
1593 break;
1595 case FRAME_TOP_RIGHT:
1596 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_BOTTOM));
1597 break;
1599 case FRAME_LEFT_SIDE:
1600 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE));
1601 break;
1603 case FRAME_RIGHT_SIDE:
1604 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE));
1605 break;
1607 case FRAME_BOTTOM_LEFT:
1608 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_TOP));
1609 break;
1611 case FRAME_BOTTOM:
1612 SetExplicitAlignment(BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP));
1613 break;
1615 case FRAME_BOTTOM_RIGHT:
1616 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
1617 break;
1619 default:
1620 break;