2005-06-17 23:10:15 +04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2001-2005, Haiku, Inc.
|
|
|
|
* Distributed under the terms of the MIT license.
|
|
|
|
*
|
|
|
|
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
|
|
|
* Adi Oanca <adioanca@cotty.iren.ro>
|
|
|
|
* Stephan Aßmus <superstippi@gmx.de>
|
|
|
|
*/
|
2005-06-24 02:43:11 +04:00
|
|
|
|
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
#include <Locker.h>
|
2003-02-14 04:53:53 +03:00
|
|
|
#include <Region.h>
|
|
|
|
#include <String.h>
|
2005-06-03 23:50:30 +04:00
|
|
|
#include <View.h> // for mouse button defines
|
|
|
|
|
2003-02-14 04:53:53 +03:00
|
|
|
#include <Debug.h>
|
2005-07-06 00:28:40 +04:00
|
|
|
#include <WindowPrivate.h>
|
2005-06-03 23:50:30 +04:00
|
|
|
#include "DebugInfoManager.h"
|
|
|
|
|
2003-02-14 04:53:53 +03:00
|
|
|
#include "Decorator.h"
|
2005-06-17 23:10:15 +04:00
|
|
|
#include "DecorManager.h"
|
2003-02-14 04:53:53 +03:00
|
|
|
#include "Desktop.h"
|
2004-01-13 03:38:42 +03:00
|
|
|
#include "Globals.h"
|
2005-06-03 23:50:30 +04:00
|
|
|
#include "MessagePrivate.h"
|
|
|
|
#include "PortLink.h"
|
2004-01-13 03:38:42 +03:00
|
|
|
#include "RootLayer.h"
|
2005-06-03 23:50:30 +04:00
|
|
|
#include "ServerWindow.h"
|
|
|
|
#include "TokenHandler.h"
|
2004-01-13 03:38:42 +03:00
|
|
|
#include "Workspace.h"
|
2003-02-14 04:53:53 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
#include "WinBorder.h"
|
|
|
|
|
2003-09-07 01:09:11 +04:00
|
|
|
// Toggle general function call output
|
2004-06-18 15:50:17 +04:00
|
|
|
//#define DEBUG_WINBORDER
|
2003-09-07 01:09:11 +04:00
|
|
|
|
|
|
|
// toggle
|
2004-06-03 00:44:46 +04:00
|
|
|
//#define DEBUG_WINBORDER_MOUSE
|
|
|
|
//#define DEBUG_WINBORDER_CLICK
|
2003-03-23 23:52:37 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_WINBORDER
|
2003-09-09 02:09:10 +04:00
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE(x) ;
|
2003-03-23 23:52:37 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DEBUG_WINBORDER_MOUSE
|
2003-09-09 02:09:10 +04:00
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACE_MOUSE(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE_MOUSE(x) ;
|
2003-03-23 23:52:37 +03:00
|
|
|
#endif
|
|
|
|
|
2003-04-05 05:51:35 +04:00
|
|
|
#ifdef DEBUG_WINBORDER_CLICK
|
2003-09-09 02:09:10 +04:00
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACE_CLICK(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE_CLICK(x) ;
|
2003-04-05 05:51:35 +04:00
|
|
|
#endif
|
|
|
|
|
2005-06-27 06:06:15 +04:00
|
|
|
WinBorder::WinBorder(const BRect &frame,
|
2005-06-03 23:50:30 +04:00
|
|
|
const char *name,
|
2005-06-28 06:00:48 +04:00
|
|
|
const uint32 look,
|
|
|
|
const uint32 feel,
|
|
|
|
const uint32 flags,
|
|
|
|
const uint32 workspaces,
|
|
|
|
ServerWindow *window,
|
2005-06-03 23:50:30 +04:00
|
|
|
DisplayDriver *driver)
|
2005-06-27 06:06:15 +04:00
|
|
|
: Layer(frame, name, B_NULL_TOKEN, B_FOLLOW_NONE, 0UL, driver),
|
2005-06-03 23:50:30 +04:00
|
|
|
fDecorator(NULL),
|
|
|
|
fTopLayer(NULL),
|
|
|
|
|
2005-06-25 17:09:19 +04:00
|
|
|
fCumulativeRegion(),
|
|
|
|
fInUpdateRegion(),
|
2004-06-11 06:46:48 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
fMouseButtons(0),
|
|
|
|
fKeyModifiers(0),
|
|
|
|
fLastMousePosition(-1.0, -1.0),
|
2003-02-14 04:53:53 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
fIsClosing(false),
|
|
|
|
fIsMinimizing(false),
|
|
|
|
fIsZooming(false),
|
2004-04-05 00:30:20 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
fIsDragging(false),
|
|
|
|
fBringToFrontOnRelease(false),
|
|
|
|
|
|
|
|
fIsResizing(false),
|
|
|
|
|
2005-06-16 16:32:42 +04:00
|
|
|
fIsSlidingTab(false),
|
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
fInUpdate(false),
|
|
|
|
fRequestSent(false),
|
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
fLook(look),
|
2005-06-03 23:50:30 +04:00
|
|
|
fLevel(-100),
|
2005-06-28 06:00:48 +04:00
|
|
|
fWindowFlags(flags),
|
|
|
|
fWorkspaces(workspaces),
|
2005-06-03 23:50:30 +04:00
|
|
|
|
|
|
|
fMinWidth(1.0),
|
2005-06-28 06:00:48 +04:00
|
|
|
fMaxWidth(32768.0),
|
2005-06-03 23:50:30 +04:00
|
|
|
fMinHeight(1.0),
|
2005-06-28 06:00:48 +04:00
|
|
|
fMaxHeight(32768.0),
|
2005-06-03 23:50:30 +04:00
|
|
|
|
|
|
|
cnt(0) // for debugging
|
2003-02-14 04:53:53 +03:00
|
|
|
{
|
2004-02-24 14:56:03 +03:00
|
|
|
// unlike BViews, windows start off as hidden
|
2004-06-11 22:21:57 +04:00
|
|
|
fHidden = true;
|
2005-06-28 06:00:48 +04:00
|
|
|
fServerWin = window;
|
2004-06-16 10:40:26 +04:00
|
|
|
fAdFlags = fAdFlags | B_LAYER_CHILDREN_DEPENDANT;
|
2004-06-18 19:24:36 +04:00
|
|
|
fFlags = B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE;
|
2005-06-16 00:36:43 +04:00
|
|
|
#ifdef NEW_CLIPPING
|
|
|
|
fRebuildDecRegion = true;
|
|
|
|
#endif
|
2005-06-28 06:00:48 +04:00
|
|
|
QuietlySetFeel(feel);
|
2005-06-27 06:06:15 +04:00
|
|
|
|
|
|
|
if (fFeel != B_NO_BORDER_WINDOW_LOOK) {
|
|
|
|
fDecorator = gDecorManager.AllocateDecorator(frame, name, fLook, fFeel,
|
2005-06-17 23:10:15 +04:00
|
|
|
fWindowFlags, fDriver);
|
2005-06-28 06:00:48 +04:00
|
|
|
if (fDecorator)
|
2005-06-03 23:50:30 +04:00
|
|
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
|
|
|
}
|
2004-03-28 18:58:39 +04:00
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
// do we need to change our size to let the decorator fit?
|
|
|
|
// _ResizeBy() will adapt the frame for validity before resizing
|
2005-07-06 00:28:40 +04:00
|
|
|
if (feel == kDesktopWindowFeel) {
|
|
|
|
// the desktop window spans over the whole screen
|
|
|
|
// ToDo: this functionality should be moved somewhere else (so that it
|
|
|
|
// is always used when the workspace is changed)
|
|
|
|
uint16 width, height;
|
|
|
|
uint32 colorSpace;
|
|
|
|
float frequency;
|
|
|
|
gDesktop->ActiveScreen()->GetMode(width, height, colorSpace, frequency);
|
|
|
|
_ResizeBy(width - frame.Width(), height - frame.Height());
|
|
|
|
} else
|
|
|
|
_ResizeBy(0, 0);
|
2005-06-28 06:00:48 +04:00
|
|
|
|
2005-06-16 22:58:14 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-02-28 23:23:51 +03:00
|
|
|
RebuildFullRegion();
|
2005-06-16 22:58:14 +04:00
|
|
|
#endif
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder %p, %s:\n", this, Name()));
|
|
|
|
STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", fFrame.left, fFrame.top,
|
|
|
|
fFrame.right, fFrame.bottom));
|
2005-06-28 06:00:48 +04:00
|
|
|
STRACE(("\tWindow %s\n", window ? window->Title() : "NULL"));
|
2003-02-14 04:53:53 +03:00
|
|
|
}
|
2004-06-11 06:46:48 +04:00
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
WinBorder::~WinBorder()
|
2003-02-14 04:53:53 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::~WinBorder()\n", Name()));
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
delete fTopLayer;
|
|
|
|
delete fDecorator;
|
2003-02-14 04:53:53 +03:00
|
|
|
}
|
2004-06-11 06:46:48 +04:00
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! redraws a certain section of the window border
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::Draw(const BRect &r)
|
2003-02-14 04:53:53 +03:00
|
|
|
{
|
2004-06-26 06:15:48 +04:00
|
|
|
#ifdef DEBUG_WINBORDER
|
2005-07-18 14:34:25 +04:00
|
|
|
printf("WinBorder(%s)::Draw() : ", Name());
|
2004-06-26 06:15:48 +04:00
|
|
|
r.PrintToStream();
|
|
|
|
#endif
|
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// if we have a visible region, it is decorator's one.
|
2005-06-03 23:50:30 +04:00
|
|
|
if (fDecorator) {
|
2005-09-24 00:34:19 +04:00
|
|
|
WinBorder* wb = GetRootLayer()->Focus();
|
2005-06-03 23:50:30 +04:00
|
|
|
if (wb == this)
|
2005-02-28 23:23:51 +03:00
|
|
|
fDecorator->SetFocus(true);
|
|
|
|
else
|
|
|
|
fDecorator->SetFocus(false);
|
2005-04-06 00:03:07 +04:00
|
|
|
fDecorator->Draw(r);
|
2005-02-28 23:23:51 +03:00
|
|
|
}
|
2003-02-14 04:53:53 +03:00
|
|
|
}
|
2004-06-11 06:46:48 +04:00
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Moves the winborder with redraw
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::MoveBy(float x, float y)
|
2003-02-14 04:53:53 +03:00
|
|
|
{
|
2005-06-28 16:25:32 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
|
2005-06-06 02:02:25 +04:00
|
|
|
x = (float)int32(x);
|
|
|
|
y = (float)int32(y);
|
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
if (x == 0.0 && y == 0.0)
|
|
|
|
return;
|
|
|
|
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::MoveBy(%.1f, %.1f) fDecorator: %p\n", Name(), x, y, fDecorator));
|
2005-06-03 23:50:30 +04:00
|
|
|
if (fDecorator)
|
2004-03-28 18:58:39 +04:00
|
|
|
fDecorator->MoveBy(x,y);
|
2004-06-19 17:04:50 +04:00
|
|
|
|
2005-04-29 03:56:40 +04:00
|
|
|
// NOTE: I moved this here from Layer::move_layer()
|
|
|
|
// Should this have any bad consequences I'm not aware of?
|
2005-06-25 17:09:19 +04:00
|
|
|
fCumulativeRegion.OffsetBy(x, y);
|
|
|
|
fInUpdateRegion.OffsetBy(x, y);
|
2005-04-29 03:56:40 +04:00
|
|
|
|
|
|
|
if (IsHidden()) {
|
|
|
|
// TODO: This is a work around for a design issue:
|
|
|
|
// The actual movement of a layer is done during
|
|
|
|
// the region rebuild. The mechanism is somewhat
|
|
|
|
// complicated and scheduled for refractoring...
|
|
|
|
// The problem here for hidden layers is that
|
|
|
|
// they seem *not* to be part of the layer tree.
|
|
|
|
// I don't think this is wrong as such, but of
|
|
|
|
// course the rebuilding of regions does not take
|
|
|
|
// place then. I don't understand yet the consequences
|
|
|
|
// for normal views, but this here fixes at least
|
|
|
|
// BWindows being MoveTo()ed before they are Show()n.
|
|
|
|
// In Layer::move_to, StartRebuildRegions() is called
|
|
|
|
// on fParent. But the rest of the this layers tree
|
|
|
|
// has not been added to fParent apperantly. So now
|
|
|
|
// you ask why fParent is even valid? Me too.
|
|
|
|
fFrame.OffsetBy(x, y);
|
|
|
|
fFull.OffsetBy(x, y);
|
|
|
|
fTopLayer->move_layer(x, y);
|
|
|
|
// ...and here we get really hacky...
|
|
|
|
fTopLayer->fFrame.OffsetTo(0.0, 0.0);
|
|
|
|
} else {
|
2005-09-19 02:43:31 +04:00
|
|
|
Layer::move_layer(x, y);
|
2005-04-29 03:56:40 +04:00
|
|
|
}
|
2005-06-03 23:50:30 +04:00
|
|
|
|
|
|
|
if (Window()) {
|
|
|
|
// dispatch a message to the client informing about the changed size
|
|
|
|
BMessage msg(B_WINDOW_MOVED);
|
|
|
|
msg.AddPoint("where", fFrame.LeftTop());
|
|
|
|
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
|
|
|
}
|
2005-06-28 16:25:32 +04:00
|
|
|
|
|
|
|
#else
|
|
|
|
Layer::MoveBy(x, y);
|
|
|
|
#endif
|
2003-02-14 04:53:53 +03:00
|
|
|
}
|
2004-06-11 06:46:48 +04:00
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::ResizeBy(float x, float y)
|
2003-02-14 04:53:53 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::ResizeBy()\n", Name()));
|
2004-06-19 17:04:50 +04:00
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
if (!_ResizeBy(x, y))
|
|
|
|
return;
|
|
|
|
|
2005-06-28 16:25:32 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-28 06:00:48 +04:00
|
|
|
if (Window()) {
|
|
|
|
// send a message to the client informing about the changed size
|
|
|
|
BMessage msg(B_WINDOW_RESIZED);
|
|
|
|
msg.AddInt64("when", system_time());
|
|
|
|
|
|
|
|
BRect frame(fTopLayer->Frame());
|
|
|
|
msg.AddInt32("width", frame.IntegerWidth());
|
|
|
|
msg.AddInt32("height", frame.IntegerHeight());
|
|
|
|
|
|
|
|
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
|
|
|
}
|
2005-06-28 16:25:32 +04:00
|
|
|
#endif
|
2005-06-28 06:00:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//! Resizes the winborder with redraw
|
|
|
|
bool
|
|
|
|
WinBorder::_ResizeBy(float x, float y)
|
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
float wantWidth = fFrame.Width() + x;
|
|
|
|
float wantHeight = fFrame.Height() + y;
|
|
|
|
|
|
|
|
// enforce size limits
|
|
|
|
if (wantWidth < fMinWidth)
|
|
|
|
wantWidth = fMinWidth;
|
|
|
|
if (wantWidth > fMaxWidth)
|
|
|
|
wantWidth = fMaxWidth;
|
|
|
|
|
|
|
|
if (wantHeight < fMinHeight)
|
|
|
|
wantHeight = fMinHeight;
|
|
|
|
if (wantHeight > fMaxHeight)
|
|
|
|
wantHeight = fMaxHeight;
|
|
|
|
|
|
|
|
x = wantWidth - fFrame.Width();
|
|
|
|
y = wantHeight - fFrame.Height();
|
|
|
|
|
2005-06-22 00:11:44 +04:00
|
|
|
if (x == 0.0 && y == 0.0)
|
2005-06-28 06:00:48 +04:00
|
|
|
return false;
|
2005-06-03 23:50:30 +04:00
|
|
|
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-22 00:11:44 +04:00
|
|
|
if (fDecorator)
|
|
|
|
fDecorator->ResizeBy(x, y);
|
|
|
|
|
|
|
|
if (IsHidden()) {
|
|
|
|
// TODO: See large comment in MoveBy()
|
|
|
|
fFrame.right += x;
|
|
|
|
fFrame.bottom += y;
|
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
if (fTopLayer)
|
|
|
|
fTopLayer->resize_layer(x, y);
|
2005-06-22 00:11:44 +04:00
|
|
|
} else {
|
|
|
|
resize_layer(x, y);
|
|
|
|
}
|
|
|
|
#else
|
2005-06-28 16:25:32 +04:00
|
|
|
Layer::ResizeBy(x, y);
|
2005-06-22 00:11:44 +04:00
|
|
|
#endif
|
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
return true;
|
2003-02-14 04:53:53 +03:00
|
|
|
}
|
2004-06-11 06:46:48 +04:00
|
|
|
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
// SetName
|
|
|
|
void
|
|
|
|
WinBorder::SetName(const char* name)
|
|
|
|
{
|
|
|
|
Layer::SetName(name);
|
|
|
|
|
|
|
|
// rebuild the clipping for the title area
|
|
|
|
// and redraw it.
|
|
|
|
|
|
|
|
// TODO: Adi, please have a look at this,
|
|
|
|
// it doesn't work yet.
|
|
|
|
if (fDecorator) {
|
|
|
|
// before the change
|
|
|
|
BRegion invalid(fDecorator->GetTabRect());
|
|
|
|
|
|
|
|
fDecorator->SetTitle(name);
|
|
|
|
|
|
|
|
// after the change
|
|
|
|
invalid.Include(fDecorator->GetTabRect());
|
|
|
|
|
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
RebuildFullRegion();
|
|
|
|
fRootLayer->GoRedraw(this, invalid);
|
|
|
|
#else
|
|
|
|
// TODO: ...
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2005-06-28 06:00:48 +04:00
|
|
|
|
2005-06-25 17:09:19 +04:00
|
|
|
// UpdateStart
|
|
|
|
void
|
|
|
|
WinBorder::UpdateStart()
|
|
|
|
{
|
|
|
|
// During updates we only want to draw what's in the update region
|
|
|
|
fInUpdate = true;
|
|
|
|
fRequestSent = false;
|
|
|
|
|
|
|
|
cnt--;
|
|
|
|
if (cnt != 0)
|
|
|
|
CRITICAL("Layer::UpdateStart(): wb->cnt != 0 -> Not Allowed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateEnd
|
|
|
|
void
|
|
|
|
WinBorder::UpdateEnd()
|
|
|
|
{
|
|
|
|
// The usual case. Drawing is permitted in the whole visible area.
|
|
|
|
|
|
|
|
fInUpdate = false;
|
|
|
|
|
|
|
|
fInUpdateRegion.MakeEmpty();
|
|
|
|
|
|
|
|
if (fCumulativeRegion.CountRects() > 0) {
|
|
|
|
BRegion reg(fCumulativeRegion);
|
|
|
|
RequestDraw(reg, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-16 22:58:14 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
|
2005-06-16 16:32:42 +04:00
|
|
|
//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator
|
|
|
|
void
|
|
|
|
WinBorder::RebuildFullRegion()
|
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::RebuildFullRegion()\n", Name()));
|
2005-06-16 16:32:42 +04:00
|
|
|
|
|
|
|
fFull.MakeEmpty();
|
|
|
|
|
|
|
|
// Winborder holds Decorator's full regions. if any...
|
|
|
|
if (fDecorator)
|
|
|
|
fDecorator->GetFootprint(&fFull);
|
|
|
|
}
|
|
|
|
|
2005-06-16 22:58:14 +04:00
|
|
|
#endif
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Sets the minimum and maximum sizes of the window
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::SetSizeLimits(float minWidth, float maxWidth,
|
|
|
|
float minHeight, float maxHeight)
|
2004-08-08 00:30:58 +04:00
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
if (minWidth < 0)
|
|
|
|
minWidth = 0;
|
2004-08-08 00:30:58 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
if (minHeight < 0)
|
|
|
|
minHeight = 0;
|
|
|
|
|
|
|
|
fMinWidth = minWidth;
|
|
|
|
fMaxWidth = maxWidth;
|
|
|
|
fMinHeight = minHeight;
|
|
|
|
fMaxHeight = maxHeight;
|
|
|
|
|
|
|
|
// give the Decorator a say in this too
|
|
|
|
if (fDecorator)
|
|
|
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
|
|
|
|
&fMaxWidth, &fMaxHeight);
|
|
|
|
|
|
|
|
if (fMaxWidth < fMinWidth)
|
|
|
|
fMaxWidth = fMinWidth;
|
|
|
|
|
|
|
|
if (fMaxHeight < fMinHeight)
|
|
|
|
fMaxHeight = fMinHeight;
|
|
|
|
|
|
|
|
// Automatically resize the window to fit these new limits
|
|
|
|
// if it does not already.
|
2005-06-28 06:00:48 +04:00
|
|
|
|
|
|
|
// On R5, Windows don't automatically resize, but since
|
|
|
|
// BWindow::ResizeTo() even honors the limits, I would guess
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
// this is a bug that we don't have to adopt.
|
|
|
|
// Note that most current apps will do unnecessary resizing
|
|
|
|
// after having set the limits, but the overhead is neglible.
|
2005-06-28 06:00:48 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
float minWidthDiff = fMinWidth - fFrame.Width();
|
|
|
|
float minHeightDiff = fMinHeight - fFrame.Height();
|
|
|
|
float maxWidthDiff = fMaxWidth - fFrame.Width();
|
|
|
|
float maxHeightDiff = fMaxHeight - fFrame.Height();
|
|
|
|
|
|
|
|
float xDiff = 0.0;
|
|
|
|
if (minWidthDiff > 0.0) // we're currently smaller than minWidth
|
|
|
|
xDiff = minWidthDiff;
|
|
|
|
else if (maxWidthDiff < 0.0) // we're currently larger than maxWidth
|
|
|
|
xDiff = maxWidthDiff;
|
|
|
|
|
|
|
|
float yDiff = 0.0;
|
|
|
|
if (minHeightDiff > 0.0) // we're currently smaller than minHeight
|
|
|
|
yDiff = minHeightDiff;
|
|
|
|
else if (maxHeightDiff < 0.0) // we're currently larger than maxHeight
|
|
|
|
yDiff = maxHeightDiff;
|
|
|
|
|
|
|
|
ResizeBy(xDiff, yDiff);
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSizeLimits
|
|
|
|
void
|
|
|
|
WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
|
|
|
|
float* minHeight, float* maxHeight) const
|
|
|
|
{
|
|
|
|
*minWidth = fMinWidth;
|
|
|
|
*maxWidth = fMaxWidth;
|
|
|
|
*minHeight = fMinHeight;
|
|
|
|
*maxHeight = fMaxHeight;
|
2004-08-08 00:30:58 +04:00
|
|
|
}
|
|
|
|
|
2005-09-08 20:53:42 +04:00
|
|
|
void
|
2005-09-19 02:43:31 +04:00
|
|
|
WinBorder::MouseDown(const PointerEvent& evt)
|
2005-09-08 20:53:42 +04:00
|
|
|
{
|
2005-09-19 02:43:31 +04:00
|
|
|
DesktopSettings desktopSettings(gDesktop);
|
|
|
|
|
|
|
|
// not in FFM mode?
|
|
|
|
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE) {
|
|
|
|
// default action is to drag the WinBorder
|
|
|
|
click_type action = DEC_DRAG;
|
|
|
|
Layer *target = LayerAt(evt.where);
|
|
|
|
// clicking a simple Layer.
|
|
|
|
if (target != this) {
|
|
|
|
if (GetRootLayer()->ActiveWorkspace()->Active() == this) {
|
|
|
|
target->MouseDown(evt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK)
|
|
|
|
target->MouseDown(evt);
|
|
|
|
else
|
|
|
|
goto activateWindow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// clicking WinBorder visible area
|
|
|
|
else {
|
|
|
|
winBorderAreaHandle:
|
|
|
|
|
|
|
|
if (fDecorator)
|
|
|
|
action = _ActionFor(evt);
|
2005-09-24 00:34:19 +04:00
|
|
|
|
|
|
|
// deactivate border buttons on first click(select)
|
|
|
|
if (GetRootLayer()->Focus() != this && action != DEC_MOVETOBACK
|
|
|
|
&& action != DEC_RESIZE && action != DEC_SLIDETAB)
|
|
|
|
action = DEC_DRAG;
|
|
|
|
|
2005-09-19 02:43:31 +04:00
|
|
|
// set decorator internals
|
|
|
|
switch(action) {
|
|
|
|
case DEC_CLOSE:
|
|
|
|
fIsClosing = true;
|
|
|
|
fDecorator->SetClose(true);
|
|
|
|
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
|
|
|
break;
|
2005-09-16 09:10:21 +04:00
|
|
|
|
2005-09-19 02:43:31 +04:00
|
|
|
case DEC_ZOOM:
|
|
|
|
fIsZooming = true;
|
|
|
|
fDecorator->SetZoom(true);
|
|
|
|
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
|
|
|
break;
|
2005-09-16 09:10:21 +04:00
|
|
|
|
2005-09-19 02:43:31 +04:00
|
|
|
case DEC_MINIMIZE:
|
|
|
|
fIsMinimizing = true;
|
|
|
|
fDecorator->SetMinimize(true);
|
|
|
|
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEC_DRAG:
|
|
|
|
fIsDragging = true;
|
|
|
|
fLastMousePosition = evt.where;
|
|
|
|
STRACE_CLICK(("===> DEC_DRAG\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEC_RESIZE:
|
|
|
|
fIsResizing = true;
|
|
|
|
fLastMousePosition = evt.where;
|
|
|
|
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEC_SLIDETAB:
|
|
|
|
fIsSlidingTab = true;
|
|
|
|
fLastMousePosition = evt.where;
|
|
|
|
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// based on what the Decorator returned, properly place this window.
|
|
|
|
if (action == DEC_MOVETOBACK) {
|
2005-10-06 14:45:46 +04:00
|
|
|
Workspace::State oldWMState;
|
|
|
|
GetRootLayer()->ActiveWorkspace()->GetState(&oldWMState);
|
|
|
|
|
2005-09-19 02:43:31 +04:00
|
|
|
GetRootLayer()->ActiveWorkspace()->MoveToBack(this);
|
2005-10-06 14:45:46 +04:00
|
|
|
|
|
|
|
GetRootLayer()->RevealNewWMState(oldWMState);
|
2005-09-19 02:43:31 +04:00
|
|
|
}
|
2005-09-20 02:41:48 +04:00
|
|
|
else {
|
2005-10-03 01:55:45 +04:00
|
|
|
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
2005-09-20 02:41:48 +04:00
|
|
|
|
2005-09-19 02:43:31 +04:00
|
|
|
activateWindow:
|
2005-10-03 01:55:45 +04:00
|
|
|
GetRootLayer()->SetActive(this);
|
2005-09-19 02:43:31 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// in FFM mode
|
|
|
|
else {
|
|
|
|
Layer *target = LayerAt(evt.where);
|
|
|
|
// clicking a simple Layer; forward event.
|
|
|
|
if (target != this)
|
|
|
|
target->MouseDown(evt);
|
|
|
|
// clicking inside our visible area.
|
|
|
|
else
|
|
|
|
goto winBorderAreaHandle;
|
|
|
|
}
|
2005-09-08 20:53:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WinBorder::MouseUp(const PointerEvent& event)
|
|
|
|
{
|
2005-10-03 01:55:45 +04:00
|
|
|
bool invalidate = false;
|
2005-09-16 09:10:21 +04:00
|
|
|
if (fDecorator) {
|
|
|
|
click_type action = _ActionFor(event);
|
2005-10-03 01:55:45 +04:00
|
|
|
// TODO: present behavior is not fine!
|
|
|
|
// Decorator's Set*() methods _actualy draw_! on screen, not
|
|
|
|
// taking into account if that region is visible or not!
|
|
|
|
// Decorator redraw code should follow the same path as Layer's
|
|
|
|
// one!
|
2005-09-16 09:10:21 +04:00
|
|
|
if (fIsZooming) {
|
|
|
|
fIsZooming = false;
|
|
|
|
fDecorator->SetZoom(false);
|
2005-10-03 01:55:45 +04:00
|
|
|
if (action == DEC_ZOOM) {
|
|
|
|
invalidate = true;
|
2005-09-16 09:10:21 +04:00
|
|
|
Window()->NotifyZoom();
|
2005-10-03 01:55:45 +04:00
|
|
|
}
|
2005-09-16 09:10:21 +04:00
|
|
|
}
|
|
|
|
if (fIsClosing) {
|
|
|
|
fIsClosing = false;
|
|
|
|
fDecorator->SetClose(false);
|
2005-10-03 01:55:45 +04:00
|
|
|
if (action == DEC_CLOSE) {
|
|
|
|
invalidate = true;
|
2005-09-16 09:10:21 +04:00
|
|
|
Window()->NotifyQuitRequested();
|
2005-10-03 01:55:45 +04:00
|
|
|
}
|
2005-09-16 09:10:21 +04:00
|
|
|
}
|
|
|
|
if (fIsMinimizing) {
|
|
|
|
fIsMinimizing = false;
|
|
|
|
fDecorator->SetMinimize(false);
|
2005-10-03 01:55:45 +04:00
|
|
|
if (action == DEC_MINIMIZE) {
|
|
|
|
invalidate = true;
|
2005-09-16 09:10:21 +04:00
|
|
|
Window()->NotifyMinimize(true);
|
2005-10-03 01:55:45 +04:00
|
|
|
}
|
2005-09-16 09:10:21 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fIsDragging = false;
|
|
|
|
fIsResizing = false;
|
|
|
|
fIsSlidingTab = false;
|
2005-09-08 20:53:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WinBorder::MouseMoved(const PointerEvent& event, uint32 transit)
|
|
|
|
{
|
2005-09-16 09:10:21 +04:00
|
|
|
if (fDecorator) {
|
2005-10-03 01:55:45 +04:00
|
|
|
// TODO: present behavior is not fine!
|
|
|
|
// Decorator's Set*() methods _actualy draw_! on screen, not
|
|
|
|
// taking into account if that region is visible or not!
|
|
|
|
// Decorator redraw code should follow the same path as Layer's
|
|
|
|
// one!
|
2005-09-16 09:10:21 +04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2005-10-03 01:55:45 +04:00
|
|
|
|
2005-09-16 09:10:21 +04:00
|
|
|
if (fIsDragging) {
|
|
|
|
BPoint delta = event.where - fLastMousePosition;
|
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
MoveBy(delta.x, delta.y);
|
|
|
|
#else
|
|
|
|
do_MoveBy(delta.x, delta.y);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (fIsResizing) {
|
|
|
|
BPoint delta = event.where - fLastMousePosition;
|
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
ResizeBy(delta.x, delta.y);
|
|
|
|
#else
|
|
|
|
do_ResizeBy(delta.x, delta.y);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (fIsSlidingTab) {
|
|
|
|
// TODO: implement
|
|
|
|
}
|
2005-10-03 01:55:45 +04:00
|
|
|
|
2005-09-16 09:10:21 +04:00
|
|
|
fLastMousePosition = event.where;
|
2005-09-08 20:53:42 +04:00
|
|
|
}
|
|
|
|
|
2005-09-29 01:12:38 +04:00
|
|
|
void
|
|
|
|
WinBorder::WorkspaceActivated(int32 index, bool active)
|
|
|
|
{
|
|
|
|
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
|
|
|
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
|
|
|
activatedMsg.AddInt32("workspace", index);
|
|
|
|
activatedMsg.AddBool("active", active);
|
|
|
|
|
|
|
|
Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false);
|
|
|
|
}
|
|
|
|
|
2005-10-01 14:03:43 +04:00
|
|
|
void
|
|
|
|
WinBorder::WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces)
|
|
|
|
{
|
|
|
|
fWorkspaces = newWorkspaces;
|
|
|
|
|
|
|
|
BMessage changedMsg(B_WORKSPACES_CHANGED);
|
|
|
|
changedMsg.AddInt64("when", real_time_clock_usecs());
|
|
|
|
changedMsg.AddInt32("old", oldWorkspaces);
|
|
|
|
changedMsg.AddInt32("new", newWorkspaces);
|
|
|
|
|
|
|
|
Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false);
|
|
|
|
}
|
|
|
|
|
2005-06-16 16:32:42 +04:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// Unimplemented. Hook function for handling when system GUI colors change
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::UpdateColors()
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder %s: UpdateColors unimplemented\n", Name()));
|
2003-02-24 18:47:06 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// Unimplemented. Hook function for handling when the system decorator changes
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::UpdateDecorator()
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder %s: UpdateDecorator unimplemented\n", Name()));
|
2003-02-24 18:47:06 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// Unimplemented. Hook function for handling when a system font changes
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::UpdateFont()
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder %s: UpdateFont unimplemented\n", Name()));
|
2003-02-24 18:47:06 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// Unimplemented. Hook function for handling when the screen resolution changes
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
WinBorder::UpdateScreen()
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder %s: UpdateScreen unimplemented\n", Name()));
|
2003-02-24 18:47:06 +03:00
|
|
|
}
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
// QuietlySetFeel
|
|
|
|
void
|
|
|
|
WinBorder::QuietlySetFeel(int32 feel)
|
2005-02-28 23:23:51 +03:00
|
|
|
{
|
2005-04-21 22:57:34 +04:00
|
|
|
fFeel = feel;
|
|
|
|
|
2005-06-28 06:00:48 +04:00
|
|
|
switch (fFeel) {
|
2005-02-28 23:23:51 +03:00
|
|
|
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
|
|
|
case B_FLOATING_APP_WINDOW_FEEL:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_FLOATING_APP;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_MODAL_SUBSET_WINDOW_FEEL:
|
|
|
|
case B_MODAL_APP_WINDOW_FEEL:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_MODAL_APP;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_NORMAL_WINDOW_FEEL:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_NORMAL;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_FLOATING_ALL_WINDOW_FEEL:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_FLOATING_ALL;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_MODAL_ALL_WINDOW_FEEL:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_MODAL_ALL;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
2005-07-06 17:25:43 +04:00
|
|
|
// TODO: This case is bogus, since I'm sure "feel"
|
|
|
|
// is being represented by uint32 somewhere before
|
|
|
|
// this function is used. And B_SYSTEM_LAST is defined -10. -Stephan
|
2005-02-28 23:23:51 +03:00
|
|
|
case B_SYSTEM_LAST:
|
2005-07-06 20:26:53 +04:00
|
|
|
case kDesktopWindowFeel:
|
|
|
|
fLevel = B_SYSTEM_LAST;
|
2005-02-28 23:23:51 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_SYSTEM_FIRST:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_SYSTEM_FIRST;
|
2005-07-06 17:25:43 +04:00
|
|
|
break;
|
|
|
|
|
2005-02-28 23:23:51 +03:00
|
|
|
default:
|
2005-07-06 20:26:53 +04:00
|
|
|
fLevel = B_NORMAL;
|
2005-02-28 23:23:51 +03:00
|
|
|
}
|
2005-04-21 22:57:34 +04:00
|
|
|
|
|
|
|
// floating and modal windows must appear in every workspace where
|
2005-07-06 00:28:40 +04:00
|
|
|
// their main window is present. Thus their fWorkspaces will be set to
|
2005-04-21 22:57:34 +04:00
|
|
|
// '0x0' and they will be made visible when needed.
|
2005-06-03 23:50:30 +04:00
|
|
|
switch (fFeel) {
|
2005-04-21 22:57:34 +04:00
|
|
|
case B_MODAL_APP_WINDOW_FEEL:
|
2005-04-23 14:05:33 +04:00
|
|
|
break;
|
2005-04-21 22:57:34 +04:00
|
|
|
case B_MODAL_SUBSET_WINDOW_FEEL:
|
|
|
|
case B_FLOATING_APP_WINDOW_FEEL:
|
|
|
|
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
|
|
|
fWorkspaces = 0x0UL;
|
|
|
|
break;
|
|
|
|
case B_MODAL_ALL_WINDOW_FEEL:
|
|
|
|
case B_FLOATING_ALL_WINDOW_FEEL:
|
|
|
|
case B_SYSTEM_LAST:
|
|
|
|
case B_SYSTEM_FIRST:
|
|
|
|
fWorkspaces = 0xffffffffUL;
|
|
|
|
break;
|
|
|
|
case B_NORMAL_WINDOW_FEEL:
|
2005-04-23 14:05:33 +04:00
|
|
|
break;
|
2005-04-21 22:57:34 +04:00
|
|
|
}
|
2005-06-03 23:50:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// _ActionFor
|
|
|
|
click_type
|
|
|
|
WinBorder::_ActionFor(const PointerEvent& event) const
|
|
|
|
{
|
2005-09-16 09:10:21 +04:00
|
|
|
#ifndef NEW_INPUT_HANDING
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-03 23:50:30 +04:00
|
|
|
if (fTopLayer->fFullVisible.Contains(event.where))
|
|
|
|
return DEC_NONE;
|
2005-06-17 00:43:53 +04:00
|
|
|
else
|
2005-06-28 16:25:32 +04:00
|
|
|
#else
|
|
|
|
if (fTopLayer->fFullVisible2.Contains(event.where))
|
|
|
|
return DEC_NONE;
|
|
|
|
else
|
2005-09-16 09:10:21 +04:00
|
|
|
#endif
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
|
|
|
if (fDecorator)
|
2005-06-03 23:50:30 +04:00
|
|
|
return fDecorator->Clicked(event.where, event.buttons, event.modifiers);
|
|
|
|
else
|
|
|
|
return DEC_NONE;
|
|
|
|
}
|
|
|
|
|
2005-06-16 00:36:43 +04:00
|
|
|
#ifdef NEW_CLIPPING
|
|
|
|
void WinBorder::MovedByHook(float dx, float dy)
|
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::MovedByHook(%.1f, %.1f) fDecorator: %p\n", Name(), x, y, fDecorator));
|
2005-06-28 16:25:32 +04:00
|
|
|
|
2005-06-16 00:36:43 +04:00
|
|
|
fDecRegion.OffsetBy(dx, dy);
|
2005-06-28 16:25:32 +04:00
|
|
|
|
|
|
|
if (fDecorator)
|
|
|
|
fDecorator->MoveBy(dx, dy);
|
|
|
|
|
|
|
|
fCumulativeRegion.OffsetBy(dx, dy);
|
|
|
|
fInUpdateRegion.OffsetBy(dx, dy);
|
|
|
|
|
|
|
|
// dispatch a message to the client informing about the changed size
|
|
|
|
BMessage msg(B_WINDOW_MOVED);
|
|
|
|
msg.AddInt64("when", system_time());
|
|
|
|
msg.AddPoint("where", Frame().LeftTop());
|
|
|
|
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void WinBorder::ResizedByHook(float dx, float dy, bool automatic)
|
|
|
|
{
|
2005-07-18 14:34:25 +04:00
|
|
|
STRACE(("WinBorder(%s)::ResizedByHook(%.1f, %.1f, %s) fDecorator: %p\n", Name(), x, y, automatic?"true":"false", fDecorator));
|
2005-06-16 00:36:43 +04:00
|
|
|
fRebuildDecRegion = true;
|
2005-06-28 16:25:32 +04:00
|
|
|
|
|
|
|
if (fDecorator)
|
|
|
|
fDecorator->ResizeBy(dx, dy);
|
|
|
|
|
|
|
|
// send a message to the client informing about the changed size
|
|
|
|
BRect frame(fTopLayer->Frame());
|
|
|
|
BMessage msg(B_WINDOW_RESIZED);
|
|
|
|
msg.AddInt64("when", system_time());
|
|
|
|
msg.AddInt32("width", frame.IntegerWidth());
|
|
|
|
msg.AddInt32("height", frame.IntegerHeight());
|
|
|
|
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void WinBorder::set_decorator_region(BRect bounds)
|
|
|
|
{
|
|
|
|
fRebuildDecRegion = false;
|
|
|
|
|
2005-06-22 00:11:44 +04:00
|
|
|
if (fDecorator)
|
|
|
|
{
|
|
|
|
fDecRegion.MakeEmpty();
|
|
|
|
fDecorator->GetFootprint(&fDecRegion);
|
|
|
|
}
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
2005-10-07 20:05:22 +04:00
|
|
|
void
|
|
|
|
WinBorder::_ReserveRegions(BRegion ®)
|
2005-06-16 00:36:43 +04:00
|
|
|
{
|
2005-10-07 20:05:22 +04:00
|
|
|
BRegion reserve(reg);
|
|
|
|
reserve.IntersectWith(&fDecRegion);
|
|
|
|
fVisible2.Include(&reserve);
|
|
|
|
reg.Exclude(&reserve);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
2005-10-07 20:05:22 +04:00
|
|
|
void
|
|
|
|
WinBorder::_GetWantedRegion(BRegion ®)
|
2005-06-16 00:36:43 +04:00
|
|
|
{
|
|
|
|
if (fRebuildDecRegion)
|
|
|
|
{
|
|
|
|
set_decorator_region(Bounds());
|
2005-06-22 00:11:44 +04:00
|
|
|
// TODO? the decorator should be in WinBorder coordinates?? It's easier not to.
|
|
|
|
//ConvertToScreen2(&fDecRegion);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
BRect screenFrame(Bounds());
|
|
|
|
ConvertToScreen2(&screenFrame);
|
|
|
|
reg.Set(screenFrame);
|
|
|
|
|
|
|
|
BRegion screenReg(GetRootLayer()->Bounds());
|
|
|
|
|
|
|
|
reg.IntersectWith(&screenReg);
|
|
|
|
|
|
|
|
reg.Include(&fDecRegion);
|
|
|
|
}
|
2005-06-24 02:43:11 +04:00
|
|
|
#endif
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
|
|
|
|
// SetTopLayer
|
|
|
|
void
|
|
|
|
WinBorder::SetTopLayer(Layer* layer)
|
|
|
|
{
|
|
|
|
if (layer) {
|
|
|
|
fTopLayer = layer;
|
|
|
|
fTopLayer->SetAsTopLayer(true);
|
|
|
|
|
|
|
|
// connect decorator and top layer. (?)
|
|
|
|
AddChild(fTopLayer, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|