* a bit more sophisticated
* now with actual view layers inside the windows * implemented the resize modes (from Adis code) * windows have resize handles and more correctly clip the views inside * bringing windows to front or sending them behind all others * one active window, the others are inactive * with and without focus follows mouse mode * bugs: - the region marked dirty when views are resized is not correct yet * todo: - move the dirty region from being managed by the desktop to being managed in each window (and being local too) - scrolling - hiding/showing of windows and views I plan to extend this to fully simulate asynchronous drawing from clients, to see any problems before using this in the real server one day. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15132 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -28,7 +28,10 @@ Desktop::Desktop(DrawView* drawView)
|
||||
fDrawView(drawView),
|
||||
fDrawingEngine(fDrawView->GetDrawingEngine()),
|
||||
|
||||
fWindows(64)
|
||||
fWindows(64),
|
||||
|
||||
fFocusFollowsMouse(true),
|
||||
fFocusWindow(NULL)
|
||||
{
|
||||
fDrawView->SetDesktop(this);
|
||||
|
||||
@@ -134,6 +137,10 @@ Desktop::MouseUp(BPoint where)
|
||||
void
|
||||
Desktop::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
|
||||
{
|
||||
WindowLayer* window;
|
||||
if (!fTracking && fFocusFollowsMouse && (window = WindowAt(where))) {
|
||||
SetFocusWindow(window);
|
||||
}
|
||||
if (fTracking) {
|
||||
int32 dx = (int32)(where.x - fLastMousePos.x);
|
||||
int32 dy = (int32)(where.y - fLastMousePos.y);
|
||||
@@ -239,6 +246,8 @@ Desktop::AddWindow(WindowLayer* window)
|
||||
|
||||
UnlockClipping();
|
||||
}
|
||||
SetFocusWindow(window);
|
||||
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
@@ -436,6 +445,9 @@ Desktop::BringToFront(WindowLayer* window)
|
||||
|
||||
UnlockClipping();
|
||||
}
|
||||
|
||||
if (!fFocusFollowsMouse)
|
||||
SetFocusWindow(TopWindow());
|
||||
}
|
||||
|
||||
// SendToBack
|
||||
@@ -467,8 +479,31 @@ Desktop::SendToBack(WindowLayer* window)
|
||||
|
||||
UnlockClipping();
|
||||
}
|
||||
|
||||
if (!fFocusFollowsMouse)
|
||||
SetFocusWindow(TopWindow());
|
||||
}
|
||||
|
||||
// SetFocusWindow
|
||||
void
|
||||
Desktop::SetFocusWindow(WindowLayer* window)
|
||||
{
|
||||
// TODO: find bug, this invalidates too many regions
|
||||
|
||||
if (fFocusWindow == window)
|
||||
return;
|
||||
|
||||
if (fFocusWindow)
|
||||
fFocusWindow->SetFocus(false);
|
||||
|
||||
fFocusWindow = window;
|
||||
|
||||
if (fFocusWindow)
|
||||
fFocusWindow->SetFocus(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// MarkDirty
|
||||
@@ -554,6 +589,11 @@ Desktop::_TriggerWindowRedrawing(BRegion* newDirtyRegion)
|
||||
void
|
||||
Desktop::_SetBackground(BRegion* background)
|
||||
{
|
||||
// NOTE: the drawing operation is caried out
|
||||
// in the clipping region rebuild, but it is
|
||||
// ok actually, because it also avoids trails on
|
||||
// moving windows
|
||||
|
||||
// remember the region not covered by any windows
|
||||
// and redraw the dirty background
|
||||
BRegion dirtyBackground(*background);
|
||||
|
||||
@@ -54,6 +54,8 @@ class Desktop : public BLooper {
|
||||
void BringToFront(WindowLayer* window);
|
||||
void SendToBack(WindowLayer* window);
|
||||
|
||||
void SetFocusWindow(WindowLayer* window);
|
||||
|
||||
#if MULTI_LOCKER
|
||||
# if 0
|
||||
bool ReadLockClipping() { return fClippingLock.ReadLock(); }
|
||||
@@ -105,6 +107,9 @@ private:
|
||||
DrawingEngine* fDrawingEngine;
|
||||
|
||||
BList fWindows;
|
||||
|
||||
bool fFocusFollowsMouse;
|
||||
WindowLayer* fFocusWindow;
|
||||
};
|
||||
|
||||
#endif // DESKTOP_H
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "Desktop.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "WindowLayer.h"
|
||||
|
||||
#include "ViewLayer.h"
|
||||
|
||||
@@ -39,6 +40,10 @@ ViewLayer::ViewLayer(BRect frame, const char* name,
|
||||
fScreenClipping(),
|
||||
fScreenClippingValid(false)
|
||||
{
|
||||
fFrame.left = float((int32)fFrame.left);
|
||||
fFrame.top = float((int32)fFrame.top);
|
||||
fFrame.right = float((int32)fFrame.right);
|
||||
fFrame.bottom = float((int32)fFrame.bottom);
|
||||
}
|
||||
|
||||
// destructor
|
||||
@@ -103,8 +108,11 @@ ViewLayer::AddChild(ViewLayer* layer)
|
||||
}
|
||||
fLastChild = layer;
|
||||
|
||||
if (fParent) {
|
||||
RebuildClipping(false);
|
||||
RebuildClipping(false);
|
||||
|
||||
if (fWindow) {
|
||||
layer->AttachedToWindow(fWindow);
|
||||
fWindow->MarkDirty(&layer->ScreenClipping());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +146,12 @@ ViewLayer::RemoveChild(ViewLayer* layer)
|
||||
layer->fPreviousSibling = NULL;
|
||||
layer->fNextSibling = NULL;
|
||||
|
||||
// TODO: track regions
|
||||
RebuildClipping(false);
|
||||
if (fParent) {
|
||||
RebuildClipping(false);
|
||||
}
|
||||
if (fWindow) {
|
||||
layer->DetachedFromWindow();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -201,13 +213,38 @@ ViewLayer::CountChildren() const
|
||||
return count;
|
||||
}
|
||||
|
||||
// ConvertToTop
|
||||
// ConvertToParent
|
||||
void
|
||||
ViewLayer::ConvertToTop(BPoint* point) const
|
||||
ViewLayer::ConvertToParent(BPoint* point) const
|
||||
{
|
||||
// remove scrolling offset and convert to parent coordinate space
|
||||
point->x += fFrame.left - fScrollingOffset.x;
|
||||
point->y += fFrame.top - fScrollingOffset.y;
|
||||
}
|
||||
|
||||
// ConvertToParent
|
||||
void
|
||||
ViewLayer::ConvertToParent(BRect* rect) const
|
||||
{
|
||||
// remove scrolling offset and convert to parent coordinate space
|
||||
rect->OffsetBy(fFrame.left - fScrollingOffset.x,
|
||||
fFrame.top - fScrollingOffset.y);
|
||||
}
|
||||
|
||||
// ConvertToParent
|
||||
void
|
||||
ViewLayer::ConvertToParent(BRegion* region) const
|
||||
{
|
||||
// remove scrolling offset and convert to parent coordinate space
|
||||
region->OffsetBy(fFrame.left - fScrollingOffset.x,
|
||||
fFrame.top - fScrollingOffset.y);
|
||||
}
|
||||
|
||||
// ConvertToTop
|
||||
void
|
||||
ViewLayer::ConvertToTop(BPoint* point) const
|
||||
{
|
||||
ConvertToParent(point);
|
||||
|
||||
if (fParent)
|
||||
fParent->ConvertToTop(point);
|
||||
@@ -217,9 +254,7 @@ ViewLayer::ConvertToTop(BPoint* point) const
|
||||
void
|
||||
ViewLayer::ConvertToTop(BRect* rect) const
|
||||
{
|
||||
// remove scrolling offset and convert to parent coordinate space
|
||||
rect->OffsetBy(fFrame.left - fScrollingOffset.x,
|
||||
fFrame.top - fScrollingOffset.y);
|
||||
ConvertToParent(rect);
|
||||
|
||||
if (fParent)
|
||||
fParent->ConvertToTop(rect);
|
||||
@@ -229,9 +264,7 @@ ViewLayer::ConvertToTop(BRect* rect) const
|
||||
void
|
||||
ViewLayer::ConvertToTop(BRegion* region) const
|
||||
{
|
||||
// remove scrolling offset and convert to parent coordinate space
|
||||
region->OffsetBy(fFrame.left - fScrollingOffset.x,
|
||||
fFrame.top - fScrollingOffset.y);
|
||||
ConvertToParent(region);
|
||||
|
||||
if (fParent)
|
||||
fParent->ConvertToTop(region);
|
||||
@@ -263,20 +296,22 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
fFrame.right += x;
|
||||
fFrame.bottom += y;
|
||||
|
||||
// TODO: broken when getting smaller
|
||||
// ... either here or in WindowLayer::ResizeBy()
|
||||
// layout the children
|
||||
for (ViewLayer* child = FirstChild(); child; child = NextChild())
|
||||
child->ParentResized(x, y, dirtyRegion);
|
||||
|
||||
// TODO: the dirty region must not include children!
|
||||
BRegion dirty(Bounds());
|
||||
dirty.Exclude(oldBounds);
|
||||
if (!(fFlags & B_FULL_UPDATE_ON_RESIZE))
|
||||
dirty.Exclude(oldBounds);
|
||||
|
||||
if (dirty.CountRects() > 0) {
|
||||
ConvertToTop(&dirty);
|
||||
dirtyRegion->Include(&dirty);
|
||||
}
|
||||
|
||||
RebuildClipping(false);
|
||||
_InvalidateScreenClipping(false);
|
||||
// TODO: layout children
|
||||
// TODO: ...
|
||||
_InvalidateScreenClipping(true);
|
||||
}
|
||||
|
||||
// ScrollBy
|
||||
@@ -287,26 +322,91 @@ ViewLayer::ScrollBy(int32 x, int32 y)
|
||||
fScrollingOffset.y += y;
|
||||
// TODO: CopyRegion...
|
||||
// TODO: ...
|
||||
|
||||
_InvalidateScreenClipping(true);
|
||||
}
|
||||
|
||||
// ParentResized
|
||||
void
|
||||
ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
{
|
||||
uint16 rm = fResizeMode & 0x0000FFFF;
|
||||
BRect newFrame = fFrame;
|
||||
|
||||
// follow with left side
|
||||
if ((rm & 0x0F00U) == _VIEW_RIGHT_ << 8)
|
||||
newFrame.left += x;
|
||||
else if ((rm & 0x0F00U) == _VIEW_CENTER_ << 8)
|
||||
newFrame.left += x / 2;
|
||||
|
||||
// follow with right side
|
||||
if ((rm & 0x000FU) == _VIEW_RIGHT_)
|
||||
newFrame.right += x;
|
||||
else if ((rm & 0x000FU) == _VIEW_CENTER_)
|
||||
newFrame.right += x / 2;
|
||||
|
||||
// follow with top side
|
||||
if ((rm & 0xF000U) == _VIEW_BOTTOM_ << 12)
|
||||
newFrame.top += y;
|
||||
else if ((rm & 0xF000U) == _VIEW_CENTER_ << 12)
|
||||
newFrame.top += y / 2;
|
||||
|
||||
// follow with bottom side
|
||||
if ((rm & 0x00F0U) == _VIEW_BOTTOM_ << 4)
|
||||
newFrame.bottom += y;
|
||||
else if ((rm & 0x00F0U) == _VIEW_CENTER_ << 4)
|
||||
newFrame.bottom += y / 2;
|
||||
|
||||
if (newFrame != fFrame) {
|
||||
// MoveBy will change fFrame, so cache it
|
||||
BRect oldFrame = fFrame;
|
||||
MoveBy(newFrame.left - oldFrame.left,
|
||||
newFrame.top - oldFrame.top);
|
||||
|
||||
ResizeBy(newFrame.Width() - oldFrame.Width(),
|
||||
newFrame.Height() - oldFrame.Height(), dirtyRegion);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, bool deep)
|
||||
{
|
||||
if (drawingEngine->Lock()) {
|
||||
// TODO intersect with local dirtyRegion
|
||||
// fill visible region with view color
|
||||
drawingEngine->SetHighColor(fViewColor);
|
||||
drawingEngine->FillRegion(effectiveClipping);
|
||||
// we can only draw within our own area
|
||||
BRegion redraw(ScreenClipping());
|
||||
// add the current clipping
|
||||
redraw.IntersectWith(effectiveClipping);
|
||||
|
||||
drawingEngine->MarkDirty(effectiveClipping);
|
||||
if (drawingEngine->Lock()) {
|
||||
drawingEngine->ConstrainClippingRegion(&redraw);
|
||||
|
||||
// fill visible region with white
|
||||
drawingEngine->SetHighColor(255, 255, 255);
|
||||
BRect b(Bounds());
|
||||
ConvertToTop(&b);
|
||||
drawingEngine->FillRect(b);
|
||||
|
||||
// draw a frame with the view color
|
||||
b.OffsetTo(0.0, 0.0);
|
||||
ConvertToTop(&b);
|
||||
drawingEngine->SetHighColor(fViewColor);
|
||||
drawingEngine->StrokeRect(b);
|
||||
drawingEngine->StrokeLine(b.LeftTop(), b.RightBottom());
|
||||
|
||||
drawingEngine->ConstrainClippingRegion(NULL);
|
||||
|
||||
drawingEngine->MarkDirty(&redraw);
|
||||
drawingEngine->Unlock();
|
||||
|
||||
// let children draw
|
||||
if (deep) {
|
||||
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
||||
child->Draw(drawingEngine, effectiveClipping, deep);
|
||||
}
|
||||
}
|
||||
|
||||
// let children draw
|
||||
if (deep) {
|
||||
// before passing the clipping on to children, exclude our
|
||||
// own region from the available clipping
|
||||
effectiveClipping->Exclude(&ScreenClipping());
|
||||
|
||||
for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
|
||||
child->Draw(drawingEngine, effectiveClipping, deep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ class ViewLayer {
|
||||
uint32 CountChildren() const;
|
||||
|
||||
// coordinate conversion
|
||||
void ConvertToParent(BPoint* point) const;
|
||||
void ConvertToParent(BRect* rect) const;
|
||||
void ConvertToParent(BRegion* region) const;
|
||||
|
||||
void ConvertToTop(BPoint* point) const;
|
||||
void ConvertToTop(BRect* rect) const;
|
||||
void ConvertToTop(BRegion* region) const;
|
||||
@@ -59,6 +63,9 @@ class ViewLayer {
|
||||
void ResizeBy(int32 dx, int32 dy, BRegion* dirtyRegion);
|
||||
void ScrollBy(int32 dx, int32 dy);
|
||||
|
||||
void ParentResized(int32 dx, int32 dy,
|
||||
BRegion* dirtyRegion);
|
||||
|
||||
void Draw(DrawingEngine* drawingEngine,
|
||||
BRegion* effectiveClipping,
|
||||
bool deep = false);
|
||||
|
||||
@@ -19,7 +19,12 @@ WindowLayer::WindowLayer(BRect frame, const char* name,
|
||||
fFrame(frame),
|
||||
fVisibleRegion(),
|
||||
|
||||
fBorderColor((rgb_color){ 255, 203, 0, 255 }),
|
||||
fBorderRegion(),
|
||||
fBorderRegionValid(false),
|
||||
fContentRegion(),
|
||||
fContentRegionValid(false),
|
||||
|
||||
fFocus(false),
|
||||
|
||||
fTopLayer(NULL),
|
||||
|
||||
@@ -95,6 +100,10 @@ WindowLayer::GetFullRegion(BRegion* region) const
|
||||
void
|
||||
WindowLayer::GetBorderRegion(BRegion* region) const
|
||||
{
|
||||
if (fBorderRegionValid) {
|
||||
*region = fBorderRegion;
|
||||
}
|
||||
|
||||
// TODO: speed up by avoiding "Exclude()"
|
||||
// start from the frame, extend to include decorator border
|
||||
region->Set(BRect(fFrame.left - 4, fFrame.top - 4,
|
||||
@@ -112,6 +121,45 @@ WindowLayer::GetBorderRegion(BRegion* region) const
|
||||
fFrame.right, fFrame.bottom));
|
||||
}
|
||||
|
||||
// GetContentRegion
|
||||
void
|
||||
WindowLayer::GetContentRegion(BRegion* region) const
|
||||
{
|
||||
if (fContentRegionValid) {
|
||||
*region = fContentRegion;
|
||||
}
|
||||
|
||||
// TODO: speed up by avoiding "Exclude()"
|
||||
// start from the frame, extend to include decorator border
|
||||
region->Set(fFrame);
|
||||
|
||||
// resize handle
|
||||
// if (B_DOCUMENT_WINDOW_LOOK)
|
||||
region->Exclude(BRect(fFrame.right - 10, fFrame.bottom - 10,
|
||||
fFrame.right, fFrame.bottom));
|
||||
}
|
||||
|
||||
// SetFocus
|
||||
void
|
||||
WindowLayer::SetFocus(bool focus)
|
||||
{
|
||||
if (Lock()) {
|
||||
// executed from Desktop thread, so it's fine
|
||||
// to use the clipping without locking
|
||||
if (fDesktop->ReadLockClipping()) {
|
||||
BRegion dirty(fBorderRegion);
|
||||
dirty.IntersectWith(&fVisibleRegion);
|
||||
MarkDirty(&dirty);
|
||||
|
||||
fDesktop->ReadUnlockClipping();
|
||||
}
|
||||
|
||||
fFocus = focus;
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// MoveBy
|
||||
void
|
||||
WindowLayer::MoveBy(int32 x, int32 y)
|
||||
@@ -121,6 +169,11 @@ WindowLayer::MoveBy(int32 x, int32 y)
|
||||
|
||||
fFrame.OffsetBy(x, y);
|
||||
|
||||
if (fBorderRegionValid)
|
||||
fBorderRegion.OffsetBy(x, y);
|
||||
if (fContentRegionValid)
|
||||
fContentRegion.OffsetBy(x, y);
|
||||
|
||||
fTopLayer->MoveBy(x, y);
|
||||
|
||||
// TODO: move a local dirty region!
|
||||
@@ -133,15 +186,21 @@ WindowLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
if (x == 0 && y == 0)
|
||||
return;
|
||||
|
||||
// BRegion previousBorder();
|
||||
//
|
||||
fFrame.right += x;
|
||||
fFrame.bottom += y;
|
||||
|
||||
fBorderRegionValid = false;
|
||||
fContentRegionValid = false;
|
||||
|
||||
// the border is dirty, put it into
|
||||
// dirtyRegion for a start
|
||||
GetBorderRegion(dirtyRegion);
|
||||
|
||||
// put the previous border region into the dirty region as well
|
||||
// to handle the part that was overlapping a layer
|
||||
// if B_DOCUMENT_WINDOW_LOOK
|
||||
dirtyRegion->Include(&fBorderRegion);
|
||||
|
||||
fTopLayer->ResizeBy(x, y, dirtyRegion);
|
||||
}
|
||||
|
||||
@@ -158,7 +217,8 @@ WindowLayer::AddChild(ViewLayer* layer)
|
||||
void
|
||||
WindowLayer::MarkDirty(BRegion* regionOnScreen)
|
||||
{
|
||||
fDesktop->MarkDirty(regionOnScreen);
|
||||
if (fDesktop)
|
||||
fDesktop->MarkDirty(regionOnScreen);
|
||||
}
|
||||
|
||||
# pragma mark -
|
||||
@@ -175,12 +235,24 @@ WindowLayer::_DrawContents(ViewLayer* layer)
|
||||
if (!layer)
|
||||
layer = fTopLayer;
|
||||
|
||||
BRegion effectiveLayerClipping(layer->ScreenClipping());
|
||||
effectiveLayerClipping.IntersectWith(&fVisibleRegion);
|
||||
effectiveLayerClipping.IntersectWith(fDesktop->DirtyRegion());
|
||||
if (effectiveLayerClipping.Frame().IsValid()) {
|
||||
layer->Draw(fDrawingEngine, &effectiveLayerClipping, true);
|
||||
fDesktop->MarkClean(&effectiveLayerClipping);
|
||||
if (!fContentRegionValid) {
|
||||
GetContentRegion(&fContentRegion);
|
||||
fContentRegionValid = true;
|
||||
}
|
||||
|
||||
BRegion effectiveWindowClipping(fContentRegion);
|
||||
// TODO: simplify
|
||||
// ideally, there would only be a local fDirtyRegion,
|
||||
// that we need to intersect with. fDirtyRegion would
|
||||
// alread only include fVisibleRegion
|
||||
effectiveWindowClipping.IntersectWith(&fVisibleRegion);
|
||||
effectiveWindowClipping.IntersectWith(fDesktop->DirtyRegion());
|
||||
if (effectiveWindowClipping.Frame().IsValid()) {
|
||||
layer->Draw(fDrawingEngine, &effectiveWindowClipping, true);
|
||||
|
||||
fDesktop->MarkClean(&fContentRegion);
|
||||
|
||||
// send UPDATE message to the client here
|
||||
}
|
||||
//else {
|
||||
//printf(" nothing to do\n");
|
||||
@@ -197,20 +269,29 @@ WindowLayer::_DrawBorder()
|
||||
snooze(10000);
|
||||
#endif
|
||||
|
||||
// construct the region containing just the border
|
||||
BRegion borderRegion(fVisibleRegion);
|
||||
borderRegion.Exclude(fFrame);
|
||||
// intersect with the Desktop's dirty region
|
||||
borderRegion.IntersectWith(fDesktop->DirtyRegion());
|
||||
if (!fBorderRegionValid) {
|
||||
GetBorderRegion(&fBorderRegion);
|
||||
fBorderRegionValid = true;
|
||||
}
|
||||
|
||||
if (borderRegion.Frame().IsValid()) {
|
||||
// construct the region of the border that needs redrawing
|
||||
BRegion dirtyBorderRegion(fBorderRegion);
|
||||
// intersect with our visible region
|
||||
dirtyBorderRegion.IntersectWith(&fVisibleRegion);
|
||||
// intersect with the Desktop's dirty region
|
||||
dirtyBorderRegion.IntersectWith(fDesktop->DirtyRegion());
|
||||
|
||||
if (dirtyBorderRegion.Frame().IsValid()) {
|
||||
if (fDrawingEngine->Lock()) {
|
||||
fDrawingEngine->SetHighColor(fBorderColor);
|
||||
fDrawingEngine->FillRegion(&borderRegion);
|
||||
fDrawingEngine->MarkDirty(&borderRegion);
|
||||
if (fFocus)
|
||||
fDrawingEngine->SetHighColor(255, 203, 0, 255);
|
||||
else
|
||||
fDrawingEngine->SetHighColor(216, 216, 216, 0);
|
||||
fDrawingEngine->FillRegion(&dirtyBorderRegion);
|
||||
fDrawingEngine->MarkDirty(&dirtyBorderRegion);
|
||||
fDrawingEngine->Unlock();
|
||||
}
|
||||
fDesktop->MarkClean(&borderRegion);
|
||||
fDesktop->MarkClean(&dirtyBorderRegion);
|
||||
}
|
||||
//else {
|
||||
//printf(" nothing to do\n");
|
||||
|
||||
@@ -31,6 +31,9 @@ class WindowLayer : public BLooper {
|
||||
{ return fVisibleRegion; }
|
||||
void GetFullRegion(BRegion* region) const;
|
||||
void GetBorderRegion(BRegion* region) const;
|
||||
void GetContentRegion(BRegion* region) const;
|
||||
|
||||
void SetFocus(bool focus);
|
||||
|
||||
void MoveBy(int32 x, int32 y);
|
||||
void ResizeBy(int32 x, int32 y, BRegion* dirtyRegion);
|
||||
@@ -50,7 +53,13 @@ class WindowLayer : public BLooper {
|
||||
// has to be called
|
||||
BRegion fVisibleRegion;
|
||||
|
||||
rgb_color fBorderColor;
|
||||
// caching local regions
|
||||
BRegion fBorderRegion;
|
||||
bool fBorderRegionValid;
|
||||
BRegion fContentRegion;
|
||||
bool fContentRegionValid;
|
||||
|
||||
bool fFocus;
|
||||
|
||||
ViewLayer* fTopLayer;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
class App : public BApplication {
|
||||
public:
|
||||
App();
|
||||
~App();
|
||||
|
||||
virtual void ReadyToRun();
|
||||
};
|
||||
@@ -22,7 +21,7 @@ class App : public BApplication {
|
||||
class Window : public BWindow {
|
||||
public:
|
||||
Window(const char* title);
|
||||
~Window();
|
||||
virtual ~Window();
|
||||
|
||||
void AddWindow(BRect frame, const char* name);
|
||||
void Test();
|
||||
@@ -31,16 +30,14 @@ class Window : public BWindow {
|
||||
Desktop* fDesktop;
|
||||
};
|
||||
|
||||
// constructor
|
||||
App::App()
|
||||
: BApplication("application/x-vnd.stippi.ClippingTest")
|
||||
{
|
||||
srand(real_time_clock_usecs());
|
||||
}
|
||||
|
||||
App::~App()
|
||||
{
|
||||
}
|
||||
|
||||
// ReadyToRun
|
||||
void
|
||||
App::ReadyToRun()
|
||||
{
|
||||
@@ -50,6 +47,7 @@ App::ReadyToRun()
|
||||
win->Test();
|
||||
}
|
||||
|
||||
// constructor
|
||||
Window::Window(const char* title)
|
||||
: BWindow(BRect(50, 50, 800, 650), title,
|
||||
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||
@@ -62,6 +60,7 @@ Window::Window(const char* title)
|
||||
fView->MakeFocus(true);
|
||||
}
|
||||
|
||||
// destructor
|
||||
Window::~Window()
|
||||
{
|
||||
fDesktop->Lock();
|
||||
@@ -75,6 +74,41 @@ Window::AddWindow(BRect frame, const char* name)
|
||||
WindowLayer* window = new WindowLayer(frame, name,
|
||||
fDesktop->GetDrawingEngine(),
|
||||
fDesktop);
|
||||
|
||||
// add a coupld children
|
||||
frame.OffsetTo(B_ORIGIN);
|
||||
frame.InsetBy(5.0, 5.0);
|
||||
if (frame.IsValid()) {
|
||||
ViewLayer* layer1 = new ViewLayer(frame, "View 1",
|
||||
B_FOLLOW_ALL,
|
||||
B_FULL_UPDATE_ON_RESIZE,
|
||||
(rgb_color){ 180, 180, 180, 255 });
|
||||
|
||||
frame.OffsetTo(B_ORIGIN);
|
||||
frame.InsetBy(15.0, 15.0);
|
||||
if (frame.IsValid()) {
|
||||
frame.bottom = (frame.top + frame.bottom) / 2 - 5;
|
||||
|
||||
ViewLayer* layer2 = new ViewLayer(frame, "View 2",
|
||||
B_FOLLOW_ALL,
|
||||
0,
|
||||
(rgb_color){ 120, 120, 120, 255 });
|
||||
|
||||
frame.OffsetBy(0.0, frame.Height() + 10);
|
||||
|
||||
ViewLayer* layer3 = new ViewLayer(frame, "View 3",
|
||||
B_FOLLOW_BOTTOM,
|
||||
0,
|
||||
(rgb_color){ 120, 120, 120, 255 });
|
||||
|
||||
|
||||
layer1->AddChild(layer2);
|
||||
layer1->AddChild(layer3);
|
||||
}
|
||||
|
||||
window->AddChild(layer1);
|
||||
}
|
||||
|
||||
window->Run();
|
||||
|
||||
BMessage message(MSG_ADD_WINDOW);
|
||||
|
||||
Reference in New Issue
Block a user