6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
35 // Classes used for setting up and managing background images
39 #include <ControlLook.h>
41 #include <TranslationKit.h>
47 #include "BackgroundImage.h"
49 #include "Background.h"
56 const char* kBackgroundImageInfo
= B_BACKGROUND_INFO
;
57 const char* kBackgroundImageInfoOffset
= B_BACKGROUND_ORIGIN
;
58 const char* kBackgroundImageInfoTextOutline
= B_BACKGROUND_TEXT_OUTLINE
;
59 const char* kBackgroundImageInfoMode
= B_BACKGROUND_MODE
;
60 const char* kBackgroundImageInfoWorkspaces
= B_BACKGROUND_WORKSPACES
;
61 const char* kBackgroundImageInfoPath
= B_BACKGROUND_IMAGE
;
63 } // namespace BPrivate
66 // #pragma mark - BackgroundImage
70 BackgroundImage::GetBackgroundImage(const BNode
* node
, bool isDesktop
)
73 if (node
->GetAttrInfo(kBackgroundImageInfo
, &info
) != B_OK
)
77 char* buffer
= new char[info
.size
];
79 status_t error
= node
->ReadAttr(kBackgroundImageInfo
, info
.type
, 0,
80 buffer
, (size_t)info
.size
);
81 if (error
== info
.size
)
82 error
= container
.Unflatten(buffer
);
89 BackgroundImage
* backgroundImage
= NULL
;
90 for (int32 index
= 0; ; index
++) {
92 uint32 workspaces
= B_ALL_WORKSPACES
;
94 bool textWidgetLabelOutline
= false;
96 BBitmap
* bitmap
= NULL
;
98 if (container
.FindString(kBackgroundImageInfoPath
, index
, &path
)
100 bitmap
= BTranslationUtils::GetBitmap(path
);
102 PRINT(("failed to load background bitmap from path\n"));
107 be_control_look
->SetBackgroundInfo(container
);
109 container
.FindInt32(kBackgroundImageInfoWorkspaces
, index
,
110 (int32
*)&workspaces
);
111 container
.FindInt32(kBackgroundImageInfoMode
, index
, (int32
*)&mode
);
112 container
.FindBool(kBackgroundImageInfoTextOutline
, index
,
113 &textWidgetLabelOutline
);
114 container
.FindPoint(kBackgroundImageInfoOffset
, index
, &offset
);
116 BackgroundImage::BackgroundImageInfo
* imageInfo
= new
117 BackgroundImage::BackgroundImageInfo(workspaces
, bitmap
, mode
,
118 offset
, textWidgetLabelOutline
);
120 if (backgroundImage
== NULL
)
121 backgroundImage
= new BackgroundImage(node
, isDesktop
);
123 backgroundImage
->Add(imageInfo
);
126 return backgroundImage
;
130 BackgroundImage::BackgroundImageInfo::BackgroundImageInfo(uint32 workspaces
,
131 BBitmap
* bitmap
, Mode mode
, BPoint offset
, bool textWidgetOutline
)
133 fWorkspace(workspaces
),
137 fTextWidgetOutline(textWidgetOutline
)
142 BackgroundImage::BackgroundImageInfo::~BackgroundImageInfo()
148 BackgroundImage::BackgroundImage(const BNode
* node
, bool desktop
)
151 fDefinedByNode(*node
),
153 fShowingBitmap(NULL
),
154 fBitmapForWorkspaceList(1, true)
159 BackgroundImage::~BackgroundImage()
165 BackgroundImage::Add(BackgroundImageInfo
* info
)
167 fBitmapForWorkspaceList
.AddItem(info
);
172 BackgroundImage::Show(BView
* view
, int32 workspace
)
176 BackgroundImageInfo
* info
= ImageInfoForWorkspace(workspace
);
178 BPoseView
* poseView
= dynamic_cast<BPoseView
*>(fView
);
179 if (poseView
!= NULL
)
180 poseView
->SetWidgetTextOutline(info
->fTextWidgetOutline
);
188 BackgroundImage::Show(BackgroundImageInfo
* info
, BView
* view
)
190 BPoseView
* poseView
= dynamic_cast<BPoseView
*>(view
);
191 if (poseView
!= NULL
)
192 poseView
->SetWidgetTextOutline(info
->fTextWidgetOutline
);
194 if (info
->fBitmap
== NULL
) {
195 view
->ClearViewBitmap();
197 fShowingBitmap
= info
;
200 BRect
viewBounds(view
->Bounds());
201 BRect
bitmapBounds(info
->fBitmap
->Bounds());
202 BRect
destinationBitmapBounds(bitmapBounds
);
205 uint32 followFlags
= B_FOLLOW_TOP
| B_FOLLOW_LEFT
;
207 // figure out the display mode and the destination bounds for the bitmap
208 switch (info
->fMode
) {
211 destinationBitmapBounds
.OffsetBy(
212 (viewBounds
.Width() - bitmapBounds
.Width()) / 2,
213 (viewBounds
.Height() - bitmapBounds
.Height()) / 2);
219 if (BRectRatio(destinationBitmapBounds
)
220 >= BRectRatio(viewBounds
)) {
221 float overlap
= BRectHorizontalOverlap(viewBounds
,
222 destinationBitmapBounds
);
223 destinationBitmapBounds
.Set(-overlap
, 0,
224 viewBounds
.Width() + overlap
, viewBounds
.Height());
226 float overlap
= BRectVerticalOverlap(viewBounds
,
227 destinationBitmapBounds
);
228 destinationBitmapBounds
.Set(0, -overlap
,
229 viewBounds
.Width(), viewBounds
.Height() + overlap
);
231 followFlags
= B_FOLLOW_ALL
;
232 options
|= B_FILTER_BITMAP_BILINEAR
;
237 destinationBitmapBounds
.OffsetTo(info
->fOffset
);
242 destinationBitmapBounds
.OffsetBy(
243 (viewBounds
.Width() - bitmapBounds
.Width()) / 2,
244 (viewBounds
.Height() - bitmapBounds
.Height()) / 2);
246 options
|= B_TILE_BITMAP
;
250 // switch to the bitmap and force a redraw
251 view
->SetViewBitmap(info
->fBitmap
, bitmapBounds
, destinationBitmapBounds
,
252 followFlags
, options
);
254 fShowingBitmap
= info
;
259 BackgroundImage::BRectRatio(BRect rect
)
261 return rect
.Width() / rect
.Height();
266 BackgroundImage::BRectHorizontalOverlap(BRect hostRect
, BRect resizedRect
)
268 return ((hostRect
.Height() / resizedRect
.Height() * resizedRect
.Width())
269 - hostRect
.Width()) / 2;
274 BackgroundImage::BRectVerticalOverlap(BRect hostRect
, BRect resizedRect
)
276 return ((hostRect
.Width() / resizedRect
.Width() * resizedRect
.Height())
277 - hostRect
.Height()) / 2;
282 BackgroundImage::Remove()
284 if (fShowingBitmap
!= NULL
) {
285 fView
->ClearViewBitmap();
287 BPoseView
* poseView
= dynamic_cast<BPoseView
*>(fView
);
288 // make sure text widgets draw the default way, erasing
290 if (poseView
!= NULL
)
291 poseView
->SetWidgetTextOutline(true);
294 fShowingBitmap
= NULL
;
298 BackgroundImage::BackgroundImageInfo
*
299 BackgroundImage::ImageInfoForWorkspace(int32 workspace
) const
301 uint32 workspaceMask
= 1;
303 for ( ; workspace
; workspace
--)
306 int32 count
= fBitmapForWorkspaceList
.CountItems();
308 // do a simple lookup for the most likely candidate bitmap -
309 // pick the imageInfo that is only defined for this workspace over one
310 // that supports multiple workspaces
311 BackgroundImageInfo
* result
= NULL
;
312 for (int32 index
= 0; index
< count
; index
++) {
313 BackgroundImageInfo
* info
= fBitmapForWorkspaceList
.ItemAt(index
);
314 if (info
->fWorkspace
== workspaceMask
)
317 if (info
->fWorkspace
& workspaceMask
)
326 BackgroundImage::WorkspaceActivated(BView
* view
, int32 workspace
, bool state
)
329 // we only care for desktop bitmaps
334 // we only care comming into a new workspace, not leaving one
338 BackgroundImageInfo
* info
= ImageInfoForWorkspace(workspace
);
339 if (info
!= fShowingBitmap
) {
343 BPoseView
* poseView
= dynamic_cast<BPoseView
*>(view
);
344 if (poseView
!= NULL
)
345 poseView
->SetWidgetTextOutline(true);
347 view
->ClearViewBitmap();
351 fShowingBitmap
= info
;
357 BackgroundImage::ScreenChanged(BRect
, color_space
)
359 if (!fIsDesktop
|| fShowingBitmap
== NULL
)
362 if (fShowingBitmap
->fMode
== kCentered
) {
363 BRect
viewBounds(fView
->Bounds());
364 BRect
bitmapBounds(fShowingBitmap
->fBitmap
->Bounds());
365 BRect
destinationBitmapBounds(bitmapBounds
);
366 destinationBitmapBounds
.OffsetBy(
367 (viewBounds
.Width() - bitmapBounds
.Width()) / 2,
368 (viewBounds
.Height() - bitmapBounds
.Height()) / 2);
370 fView
->SetViewBitmap(fShowingBitmap
->fBitmap
, bitmapBounds
,
371 destinationBitmapBounds
, B_FOLLOW_NONE
, 0);
378 BackgroundImage::Refresh(BackgroundImage
* oldBackgroundImage
,
379 const BNode
* fromNode
, bool desktop
, BPoseView
* poseView
)
381 if (oldBackgroundImage
!= NULL
) {
382 oldBackgroundImage
->Remove();
383 delete oldBackgroundImage
;
386 BackgroundImage
* backgroundImage
= GetBackgroundImage(fromNode
, desktop
);
387 if (backgroundImage
!= NULL
&& poseView
->ViewMode() != kListMode
)
388 backgroundImage
->Show(poseView
, current_workspace());
390 return backgroundImage
;