a new state begins life as a copy from the previous state, fixed Scale(). Note that BoundsOrigin() (and therefor Scale()) is called _a lot_ so we should cache the value! I started to work on this, but our lack of encapsulation strikes again... Layer::fLayerData is used directly all over the place.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13172 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-06-16 12:32:42 +00:00
parent 512d251741
commit 99b9d5ac8a
10 changed files with 241 additions and 206 deletions

View File

@ -361,7 +361,7 @@ Decorator::GetFootprint(BRegion *region)
- \c DEC_DRAG : Moves the window to the front and prepares to move the window
- \c DEC_MOVETOBACK : Moves the window to the back of the stack
- \c DEC_MOVETOFRONT : Moves the window to the front of the stack
- \c DEC_SLIDETAB : Initiates tab-sliding, including calling SlideTab()
- \c DEC_SLIDETAB : Initiates tab-sliding
- \c DEC_RESIZE : Handle window resizing as appropriate
- \c DEC_RESIZE_L
@ -418,23 +418,6 @@ Decorator::MoveBy(BPoint pt)
MoveBy(pt.x, pt.y);
}
/*!
\brief Moves the tab by the specified amount
\param dx x offset
\param dy y offset
\return The new tab rectangle.
Slides the tab by the x or y value. This function is not required to be
implemented by subclasses. Note that the tab rectangle returned does not
necessarily reflect _tabrect offset by the amount given - few people want to
slide a tab right off the window - that would be a Bad Thing (TM).
*/
BRect
Decorator::SlideTab(float dx, float dy)
{
return BRect(0, 0, 0, 0);
}
/*!
\brief Resizes the decorator frame
\param dx x offset

View File

@ -218,13 +218,6 @@ DefaultDecorator::GetFootprint(BRegion *region)
}
}
BRect
DefaultDecorator::SlideTab(float dx, float dy)
{
//return Decorator::SlideTab(dx,dy);
return _tabrect;
}
click_type
DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
{
@ -289,6 +282,9 @@ DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
// Clicking in the tab?
if (_tabrect.Contains(pt)) {
// tab sliding in any case if either shift key is held down
if (modifiers & B_SHIFT_KEY)
return DEC_SLIDETAB;
// Here's part of our window management stuff
if (buttons == B_SECONDARY_MOUSE_BUTTON)
return DEC_MOVETOBACK;
@ -353,9 +349,11 @@ DefaultDecorator::_DoLayout()
// calculate our tab rect
if (hasTab) {
// tab is initially on the left
fTabOffset = 0;
// distance from one item of the tab bar to another.
// In this case the text and close/zoom rects
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 7 : 10;
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 12 : 20;
font_height fh;
_drawdata.Font().Height(&fh);

View File

@ -51,7 +51,6 @@ public:
virtual void GetFootprint(BRegion *region);
virtual BRect SlideTab(float dx, float dy);
virtual click_type Clicked(BPoint pt, int32 buttons,
int32 modifiers);
@ -90,8 +89,7 @@ private:
int32 fBorderWidth;
// bool fSlidingTab;
// uint32 fTabOffset;
uint32 fTabOffset;
float fTextOffset;
float fMinTabWidth;

View File

@ -106,7 +106,11 @@ Desktop::AddDriver(DisplayDriver *driver)
// The driver is now owned by the screen
// TODO: be careful of screen initialization - monitor may not support 640x480
#if __HAIKU__
screen->SetMode(1400, 1050, B_RGB32, 60.f);
#else
screen->SetMode(800, 600, B_RGB32, 60.f);
#endif
fScreenList.AddItem(screen);
} else {

View File

@ -939,7 +939,7 @@ Layer::IsHidden(void) const
void
Layer::PushState()
{
LayerData *data = new LayerData();
LayerData *data = new LayerData(*fLayerData);
data->prevState = fLayerData;
fLayerData = data;
}
@ -1043,7 +1043,7 @@ Layer::Scale() const
LayerData *ld = fLayerData;
do {
scale += ld->Scale();
scale *= ld->Scale();
} while ((ld = ld->prevState));
return scale;

View File

@ -325,7 +325,7 @@ LayerData::LayerData(const LayerData &data)
}
// destructor
LayerData::~LayerData(void)
LayerData::~LayerData()
{
delete prevState;
}

View File

@ -274,7 +274,7 @@ ServerApp::MonitorApp(void *data)
status_t err = B_OK;
while (!app->fQuitting) {
STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort));
// STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort));
err = reader.GetNextMessage(code, B_INFINITE_TIMEOUT);
if (err < B_OK) {
STRACE(("ServerApp::MonitorApp(): GetNextMessage returned %s\n", strerror(err)));
@ -1575,6 +1575,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_GET_ESCAPEMENTS_AS_FLOATS:
{
FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", fSignature.String()));
//printf("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", fSignature.String());
// Attached Data:
// 1) uint16 - family ID
// 2) uint16 - style ID
@ -1608,16 +1609,15 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
int32 numChars;
link.Read<int32>(&numChars);
//printf(" numChars: %ld\n", numChars);
/* char charArray[numChars];
for (int32 i = 0; i < numChars; i++) {
link.Read<char>(&charArray[i]);
}*/
uint32 numBytes;
link.Read<uint32>(&numBytes);
//printf(" numBytes: %ld\n", numBytes);
char* charArray = new char[numBytes];
link.Read(charArray, numBytes);
//printf(" charArray[numBytes - 1]: '%c'\n", charArray[numBytes - 1]);
float* escapements = new float[numChars];
// figure out escapements
@ -1629,6 +1629,8 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
font.SetRotation(rotation);
font.SetFlags(flags);
//if (true) {
//memset(escapements, 0, numChars * sizeof(float));
if (font.GetEscapements(charArray, numChars, escapements, delta)) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach(escapements, numChars * sizeof(float));
@ -1721,7 +1723,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_SCREEN_GET_MODE:
{
STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String()));
printf("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String());
//printf("ServerApp %s: AS_SCREEN_GET_MODE\n", fSignature.String());
// Attached data
// 1) int32 port to reply to
// 2) screen_id

View File

@ -104,6 +104,8 @@ WinBorder::WinBorder(const BRect &r,
fIsResizing(false),
fIsSlidingTab(false),
fInUpdate(false),
fRequestSent(false),
@ -157,167 +159,6 @@ WinBorder::~WinBorder()
delete fDecorator;
}
//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator
void
WinBorder::RebuildFullRegion()
{
STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName()));
fFull.MakeEmpty();
// Winborder holds Decorator's full regions. if any...
if (fDecorator)
fDecorator->GetFootprint(&fFull);
}
/*!
\brief Handles B_MOUSE_DOWN events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_DOWN message
\param sendMessage flag to send a B_MOUSE_DOWN message to the client
This function searches to see if the B_MOUSE_DOWN message is being sent to the window tab
or frame. If it is not, the message is passed on to the appropriate view in the client
BWindow. If the WinBorder is the target, then the proper action flag is set.
*/
click_type
WinBorder::MouseDown(const PointerEvent& event)
{
click_type action = _ActionFor(event);
if (fDecorator) {
// find out where user clicked in Decorator
switch(action) {
case DEC_CLOSE:
fIsClosing = true;
fDecorator->SetClose(true);
STRACE_CLICK(("===> DEC_CLOSE\n"));
break;
case DEC_ZOOM:
fIsZooming = true;
fDecorator->SetZoom(true);
STRACE_CLICK(("===> DEC_ZOOM\n"));
break;
case DEC_MINIMIZE:
fIsMinimizing = true;
fDecorator->SetMinimize(true);
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
break;
case DEC_DRAG:
fIsDragging = true;
fBringToFrontOnRelease = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_DRAG\n"));
break;
case DEC_RESIZE:
fIsResizing = true;
fLastMousePosition = event.where;
fResizingClickOffset = event.where - fFrame.RightBottom();
STRACE_CLICK(("===> DEC_RESIZE\n"));
break;
default:
break;
}
}
return action;
}
/*!
\brief Handles B_MOUSE_MOVED events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_MOVED message
This function doesn't do much except test continue any move/resize operations in progress
or check to see if the user clicked on a tab button (close, zoom, etc.) and then moused
away to prevent the operation from occurring
*/
void
WinBorder::MouseMoved(const PointerEvent& event)
{
if (fDecorator) {
if (fIsZooming) {
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
} else if (fIsClosing) {
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
} else if (fIsMinimizing) {
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
}
}
if (fIsDragging) {
// we will not come to front if we ever actually moved
fBringToFrontOnRelease = false;
BPoint delta = event.where - fLastMousePosition;
MoveBy(delta.x, delta.y);
}
if (fIsResizing) {
BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset);
BPoint delta = frame.RightBottom() - fFrame.RightBottom();
ResizeBy(delta.x, delta.y);
}
fLastMousePosition = event.where;
}
/*!
\brief Handles B_MOUSE_UP events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_UP message
This function resets any state objects (is_resizing flag and such) and if resetting a
button click flag, takes the appropriate action (i.e. clearing the close button flag also
takes steps to close the window).
*/
void
WinBorder::MouseUp(const PointerEvent& event)
{
if (fDecorator) {
click_type action = _ActionFor(event);
if (fIsZooming) {
fIsZooming = false;
fDecorator->SetZoom(false);
if (action == DEC_ZOOM)
Window()->Zoom();
return;
}
if (fIsClosing) {
fIsClosing = false;
fDecorator->SetClose(false);
if (action == DEC_CLOSE)
Window()->Quit();
return;
}
if (fIsMinimizing) {
fIsMinimizing = false;
fDecorator->SetMinimize(false);
if (action == DEC_MINIMIZE)
Window()->Minimize(true);
return;
}
}
if (fBringToFrontOnRelease) {
// TODO: We would have dragged the window if
// the mouse would have moved, but it didn't
// move -> This will bring the window to the
// front on R5 in FFM mode!
}
fIsDragging = false;
fIsResizing = false;
fBringToFrontOnRelease = false;
}
//! Sets the decorator focus to active or inactive colors
void
WinBorder::HighlightDecorator(const bool &active)
{
STRACE(("Decorator->Highlight\n"));
if (fDecorator)
fDecorator->SetFocus(active);
}
//! redraws a certain section of the window border
void
WinBorder::Draw(const BRect &r)
@ -442,6 +283,19 @@ y = (float)int32(y);
}
}
//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator
void
WinBorder::RebuildFullRegion()
{
STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName()));
fFull.MakeEmpty();
// Winborder holds Decorator's full regions. if any...
if (fDecorator)
fDecorator->GetFootprint(&fFull);
}
//! Sets the minimum and maximum sizes of the window
void
WinBorder::SetSizeLimits(float minWidth, float maxWidth,
@ -469,7 +323,7 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth,
if (fMaxHeight < fMinHeight)
fMaxHeight = fMinHeight;
#if 0 // On R5, Windows don't automatically resize
#if 0 // On R5, Windows don't automatically resize (the code works though)
// Automatically resize the window to fit these new limits
// if it does not already.
float minWidthDiff = fMinWidth - fFrame.Width();
@ -504,6 +358,181 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
*maxHeight = fMaxHeight;
}
/*!
\brief Handles B_MOUSE_DOWN events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_DOWN message
\param sendMessage flag to send a B_MOUSE_DOWN message to the client
This function searches to see if the B_MOUSE_DOWN message is being sent to the window tab
or frame. If it is not, the message is passed on to the appropriate view in the client
BWindow. If the WinBorder is the target, then the proper action flag is set.
*/
click_type
WinBorder::MouseDown(const PointerEvent& event)
{
click_type action = _ActionFor(event);
if (fDecorator) {
// find out where user clicked in Decorator
switch(action) {
case DEC_CLOSE:
fIsClosing = true;
fDecorator->SetClose(true);
STRACE_CLICK(("===> DEC_CLOSE\n"));
break;
case DEC_ZOOM:
fIsZooming = true;
fDecorator->SetZoom(true);
STRACE_CLICK(("===> DEC_ZOOM\n"));
break;
case DEC_MINIMIZE:
fIsMinimizing = true;
fDecorator->SetMinimize(true);
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
break;
case DEC_DRAG:
fIsDragging = true;
fBringToFrontOnRelease = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_DRAG\n"));
break;
case DEC_RESIZE:
fIsResizing = true;
fLastMousePosition = event.where;
fResizingClickOffset = event.where - fFrame.RightBottom();
STRACE_CLICK(("===> DEC_RESIZE\n"));
break;
case DEC_SLIDETAB:
fIsSlidingTab = true;
fLastMousePosition = event.where;
// fResizingClickOffset = event.where - fFrame.RightBottom();
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
break;
default:
break;
}
}
return action;
}
/*!
\brief Handles B_MOUSE_MOVED events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_MOVED message
This function doesn't do much except test continue any move/resize operations in progress
or check to see if the user clicked on a tab button (close, zoom, etc.) and then moused
away to prevent the operation from occurring
*/
void
WinBorder::MouseMoved(const PointerEvent& event)
{
if (fDecorator) {
if (fIsZooming) {
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
} else if (fIsClosing) {
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
} else if (fIsMinimizing) {
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
}
}
if (fIsDragging) {
// we will not come to front if we ever actually moved
fBringToFrontOnRelease = false;
BPoint delta = event.where - fLastMousePosition;
MoveBy(delta.x, delta.y);
}
if (fIsResizing) {
BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset);
BPoint delta = frame.RightBottom() - fFrame.RightBottom();
ResizeBy(delta.x, delta.y);
}
if (fIsSlidingTab) {
}
fLastMousePosition = event.where;
}
/*!
\brief Handles B_MOUSE_UP events and takes appropriate actions
\param evt PointerEvent object containing the info from the last B_MOUSE_UP message
This function resets any state objects (is_resizing flag and such) and if resetting a
button click flag, takes the appropriate action (i.e. clearing the close button flag also
takes steps to close the window).
*/
void
WinBorder::MouseUp(const PointerEvent& event)
{
if (fDecorator) {
click_type action = _ActionFor(event);
if (fIsZooming) {
fIsZooming = false;
fDecorator->SetZoom(false);
if (action == DEC_ZOOM)
Window()->Zoom();
return;
}
if (fIsClosing) {
fIsClosing = false;
fDecorator->SetClose(false);
if (action == DEC_CLOSE)
Window()->Quit();
return;
}
if (fIsMinimizing) {
fIsMinimizing = false;
fDecorator->SetMinimize(false);
if (action == DEC_MINIMIZE)
Window()->Minimize(true);
return;
}
}
if (fBringToFrontOnRelease) {
// TODO: We would have dragged the window if
// the mouse would have moved, but it didn't
// move -> This will bring the window to the
// front on R5 in FFM mode!
}
fIsDragging = false;
fIsResizing = false;
fIsSlidingTab = false;
fBringToFrontOnRelease = false;
}
// SetTabLocation
void
WinBorder::SetTabLocation(float location)
{
if (fDecorator)
fDecorator->SetTabLocation(location);
}
// TabLocation
float
WinBorder::TabLocation() const
{
if (fDecorator)
return fDecorator->TabLocation();
return 0.0;
}
//! Sets the decorator focus to active or inactive colors
void
WinBorder::HighlightDecorator(bool active)
{
STRACE(("Decorator->Highlight\n"));
if (fDecorator)
fDecorator->SetFocus(active);
}
//! Returns true if the point is in the WinBorder's screen area
bool
WinBorder::HasPoint(const BPoint& pt) const

View File

@ -104,7 +104,7 @@ class WinBorder : public Layer {
void UpdateDecorator();
void UpdateFont();
void UpdateScreen();
virtual bool HasClient() { return false; }
inline Decorator* GetDecorator() const { return fDecorator; }
@ -114,7 +114,11 @@ class WinBorder : public Layer {
inline uint32 WindowFlags() const { return fWindowFlags; }
inline uint32 Workspaces() const { return fWorkspaces; }
void HighlightDecorator(const bool &active);
// 0.0 -> left .... 1.0 -> right
void SetTabLocation(float location);
float TabLocation() const;
void HighlightDecorator(bool active);
bool HasPoint(const BPoint &pt) const;
@ -166,6 +170,8 @@ class WinBorder : public Layer {
bool fIsResizing;
bool fIsSlidingTab;
bool fInUpdate;
bool fRequestSent;

View File

@ -366,12 +366,27 @@ void
DisplayDriverPainter::InvertRect(const BRect &r)
{
if (Lock()) {
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r));
BRect vr(min_c(r.left, r.right),
min_c(r.top, r.bottom),
max_c(r.left, r.right),
max_c(r.top, r.bottom));
vr = fPainter->ClipRect(vr);
if (vr.IsValid()) {
fGraphicsCard->HideSoftwareCursor(vr);
BRect touched = fPainter->InvertRect(r);
// try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) {
BRegion region(vr);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->InvertRegion(region);
} else {
fPainter->InvertRect(vr);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
fGraphicsCard->Invalidate(vr);
}
fGraphicsCard->ShowSoftwareCursor();
}
Unlock();
}