* Fix the completely broken desktop icon size changing which I introduced

yesterday. It needs to auto-place icons which go out of view or underneath
  the deskbar or a replicant. Also it obviously cannot scroll to keep the
  view "centered" as normal Tracker windows.
* Fix/improve the desktop context menu with regards to icon size options. It
  also displays the shortcuts, which now work on the desktop too.
* When doing an icon cleanup on the desktop, not only the deskbar is avoided,
  but also replicant views.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30009 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-04-07 21:09:10 +00:00
parent 9b4cfa9d3b
commit 96da4b41b0
5 changed files with 108 additions and 20 deletions

View File

@ -77,6 +77,21 @@ BDeskWindow::BDeskWindow(LockingList<BWindow> *windowList)
fTrashContextMenu(0),
fShouldUpdateAddonShortcuts(true)
{
// Add icon view switching shortcuts. These are displayed in the context
// menu, although they obviously don't work from those menu items.
BMessage* message = new BMessage(kIconMode);
AddShortcut('1', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kMiniIconMode);
AddShortcut('2', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 1);
AddShortcut('+', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 0);
AddShortcut('-', B_COMMAND_KEY, message, PoseView());
}
@ -266,7 +281,7 @@ BDeskWindow::AddWindowContextMenus(BMenu *menu)
BMessage* message = new BMessage(kIconMode);
message->AddInt32("size", 32);
BMenuItem* item = new BMenuItem("32 x 32", message, '1');
BMenuItem* item = new BMenuItem("32 x 32", message);
item->SetMarked(PoseView()->IconSizeInt() == 32);
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
@ -292,9 +307,28 @@ BDeskWindow::AddWindowContextMenus(BMenu *menu)
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
menu->AddItem(iconSizeMenu);
iconSizeMenu->AddSeparatorItem();
item = new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode));
message = new BMessage(kIconMode);
message->AddInt32("scale", 0);
item = new BMenuItem("Decrease Size", message, '-');
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
message = new BMessage(kIconMode);
message->AddInt32("scale", 1);
item = new BMenuItem("Increase Size", message, '+');
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
// A sub menu where the super item can be invoked.
menu->AddItem(iconSizeMenu);
iconSizeMenu->Superitem()->SetShortcut('1', B_COMMAND_KEY);
iconSizeMenu->Superitem()->SetMessage(new BMessage(kIconMode));
iconSizeMenu->Superitem()->SetTarget(PoseView());
iconSizeMenu->Superitem()->SetMarked(PoseView()->ViewMode() == kIconMode);
item = new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode), '2');
item->SetMarked(PoseView()->ViewMode() == kMiniIconMode);
menu->AddItem(item);

View File

@ -891,7 +891,7 @@ debugger("BPose::SetLocation() - infinite location");
BRect
BPose::CalcRect(BPoint loc, const BPoseView *poseView, bool minimalRect)
BPose::CalcRect(BPoint loc, const BPoseView *poseView, bool minimalRect) const
{
ASSERT(poseView->ViewMode() == kListMode);
@ -913,7 +913,7 @@ BPose::CalcRect(BPoint loc, const BPoseView *poseView, bool minimalRect)
BRect
BPose::CalcRect(const BPoseView *poseView)
BPose::CalcRect(const BPoseView *poseView) const
{
ASSERT(poseView->ViewMode() != kListMode);

View File

@ -91,8 +91,9 @@ class BPose {
bool PointInPose(BPoint poseLoc, const BPoseView *, BPoint where,
BTextWidget ** = NULL) const;
bool PointInPose(const BPoseView *, BPoint where) const ;
BRect CalcRect(BPoint loc, const BPoseView *, bool minimal_rect = false);
BRect CalcRect(const BPoseView *);
BRect CalcRect(BPoint loc, const BPoseView *,
bool minimal_rect = false) const;
BRect CalcRect(const BPoseView *) const;
void UpdateAllWidgets(int32 poseIndex, BPoint poseLoc, BPoseView *);
void UpdateWidgetAndModel(Model *resolvedModel, const char *attrName,
uint32 attrType, int32 poseIndex, BPoint poseLoc, BPoseView *view);

View File

@ -2741,9 +2741,11 @@ BPoseView::SetViewMode(uint32 newMode)
fViewState->SetViewMode(newMode);
// try to lock the center of the pose view when scaling icons
// Try to lock the center of the pose view when scaling icons, but not
// if we are the desktop.
BPoint scaleOffset(0, 0);
if (newMode == kIconMode && oldMode == kIconMode) {
bool iconSizeChanged = newMode == kIconMode && oldMode == kIconMode;
if (!IsDesktopWindow() && iconSizeChanged) {
// definitely changing the icon size, so we will need to scroll
BRect bounds(Bounds());
BPoint center(bounds.LeftTop());
@ -2795,6 +2797,9 @@ BPoseView::SetViewMode(uint32 newMode)
|| fViewState->IconSize() != lastIconSize);
}
// check if we need to re-place poses when they are out of view
bool checkLocations = IsDesktopWindow() && iconSizeChanged;
BPoint oldOffset;
BPoint oldGrid;
if (mapIcons)
@ -2807,10 +2812,16 @@ BPoseView::SetViewMode(uint32 newMode)
int32 count = fPoseList->CountItems();
for (int32 index = 0; index < count; index++) {
BPose *pose = fPoseList->ItemAt(index);
if (pose->HasLocation() == false)
if (pose->HasLocation() == false) {
newPoseList.AddItem(pose);
else if (mapIcons)
} else if (checkLocations && !IsValidLocation(pose)) {
// this icon has a location, but needs to be remapped, because
// it is going out of view for example
RemoveFromVSList(pose);
newPoseList.AddItem(pose);
} else if (mapIcons) {
MapToNewIconMode(pose, oldGrid, oldOffset);
}
}
}
@ -3216,19 +3227,16 @@ BPoseView::PlacePose(BPose *pose, BRect &viewBounds)
// make pose rect a little bigger to ensure space between poses
rect.InsetBy(-3, 0);
BRect deskbarFrame;
bool checkDeskbarFrame = false;
if (IsDesktopWindow() && GetDeskbarFrame(&deskbarFrame) == B_OK) {
checkDeskbarFrame = true;
deskbarFrame.InsetBy(-10, -10);
}
bool checkValidLocation = IsDesktopWindow();
// find an empty slot to put pose into
if (fVSPoseList->CountItems() > 0)
if (fVSPoseList->CountItems() > 0) {
while (SlotOccupied(rect, viewBounds)
// avoid Deskbar
|| (checkDeskbarFrame && deskbarFrame.Intersects(rect)))
// check good location on the desktop
|| (checkValidLocation && !IsValidLocation(rect))) {
NextSlot(pose, rect, viewBounds);
}
}
rect.InsetBy(3, 0);
@ -3239,6 +3247,49 @@ BPoseView::PlacePose(BPose *pose, BRect &viewBounds)
}
bool
BPoseView::IsValidLocation(const BPose *pose)
{
if (!IsDesktopWindow())
return true;
BRect rect(pose->CalcRect(this));
rect.InsetBy(-3, 0);
return IsValidLocation(rect);
}
bool
BPoseView::IsValidLocation(const BRect& rect)
{
if (!IsDesktopWindow())
return true;
// on the desktop, don't allow icons outside of the view bounds
if (!Bounds().Contains(rect))
return false;
// also check the deskbar frame
BRect deskbarFrame;
if (GetDeskbarFrame(&deskbarFrame) == B_OK) {
deskbarFrame.InsetBy(-10, -10);
if (deskbarFrame.Intersects(rect))
return false;
}
// check replicants
for (int32 i = 0; BView* child = ChildAt(i); i++) {
BRect childFrame = child->Frame();
childFrame.InsetBy(-5, -5);
if (childFrame.Intersects(rect))
return false;
}
// location is ok
return true;
}
status_t
BPoseView::GetDeskbarFrame(BRect* frame)
{

View File

@ -479,6 +479,8 @@ class BPoseView : public BView {
// find poses that need placing and place them in a new spot
void PlacePose(BPose *, BRect &);
// find a new place for a pose, starting at fHintLocation and place it
bool IsValidLocation(const BPose *pose);
bool IsValidLocation(const BRect& rect);
status_t GetDeskbarFrame(BRect* frame);
bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
void NextSlot(BPose *, BRect &poseRect, BRect viewBounds);