huge cleanup, support for SetSizeLimits, support for truncating strings, numerous decorator bug fixes, Layer does not draw when view color is B_TRANSPARENT_COLOR, cleaner dispatching of mouse events to the WinBorder in RootLayer, commented the char map selection in the font server, as it seems glyph lookup by unicode index works much better with the default map
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12945 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* a helper function to truncate strings
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TRUNCATE_STRING_H
|
||||||
|
#define TRUNCATE_STRING_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// truncated_string
|
||||||
|
void
|
||||||
|
truncate_string(const char* string,
|
||||||
|
uint32 mode, float width, char* result,
|
||||||
|
const float* escapementArray, float fontSize,
|
||||||
|
float ellipsisWidth, int32 length, int32 numChars);
|
||||||
|
|
||||||
|
#endif // STRING_TRUNCATION_H
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Copyright (c) 2001-2002, Haiku, Inc.
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -21,119 +21,164 @@
|
|||||||
//
|
//
|
||||||
// File Name: Decorator.h
|
// File Name: Decorator.h
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Base class for window decorators
|
// Description: Base class for window decorators
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#ifndef _DECORATOR_H_
|
#ifndef _DECORATOR_H_
|
||||||
#define _DECORATOR_H_
|
#define _DECORATOR_H_
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
#include "LayerData.h"
|
|
||||||
#include "ColorSet.h"
|
#include "ColorSet.h"
|
||||||
|
#include "LayerData.h"
|
||||||
|
|
||||||
class DisplayDriver;
|
class DisplayDriver;
|
||||||
class ServerFont;
|
class ServerFont;
|
||||||
class BRegion;
|
class BRegion;
|
||||||
|
|
||||||
typedef enum { DEC_NONE=0, DEC_ZOOM, DEC_CLOSE, DEC_MINIMIZE,
|
typedef enum {
|
||||||
DEC_TAB, DEC_DRAG, DEC_MOVETOBACK, DEC_MOVETOFRONT, DEC_SLIDETAB,
|
DEC_NONE = 0,
|
||||||
|
DEC_ZOOM,
|
||||||
|
DEC_CLOSE,
|
||||||
|
DEC_MINIMIZE,
|
||||||
|
DEC_TAB,
|
||||||
|
DEC_DRAG,
|
||||||
|
DEC_MOVETOBACK,
|
||||||
|
DEC_MOVETOFRONT,
|
||||||
|
DEC_SLIDETAB,
|
||||||
|
|
||||||
DEC_RESIZE, CLICK_RESIZE_L, CLICK_RESIZE_T,
|
DEC_RESIZE,
|
||||||
CLICK_RESIZE_R, CLICK_RESIZE_B, CLICK_RESIZE_LT, CLICK_RESIZE_RT,
|
CLICK_RESIZE_L,
|
||||||
CLICK_RESIZE_LB, CLICK_RESIZE_RB } click_type;
|
CLICK_RESIZE_T,
|
||||||
|
CLICK_RESIZE_R,
|
||||||
|
CLICK_RESIZE_B,
|
||||||
|
CLICK_RESIZE_LT,
|
||||||
|
CLICK_RESIZE_RT,
|
||||||
|
CLICK_RESIZE_LB,
|
||||||
|
CLICK_RESIZE_RB
|
||||||
|
} click_type;
|
||||||
|
|
||||||
class Decorator
|
class Decorator {
|
||||||
{
|
public:
|
||||||
public:
|
Decorator(BRect rect,
|
||||||
Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
int32 wlook,
|
||||||
virtual ~Decorator(void);
|
int32 wfeel,
|
||||||
|
int32 wflags);
|
||||||
|
virtual ~Decorator();
|
||||||
|
|
||||||
void SetColors(const ColorSet &cset);
|
void SetColors(const ColorSet &cset);
|
||||||
void SetDriver(DisplayDriver *driver);
|
void SetDriver(DisplayDriver *driver);
|
||||||
void SetFlags(int32 wflags);
|
void SetFlags(int32 wflags);
|
||||||
void SetFeel(int32 wfeel);
|
void SetFeel(int32 wfeel);
|
||||||
void SetFont(ServerFont *font);
|
void SetFont(ServerFont *font);
|
||||||
void SetLook(int32 wlook);
|
void SetLook(int32 wlook);
|
||||||
|
|
||||||
|
void SetClose(bool is_down);
|
||||||
|
void SetMinimize(bool is_down);
|
||||||
|
void SetZoom(bool is_down);
|
||||||
|
|
||||||
|
virtual void SetTitle(const char *string);
|
||||||
|
|
||||||
|
int32 GetLook() const;
|
||||||
|
int32 GetFeel() const;
|
||||||
|
int32 GetFlags() const;
|
||||||
|
|
||||||
|
const char* GetTitle() const;
|
||||||
|
|
||||||
|
// we need to know its border(frame). WinBorder's _frame rect
|
||||||
|
// must expand to include Decorator borders. Otherwise we can't
|
||||||
|
// draw the border. We also add GetTabRect because I feel we'll need it
|
||||||
|
BRect GetBorderRect() const;
|
||||||
|
BRect GetTabRect() const;
|
||||||
|
|
||||||
|
bool GetClose();
|
||||||
|
bool GetMinimize();
|
||||||
|
bool GetZoom();
|
||||||
|
|
||||||
|
virtual void GetSizeLimits(float* minWidth, float* minHeight,
|
||||||
|
float* maxWidth, float* maxHeight) const;
|
||||||
|
|
||||||
|
|
||||||
|
void SetFocus(bool is_active);
|
||||||
|
bool GetFocus()
|
||||||
|
{ return fIsFocused; };
|
||||||
|
ColorSet GetColors()
|
||||||
|
{ return (_colors) ? *_colors : ColorSet(); }
|
||||||
|
|
||||||
void SetClose(bool is_down);
|
virtual void GetFootprint(BRegion *region);
|
||||||
void SetMinimize(bool is_down);
|
virtual click_type Clicked(BPoint pt, int32 buttons,
|
||||||
void SetZoom(bool is_down);
|
int32 modifiers);
|
||||||
virtual void SetTitle(const char *string);
|
|
||||||
|
|
||||||
int32 GetLook(void);
|
virtual void MoveBy(float x, float y);
|
||||||
int32 GetFeel(void);
|
virtual void MoveBy(BPoint pt);
|
||||||
int32 GetFlags(void);
|
virtual BRect SlideTab(float dx, float dy = 0);
|
||||||
const char *GetTitle(void);
|
virtual void ResizeBy(float x, float y);
|
||||||
// we need to know its border(frame). WinBorder's _frame rect
|
virtual void ResizeBy(BPoint pt);
|
||||||
// must expand to include Decorator borders. Otherwise we can't
|
|
||||||
// draw the border. We also add GetTabRect because I feel we'll need it
|
|
||||||
BRect GetBorderRect(void);
|
|
||||||
BRect GetTabRect(void);
|
|
||||||
|
|
||||||
bool GetClose(void);
|
virtual void Draw(BRect r);
|
||||||
bool GetMinimize(void);
|
virtual void Draw();
|
||||||
bool GetZoom(void);
|
virtual void DrawClose();
|
||||||
|
virtual void DrawFrame();
|
||||||
|
virtual void DrawMinimize();
|
||||||
void SetFocus(bool is_active);
|
virtual void DrawTab();
|
||||||
bool GetFocus(void) { return _has_focus; };
|
virtual void DrawTitle();
|
||||||
ColorSet GetColors(void) { return (_colors)?*_colors:ColorSet(); }
|
virtual void DrawZoom();
|
||||||
|
|
||||||
virtual BRect SlideTab(float dx, float dy=0);
|
protected:
|
||||||
virtual void GetFootprint(BRegion *region);
|
int32 _ClipTitle(float width);
|
||||||
virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers);
|
|
||||||
|
|
||||||
virtual void MoveBy(float x, float y);
|
|
||||||
virtual void MoveBy(BPoint pt);
|
|
||||||
virtual void ResizeBy(float x, float y);
|
|
||||||
virtual void ResizeBy(BPoint pt);
|
|
||||||
|
|
||||||
virtual void Draw(BRect r);
|
|
||||||
virtual void Draw(void);
|
|
||||||
virtual void DrawClose(void);
|
|
||||||
virtual void DrawFrame(void);
|
|
||||||
virtual void DrawMinimize(void);
|
|
||||||
virtual void DrawTab(void);
|
|
||||||
virtual void DrawTitle(void);
|
|
||||||
virtual void DrawZoom(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int32 _ClipTitle(float width);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the number of characters in the title
|
\brief Returns the number of characters in the title
|
||||||
\return The title character count
|
\return The title character count
|
||||||
*/
|
*/
|
||||||
int32 _TitleWidth(void) { return (_title_string)?_title_string->CountChars():0; }
|
int32 _TitleWidth() const
|
||||||
|
{ return fTitle.CountChars(); }
|
||||||
virtual void _DrawClose(BRect r);
|
|
||||||
virtual void _DrawFrame(BRect r);
|
|
||||||
virtual void _DrawMinimize(BRect r);
|
|
||||||
virtual void _DrawTab(BRect r);
|
|
||||||
virtual void _DrawTitle(BRect r);
|
|
||||||
virtual void _DrawZoom(BRect r);
|
|
||||||
virtual void _SetFocus(void);
|
|
||||||
virtual void _DoLayout(void);
|
|
||||||
virtual void _SetColors(void);
|
|
||||||
|
|
||||||
ColorSet *_colors;
|
|
||||||
DisplayDriver *_driver;
|
|
||||||
DrawData _drawdata;
|
|
||||||
int32 _look, _feel, _flags;
|
|
||||||
BRect _zoomrect,_closerect,_minimizerect,_tabrect,_frame,
|
|
||||||
_resizerect,_borderrect;
|
|
||||||
|
|
||||||
private:
|
virtual void _DoLayout();
|
||||||
bool _close_state, _zoom_state, _minimize_state;
|
|
||||||
bool _has_focus;
|
virtual void _DrawFrame(BRect r);
|
||||||
BString *_title_string;
|
virtual void _DrawTab(BRect r);
|
||||||
|
|
||||||
|
virtual void _DrawClose(BRect r);
|
||||||
|
virtual void _DrawTitle(BRect r);
|
||||||
|
virtual void _DrawZoom(BRect r);
|
||||||
|
virtual void _DrawMinimize(BRect r);
|
||||||
|
|
||||||
|
virtual void _SetFocus();
|
||||||
|
virtual void _SetColors();
|
||||||
|
|
||||||
|
ColorSet* _colors;
|
||||||
|
DisplayDriver* _driver;
|
||||||
|
DrawData _drawdata;
|
||||||
|
|
||||||
|
int32 _look;
|
||||||
|
int32 _feel;
|
||||||
|
int32 _flags;
|
||||||
|
|
||||||
|
BRect _zoomrect;
|
||||||
|
BRect _closerect;
|
||||||
|
BRect _minimizerect;
|
||||||
|
BRect _tabrect;
|
||||||
|
BRect _frame;
|
||||||
|
BRect _resizerect;
|
||||||
|
BRect _borderrect;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fClosePressed;
|
||||||
|
bool fZoomPressed;
|
||||||
|
bool fMinimizePressed;
|
||||||
|
|
||||||
|
bool fIsFocused;
|
||||||
|
|
||||||
|
BString fTitle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// add-on stuff
|
||||||
typedef float get_version(void);
|
typedef float get_version(void);
|
||||||
typedef Decorator *create_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
typedef Decorator* create_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class FontServer
|
|||||||
public:
|
public:
|
||||||
FontServer(void);
|
FontServer(void);
|
||||||
~FontServer(void);
|
~FontServer(void);
|
||||||
void Lock(void);
|
bool Lock(void);
|
||||||
void Unlock(void);
|
void Unlock(void);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -108,10 +108,12 @@ class DrawData {
|
|||||||
inline const ServerFont& Font() const
|
inline const ServerFont& Font() const
|
||||||
{ return fFont; }
|
{ return fFont; }
|
||||||
|
|
||||||
|
// TODO: remove (is contained in SeverFont::Flags())
|
||||||
void SetFontAntiAliasing(bool antiAliasing);
|
void SetFontAntiAliasing(bool antiAliasing);
|
||||||
inline bool FontAntiAliasing() const
|
inline bool FontAntiAliasing() const
|
||||||
{ return fFontAntiAliasing; }
|
{ return fFontAntiAliasing; }
|
||||||
|
|
||||||
|
// TODO: remove (should be part of DisplayDriver::DrawString() as in BView)
|
||||||
void SetEscapementDelta(escapement_delta delta);
|
void SetEscapementDelta(escapement_delta delta);
|
||||||
inline escapement_delta EscapementDelta() const
|
inline escapement_delta EscapementDelta() const
|
||||||
{ return fEscapementDelta; }
|
{ return fEscapementDelta; }
|
||||||
|
|||||||
@@ -27,10 +27,14 @@
|
|||||||
#ifndef SERVERFONT_H_
|
#ifndef SERVERFONT_H_
|
||||||
#define SERVERFONT_H_
|
#define SERVERFONT_H_
|
||||||
|
|
||||||
#include <Rect.h>
|
|
||||||
#include <Font.h>
|
#include <Font.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
|
||||||
#include "FontFamily.h"
|
#include "FontFamily.h"
|
||||||
|
|
||||||
|
class BShape;
|
||||||
|
class BString;
|
||||||
|
|
||||||
class ServerFont {
|
class ServerFont {
|
||||||
public:
|
public:
|
||||||
ServerFont();
|
ServerFont();
|
||||||
@@ -48,6 +52,9 @@ class ServerFont {
|
|||||||
{ return fStyle ? B_OK : B_NO_INIT; }
|
{ return fStyle ? B_OK : B_NO_INIT; }
|
||||||
|
|
||||||
|
|
||||||
|
ServerFont &operator=(const ServerFont& font);
|
||||||
|
|
||||||
|
|
||||||
font_direction Direction() const
|
font_direction Direction() const
|
||||||
{ return fDirection; }
|
{ return fDirection; }
|
||||||
uint32 Encoding() const
|
uint32 Encoding() const
|
||||||
@@ -70,11 +77,24 @@ class ServerFont {
|
|||||||
{ return fStyle->GlyphCount(); }
|
{ return fStyle->GlyphCount(); }
|
||||||
int32 CountTuned();
|
int32 CountTuned();
|
||||||
|
|
||||||
|
|
||||||
font_file_format FileFormat();
|
font_file_format FileFormat();
|
||||||
|
|
||||||
|
const char* GetStyle() const;
|
||||||
|
const char* GetFamily() const;
|
||||||
|
const char* GetPath() const
|
||||||
|
{ return fStyle->GetPath(); }
|
||||||
|
|
||||||
status_t SetFamilyAndStyle(const uint16& familyID,
|
status_t SetFamilyAndStyle(uint16 familyID,
|
||||||
const uint16& styleID);
|
uint16 styleID);
|
||||||
status_t SetFamilyAndStyle(const uint32& fontID);
|
status_t SetFamilyAndStyle(uint32 fontID);
|
||||||
|
|
||||||
|
uint16 StyleID() const
|
||||||
|
{ return fStyle->GetID(); }
|
||||||
|
uint16 FamilyID() const
|
||||||
|
{ return fStyle->Family()->GetID(); }
|
||||||
|
uint32 GetFamilyAndStyle() const;
|
||||||
|
|
||||||
|
|
||||||
void SetDirection(const font_direction& dir)
|
void SetDirection(const font_direction& dir)
|
||||||
{ fDirection = dir; }
|
{ fDirection = dir; }
|
||||||
@@ -109,6 +129,7 @@ class ServerFont {
|
|||||||
{ return fStyle->GlyphCount(); }
|
{ return fStyle->GlyphCount(); }
|
||||||
uint16 CharMapCount() const
|
uint16 CharMapCount() const
|
||||||
{ return fStyle->CharMapCount(); }
|
{ return fStyle->CharMapCount(); }
|
||||||
|
|
||||||
BShape** GetGlyphShapes(const char charArray[],
|
BShape** GetGlyphShapes(const char charArray[],
|
||||||
int32 numChars) const;
|
int32 numChars) const;
|
||||||
|
|
||||||
@@ -125,24 +146,17 @@ class ServerFont {
|
|||||||
FT_Face GetFTFace() const
|
FT_Face GetFTFace() const
|
||||||
{ return fStyle->GetFTFace(); };
|
{ return fStyle->GetFTFace(); };
|
||||||
|
|
||||||
const char* GetStyle() const;
|
|
||||||
const char* GetFamily() const;
|
|
||||||
const char* GetPath() const
|
|
||||||
{ return fStyle->GetPath(); }
|
|
||||||
|
|
||||||
uint16 StyleID() const
|
|
||||||
{ return fStyle->GetID(); }
|
|
||||||
uint16 FamilyID() const
|
|
||||||
{ return fStyle->Family()->GetID(); }
|
|
||||||
uint32 GetFamilyAndStyle() const;
|
|
||||||
|
|
||||||
BRect BoundingBox();
|
BRect BoundingBox();
|
||||||
void Height(font_height* fh);
|
void Height(font_height* fh) const;
|
||||||
|
|
||||||
|
void TruncateString(BString* inOut,
|
||||||
|
uint32 mode,
|
||||||
|
float width) const;
|
||||||
|
|
||||||
ServerFont &operator=(const ServerFont& font);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class FontStyle;
|
friend class FontStyle;
|
||||||
|
void _SetStyle(FontStyle* style);
|
||||||
|
|
||||||
|
|
||||||
FontStyle* fStyle;
|
FontStyle* fStyle;
|
||||||
edge_info fEdges;
|
edge_info fEdges;
|
||||||
@@ -152,8 +166,8 @@ protected:
|
|||||||
BRect fBounds;
|
BRect fBounds;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
uint32 fSpacing;
|
uint32 fSpacing;
|
||||||
uint16 fFace;
|
|
||||||
font_direction fDirection;
|
font_direction fDirection;
|
||||||
|
uint16 fFace;
|
||||||
uint32 fEncoding;
|
uint32 fEncoding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+42
-87
@@ -35,6 +35,7 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#include <moreUTF8.h>
|
#include <moreUTF8.h>
|
||||||
|
#include <truncate_string.h>
|
||||||
|
|
||||||
#include <Font.h>
|
#include <Font.h>
|
||||||
|
|
||||||
@@ -765,115 +766,69 @@ BFont::GetTunedInfo(int32 index, tuned_font_info *info) const
|
|||||||
link.Read<tuned_font_info>(info);
|
link.Read<tuned_font_info>(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TruncateString
|
||||||
void
|
void
|
||||||
BFont::TruncateString(BString *inOut, uint32 mode, float width) const
|
BFont::TruncateString(BString *inOut, uint32 mode, float width) const
|
||||||
{
|
{
|
||||||
if(!inOut)
|
// NOTE: Careful, we cannot directly use "inOut->String()" as result
|
||||||
return;
|
// array, because the string length increases by 3 bytes in the worst case scenario.
|
||||||
|
const char* array[1];
|
||||||
if(width<=0)
|
array[0] = inOut->String();
|
||||||
{
|
GetTruncatedStrings(array, 1, mode, width, inOut);
|
||||||
*inOut="";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 code;
|
|
||||||
BPrivate::BAppServerLink link;
|
|
||||||
|
|
||||||
link.StartMessage(AS_GET_TRUNCATED_STRINGS);
|
|
||||||
|
|
||||||
link.Attach<uint32>(mode);
|
|
||||||
link.Attach<float>(width);
|
|
||||||
link.Attach<int32>(1);
|
|
||||||
link.AttachString(inOut->String());
|
|
||||||
link.FlushWithReply(&code);
|
|
||||||
|
|
||||||
if(code!=SERVER_TRUE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char *string;
|
|
||||||
link.ReadString(&string);
|
|
||||||
*inOut=string;
|
|
||||||
free(string);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTruncatedStrings
|
||||||
void
|
void
|
||||||
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
||||||
uint32 mode, float width, BString resultArray[]) const
|
uint32 mode, float width, BString resultArray[]) const
|
||||||
{
|
{
|
||||||
if(!stringArray || numStrings<1 || !resultArray)
|
if (stringArray && resultArray && numStrings > 0) {
|
||||||
return;
|
// allocate storage, see BeBook for "+ 3"
|
||||||
|
char** truncatedStrings = new char*[numStrings];
|
||||||
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
|
truncatedStrings[i] = new char[strlen(stringArray[i]) + 3];
|
||||||
|
}
|
||||||
|
|
||||||
int32 code;
|
GetTruncatedStrings(stringArray, numStrings, mode, width, truncatedStrings);
|
||||||
BPrivate::BAppServerLink link;
|
|
||||||
|
|
||||||
link.StartMessage(AS_GET_TRUNCATED_STRINGS);
|
// copy the strings into the BString array and free each one
|
||||||
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
link.Attach<uint32>(mode);
|
resultArray[i].SetTo(truncatedStrings[i]);
|
||||||
link.Attach<float>(width);
|
delete[] truncatedStrings[i];
|
||||||
link.Attach<int32>(numStrings);
|
}
|
||||||
|
delete[] truncatedStrings;
|
||||||
for(int32 i=0; i<numStrings; i++)
|
|
||||||
link.AttachString(stringArray[i]);
|
|
||||||
|
|
||||||
link.FlushWithReply(&code);
|
|
||||||
|
|
||||||
if(code!=SERVER_TRUE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(int32 i=0; i<numStrings; i++)
|
|
||||||
{
|
|
||||||
char *string;
|
|
||||||
link.ReadString(&string);
|
|
||||||
resultArray[i].SetTo(string);
|
|
||||||
free(string);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTruncatedStrings
|
||||||
void
|
void
|
||||||
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
||||||
uint32 mode, float width, char *resultArray[]) const
|
uint32 mode, float width, char *resultArray[]) const
|
||||||
{
|
{
|
||||||
if(!stringArray || numStrings<1 || !resultArray)
|
if (stringArray && numStrings > 0) {
|
||||||
return;
|
// the width of the "…" glyph
|
||||||
|
float ellipsisWidth = StringWidth(B_UTF8_ELLIPSIS);
|
||||||
int32 code;
|
for (int32 i = 0; i < numStrings; i++) {
|
||||||
BPrivate::BAppServerLink link;
|
int32 length = strlen(stringArray[i]);
|
||||||
|
// count the individual glyphs
|
||||||
link.StartMessage(AS_GET_TRUNCATED_STRINGS);
|
int32 numChars = UTF8CountChars(stringArray[i], length);
|
||||||
|
// get the escapement of each glyph in font units
|
||||||
link.Attach<uint32>(mode);
|
float* escapementArray = new float[numChars];
|
||||||
link.Attach<float>(width);
|
GetEscapements(stringArray[i], numChars, NULL, escapementArray);
|
||||||
link.Attach<int32>(numStrings);
|
|
||||||
|
truncate_string(stringArray[i], mode, width, resultArray[i],
|
||||||
for(int32 i=0; i<numStrings; i++)
|
escapementArray, fSize, ellipsisWidth, length, numChars);
|
||||||
link.AttachString(stringArray[i]);
|
|
||||||
|
delete[] escapementArray;
|
||||||
link.FlushWithReply(&code);
|
}
|
||||||
|
|
||||||
if(code!=SERVER_TRUE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// TODO: Look into a possible BPortLink::ReadIntoString() method to speed things
|
|
||||||
// like this up, along with the other string truncation functions
|
|
||||||
for(int32 i=0; i<numStrings; i++)
|
|
||||||
{
|
|
||||||
char *string;
|
|
||||||
link.ReadString(&string);
|
|
||||||
strcpy(resultArray[i],string);
|
|
||||||
free(string);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringWidth
|
||||||
float
|
float
|
||||||
BFont::StringWidth(const char *string) const
|
BFont::StringWidth(const char *string) const
|
||||||
{
|
{
|
||||||
int32 length=strlen(string);
|
int32 length = strlen(string);
|
||||||
return StringWidth(string, length);
|
return StringWidth(string, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,7 +836,7 @@ BFont::StringWidth(const char *string) const
|
|||||||
float
|
float
|
||||||
BFont::StringWidth(const char *string, int32 length) const
|
BFont::StringWidth(const char *string, int32 length) const
|
||||||
{
|
{
|
||||||
if(!string || length<1)
|
if (!string || length < 1)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
int32 code;
|
int32 code;
|
||||||
@@ -896,7 +851,7 @@ BFont::StringWidth(const char *string, int32 length) const
|
|||||||
link.Attach<uint8>(fSpacing);
|
link.Attach<uint8>(fSpacing);
|
||||||
link.FlushWithReply(&code);
|
link.FlushWithReply(&code);
|
||||||
|
|
||||||
if(code!=SERVER_TRUE)
|
if (code != SERVER_TRUE)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
float width;
|
float width;
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
// TODO: remove this header
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
// Private definitions not placed in public headers
|
// Private definitions not placed in public headers
|
||||||
extern "C" void _init_global_fonts();
|
extern "C" void _init_global_fonts();
|
||||||
@@ -45,6 +47,10 @@ extern "C" status_t _fini_interface_kit_();
|
|||||||
#include <ServerProtocol.h>
|
#include <ServerProtocol.h>
|
||||||
#include <WidthBuffer.h>
|
#include <WidthBuffer.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <Font.h>
|
||||||
|
#include "moreUTF8.h"
|
||||||
|
#include "truncate_string.h"
|
||||||
|
|
||||||
using namespace BPrivate;
|
using namespace BPrivate;
|
||||||
|
|
||||||
@@ -729,5 +735,172 @@ do_minimize_team(BRect zoomRect, team_id team, bool zoom)
|
|||||||
// ToDo: implement me, needed for Deskbar!
|
// ToDo: implement me, needed for Deskbar!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy_from_start
|
||||||
|
static char*
|
||||||
|
copy_from_start(const char* src, char* dst, uint32 numChars,
|
||||||
|
const float* escapementArray, float width, float ellipsisWidth, float size)
|
||||||
|
{
|
||||||
|
//printf("copy_from_start: %.1f\n", width);
|
||||||
|
float currentWidth = 0.0;
|
||||||
|
for (uint32 c = 0; c < numChars; c++) {
|
||||||
|
//printf("forward: %c (%ld) (%.1f + %.1f = %.1f)\n", *src, c, currentWidth, escapementArray[c] * size, currentWidth + escapementArray[c] * size);
|
||||||
|
currentWidth += escapementArray[c] * size;
|
||||||
|
if (currentWidth > width) {
|
||||||
|
//*dst = *src;
|
||||||
|
// ups, we definitely don't fit. go back until the ellipsis fits
|
||||||
|
currentWidth += ellipsisWidth;
|
||||||
|
for (int32 c2 = c; c2 >= 0; c2--) {
|
||||||
|
//printf(" backward: %c (%ld) (%.1f - %.1f = %.1f)\n", *dst, c2, currentWidth, escapementArray[c2] * size, currentWidth - escapementArray[c2] * size);
|
||||||
|
currentWidth -= escapementArray[c2] * size;
|
||||||
|
do {
|
||||||
|
dst--;
|
||||||
|
} while (IsInsideGlyph(*dst));
|
||||||
|
// see if we went back enough
|
||||||
|
if (currentWidth <= width)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// dst needs to point behind the last glyph we want to use
|
||||||
|
dst++;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// copy one glyph
|
||||||
|
do {
|
||||||
|
*dst++ = *src++;
|
||||||
|
} while (IsInsideGlyph(*src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy_from_end
|
||||||
|
static char*
|
||||||
|
copy_from_end(const char* src, char* dst, uint32 numChars, uint32 length,
|
||||||
|
const float* escapementArray, float width, float ellipsisWidth, float size)
|
||||||
|
{
|
||||||
|
const char* originalStart = src;
|
||||||
|
src += length - 1;
|
||||||
|
float currentWidth = 0.0;
|
||||||
|
for (int32 c = numChars - 1; c > 0; c--) {
|
||||||
|
currentWidth += escapementArray[c] * size;
|
||||||
|
if (currentWidth > width) {
|
||||||
|
// ups, we definitely don't fit. go back until the ellipsis fits
|
||||||
|
currentWidth += ellipsisWidth;
|
||||||
|
// go forward again until ellipsis fits (already beyond the target)
|
||||||
|
for (int32 c2 = c; c2 < numChars; c2++) {
|
||||||
|
//printf(" backward: %c (%ld) (%.1f - %.1f = %.1f)\n", *dst, c2, currentWidth, escapementArray[c2] * size, currentWidth - escapementArray[c2] * size);
|
||||||
|
currentWidth -= escapementArray[c2] * size;
|
||||||
|
do {
|
||||||
|
src++;
|
||||||
|
} while (IsInsideGlyph(*src));
|
||||||
|
// see if we went back enough
|
||||||
|
if (currentWidth <= width)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// go back one glyph
|
||||||
|
do {
|
||||||
|
src--;
|
||||||
|
} while (IsInsideGlyph(*src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy from the end of the string
|
||||||
|
uint32 bytesToCopy = originalStart + length - src;
|
||||||
|
memcpy(dst, src, bytesToCopy);
|
||||||
|
dst += bytesToCopy;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
write_ellipsis(char* dst)
|
||||||
|
{
|
||||||
|
strcpy(dst, B_UTF8_ELLIPSIS);
|
||||||
|
//strcpy(dst, "...");
|
||||||
|
return dst + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// truncated_string
|
||||||
|
void
|
||||||
|
truncate_string(const char* string,
|
||||||
|
uint32 mode, float width, char* result,
|
||||||
|
const float* escapementArray, float fontSize,
|
||||||
|
float ellipsisWidth, int32 length, int32 numChars)
|
||||||
|
{
|
||||||
|
if (string) {
|
||||||
|
// skip calculation if we don't even have enough room for that
|
||||||
|
if (width >= ellipsisWidth) {
|
||||||
|
|
||||||
|
// iterate over glyphs and copy source into result string
|
||||||
|
// one glyph at a time as long as we have room for the "…" yet
|
||||||
|
char* dst = result;
|
||||||
|
const char* src = string;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case B_TRUNCATE_BEGINNING: {
|
||||||
|
|
||||||
|
dst = copy_from_end(src, dst, numChars, length,
|
||||||
|
escapementArray, width, ellipsisWidth, fontSize);
|
||||||
|
// "dst" points to the position behind the last glyph that
|
||||||
|
// was copied.
|
||||||
|
int32 dist = dst - result;
|
||||||
|
// we didn't terminate yet
|
||||||
|
*dst = 0;
|
||||||
|
if (dist < length) {
|
||||||
|
// TODO: Is there a smarter way?
|
||||||
|
char* temp = new char[dist + 4];
|
||||||
|
char* t = temp;
|
||||||
|
// append "…"
|
||||||
|
t = write_ellipsis(t);
|
||||||
|
// shuffle arround strings so that "…" is prepended
|
||||||
|
strcpy(t, result);
|
||||||
|
strcpy(result, temp);
|
||||||
|
delete[] temp;
|
||||||
|
/* char t = result[3];
|
||||||
|
memmove(&result[3], result, dist + 1);
|
||||||
|
write_ellipsis(result);
|
||||||
|
result[3] = t;*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_TRUNCATE_END:
|
||||||
|
|
||||||
|
dst = copy_from_start(src, dst, numChars,
|
||||||
|
escapementArray, width, ellipsisWidth, fontSize);
|
||||||
|
// "dst" points to the position behind the last glyph that
|
||||||
|
// was copied.
|
||||||
|
if (dst - result < length) {
|
||||||
|
// append "…" and terminate with 0
|
||||||
|
write_ellipsis(dst);
|
||||||
|
} else {
|
||||||
|
*dst = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_TRUNCATE_SMART:
|
||||||
|
// TODO: implement, though it was never implemented on R5
|
||||||
|
// FALL THROUGH (at least do something)
|
||||||
|
case B_TRUNCATE_MIDDLE:
|
||||||
|
|
||||||
|
float halfWidth = width / 2.0;
|
||||||
|
|
||||||
|
dst = copy_from_start(src, dst, numChars,
|
||||||
|
escapementArray, halfWidth, ellipsisWidth, fontSize);
|
||||||
|
// insert "…"
|
||||||
|
dst = write_ellipsis(dst);
|
||||||
|
|
||||||
|
dst = copy_from_end(src, dst, numChars, length,
|
||||||
|
escapementArray, halfWidth, 0.0, fontSize);
|
||||||
|
// terminate
|
||||||
|
*dst = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we don't have room for a single glyph
|
||||||
|
strcpy(result, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // !COMPILE_FOR_R5
|
#endif // !COMPILE_FOR_R5
|
||||||
|
|||||||
@@ -1026,27 +1026,29 @@ void
|
|||||||
BWindow::SetSizeLimits(float minWidth, float maxWidth,
|
BWindow::SetSizeLimits(float minWidth, float maxWidth,
|
||||||
float minHeight, float maxHeight)
|
float minHeight, float maxHeight)
|
||||||
{
|
{
|
||||||
int32 rCode;
|
if (minWidth > maxWidth || minHeight > maxHeight)
|
||||||
|
|
||||||
if (minWidth > maxWidth
|
|
||||||
|| minHeight > maxHeight)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Lock();
|
if (Lock()) {
|
||||||
fLink->StartMessage(AS_SET_SIZE_LIMITS);
|
fLink->StartMessage(AS_SET_SIZE_LIMITS);
|
||||||
fLink->Attach<float>(fMinWindWidth);
|
fLink->Attach<float>(minWidth);
|
||||||
fLink->Attach<float>(fMaxWindWidth);
|
fLink->Attach<float>(maxWidth);
|
||||||
fLink->Attach<float>(fMinWindHeight);
|
fLink->Attach<float>(minHeight);
|
||||||
fLink->Attach<float>(fMaxWindHeight);
|
fLink->Attach<float>(maxHeight);
|
||||||
fLink->Flush();
|
fLink->Flush();
|
||||||
fLink->GetNextReply(&rCode);
|
|
||||||
Unlock();
|
|
||||||
|
|
||||||
if (rCode == SERVER_TRUE) {
|
int32 rCode;
|
||||||
fMinWindHeight = minHeight;
|
fLink->GetNextReply(&rCode);
|
||||||
fMinWindWidth = minWidth;
|
|
||||||
fMaxWindHeight = maxHeight;
|
if (rCode == SERVER_TRUE) {
|
||||||
fMaxWindWidth = maxWidth;
|
// read the values that were really enforced on
|
||||||
|
// the server side
|
||||||
|
fLink->Read<float>(&fMinWindWidth);
|
||||||
|
fLink->Read<float>(&fMaxWindWidth);
|
||||||
|
fLink->Read<float>(&fMinWindHeight);
|
||||||
|
fLink->Read<float>(&fMaxWindHeight);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,16 +1057,18 @@ void
|
|||||||
BWindow::GetSizeLimits(float *minWidth, float *maxWidth,
|
BWindow::GetSizeLimits(float *minWidth, float *maxWidth,
|
||||||
float *minHeight, float *maxHeight)
|
float *minHeight, float *maxHeight)
|
||||||
{
|
{
|
||||||
*minHeight = fMinWindHeight;
|
// TODO: What about locking?!?
|
||||||
*minWidth = fMinWindWidth;
|
*minHeight = fMinWindHeight;
|
||||||
*maxHeight = fMaxWindHeight;
|
*minWidth = fMinWindWidth;
|
||||||
*maxWidth = fMaxWindWidth;
|
*maxHeight = fMaxWindHeight;
|
||||||
|
*maxWidth = fMaxWindWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BWindow::SetZoomLimits(float maxWidth, float maxHeight)
|
BWindow::SetZoomLimits(float maxWidth, float maxHeight)
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
if (maxWidth > fMaxWindWidth)
|
if (maxWidth > fMaxWindWidth)
|
||||||
maxWidth = fMaxWindWidth;
|
maxWidth = fMaxWindWidth;
|
||||||
else
|
else
|
||||||
@@ -1090,6 +1094,8 @@ BWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
|
|||||||
void
|
void
|
||||||
BWindow::Zoom()
|
BWindow::Zoom()
|
||||||
{
|
{
|
||||||
|
// TODO: broken.
|
||||||
|
// TODO: What about locking?!?
|
||||||
float minWidth, minHeight;
|
float minWidth, minHeight;
|
||||||
BScreen screen;
|
BScreen screen;
|
||||||
|
|
||||||
@@ -1142,6 +1148,7 @@ BWindow::ScreenChanged(BRect screen_size, color_space depth)
|
|||||||
void
|
void
|
||||||
BWindow::SetPulseRate(bigtime_t rate)
|
BWindow::SetPulseRate(bigtime_t rate)
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
if (rate < 0)
|
if (rate < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1170,6 +1177,7 @@ BWindow::SetPulseRate(bigtime_t rate)
|
|||||||
bigtime_t
|
bigtime_t
|
||||||
BWindow::PulseRate() const
|
BWindow::PulseRate() const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
return fPulseRate;
|
return fPulseRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1192,6 +1200,7 @@ void
|
|||||||
BWindow::AddShortcut(uint32 key, uint32 modifiers, BMessage *msg, BHandler *target)
|
BWindow::AddShortcut(uint32 key, uint32 modifiers, BMessage *msg, BHandler *target)
|
||||||
{
|
{
|
||||||
// NOTE: I'm not sure if it is OK to use 'key'
|
// NOTE: I'm not sure if it is OK to use 'key'
|
||||||
|
// TODO: What about locking?!?
|
||||||
|
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -1224,6 +1233,7 @@ BWindow::AddShortcut(uint32 key, uint32 modifiers, BMessage *msg, BHandler *targ
|
|||||||
void
|
void
|
||||||
BWindow::RemoveShortcut(uint32 key, uint32 modifiers)
|
BWindow::RemoveShortcut(uint32 key, uint32 modifiers)
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
int32 index = findShortcut(key, modifiers | B_COMMAND_KEY);
|
int32 index = findShortcut(key, modifiers | B_COMMAND_KEY);
|
||||||
if (index >=0) {
|
if (index >=0) {
|
||||||
_BCmdKey *cmdKey = (_BCmdKey *)accelList.ItemAt(index);
|
_BCmdKey *cmdKey = (_BCmdKey *)accelList.ItemAt(index);
|
||||||
@@ -1239,6 +1249,7 @@ BWindow::RemoveShortcut(uint32 key, uint32 modifiers)
|
|||||||
BButton *
|
BButton *
|
||||||
BWindow::DefaultButton() const
|
BWindow::DefaultButton() const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
return fDefaultButton;
|
return fDefaultButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1246,6 +1257,7 @@ BWindow::DefaultButton() const
|
|||||||
void
|
void
|
||||||
BWindow::SetDefaultButton(BButton *button)
|
BWindow::SetDefaultButton(BButton *button)
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
if (fDefaultButton == button)
|
if (fDefaultButton == button)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1268,6 +1280,7 @@ BWindow::SetDefaultButton(BButton *button)
|
|||||||
bool
|
bool
|
||||||
BWindow::NeedsUpdate() const
|
BWindow::NeedsUpdate() const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
int32 rCode;
|
int32 rCode;
|
||||||
|
|
||||||
const_cast<BWindow *>(this)->Lock();
|
const_cast<BWindow *>(this)->Lock();
|
||||||
@@ -1283,6 +1296,7 @@ BWindow::NeedsUpdate() const
|
|||||||
void
|
void
|
||||||
BWindow::UpdateIfNeeded()
|
BWindow::UpdateIfNeeded()
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
// works only from this thread
|
// works only from this thread
|
||||||
if (find_thread(NULL) != Thread())
|
if (find_thread(NULL) != Thread())
|
||||||
return;
|
return;
|
||||||
@@ -1317,6 +1331,7 @@ BWindow::UpdateIfNeeded()
|
|||||||
BView *
|
BView *
|
||||||
BWindow::FindView(const char *viewName) const
|
BWindow::FindView(const char *viewName) const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
return findView(top_view, viewName);
|
return findView(top_view, viewName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1324,12 +1339,14 @@ BWindow::FindView(const char *viewName) const
|
|||||||
BView *
|
BView *
|
||||||
BWindow::FindView(BPoint point) const
|
BWindow::FindView(BPoint point) const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
return findView(top_view, point);
|
return findView(top_view, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BView *BWindow::CurrentFocus() const
|
BView *BWindow::CurrentFocus() const
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
return fFocus;
|
return fFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1337,6 +1354,7 @@ BView *BWindow::CurrentFocus() const
|
|||||||
void
|
void
|
||||||
BWindow::Activate(bool active)
|
BWindow::Activate(bool active)
|
||||||
{
|
{
|
||||||
|
// TODO: What about locking?!?
|
||||||
if (IsHidden())
|
if (IsHidden())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
+418
-363
@@ -1,5 +1,5 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Copyright (c) 2001-2002, Haiku, Inc.
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
//
|
//
|
||||||
// File Name: Decorator.cpp
|
// File Name: Decorator.cpp
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Base class for window decorators
|
// Description: Base class for window decorators
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -41,36 +42,28 @@
|
|||||||
object.
|
object.
|
||||||
*/
|
*/
|
||||||
Decorator::Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
|
Decorator::Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
|
||||||
|
: _colors(new ColorSet()),
|
||||||
|
_driver(NULL),
|
||||||
|
_drawdata(),
|
||||||
|
|
||||||
|
_look(wlook),
|
||||||
|
_feel(wfeel),
|
||||||
|
_flags(wflags),
|
||||||
|
|
||||||
|
_zoomrect(),
|
||||||
|
_closerect(),
|
||||||
|
_minimizerect(),
|
||||||
|
_tabrect(),
|
||||||
|
_frame(rect),
|
||||||
|
_resizerect(),
|
||||||
|
_borderrect(),
|
||||||
|
|
||||||
|
fClosePressed(false),
|
||||||
|
fZoomPressed(false),
|
||||||
|
fMinimizePressed(false),
|
||||||
|
fIsFocused(false),
|
||||||
|
fTitle("")
|
||||||
{
|
{
|
||||||
_close_state=false;
|
|
||||||
_minimize_state=false;
|
|
||||||
_zoom_state=false;
|
|
||||||
_has_focus=false;
|
|
||||||
_title_string=new BString;
|
|
||||||
_driver=NULL;
|
|
||||||
|
|
||||||
/// xxx.Set(0,0,1,1) produces a rectangle 2 pixels wide, that
|
|
||||||
// WILL be drawn on screen. We so not want that... so...
|
|
||||||
// [ A BRect when instantiated is made invalid, so, no need for: ]
|
|
||||||
/*
|
|
||||||
_closerect.Set( 0, 0, -1, -1);
|
|
||||||
_zoomrect.Set( 0, 0, -1, -1);
|
|
||||||
_minimizerect.Set( 0, 0, -1, -1);
|
|
||||||
_resizerect.Set( 0, 0, -1, -1);
|
|
||||||
*/
|
|
||||||
_frame=rect;
|
|
||||||
|
|
||||||
// rect rectangle MUST remain intact - it is top_view's area
|
|
||||||
// Decorator drawing MUST be done arround that area
|
|
||||||
//_tabrect.Set(rect.left,rect.top,rect.right, rect.top+((rect.bottom-rect.top)/4));
|
|
||||||
// [ A BRect when instantiated is made invalid, so, no need for: ]
|
|
||||||
// _tabrect.Set( 0, 0, -1, -1 );
|
|
||||||
|
|
||||||
_look=wlook;
|
|
||||||
_feel=wfeel;
|
|
||||||
_flags=wflags;
|
|
||||||
|
|
||||||
_colors=new ColorSet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -78,22 +71,17 @@ Decorator::Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
|
|||||||
|
|
||||||
Frees the color set and the title string
|
Frees the color set and the title string
|
||||||
*/
|
*/
|
||||||
Decorator::~Decorator(void)
|
Decorator::~Decorator()
|
||||||
{
|
{
|
||||||
if(_colors!=NULL)
|
delete _colors;
|
||||||
{
|
|
||||||
delete _colors;
|
|
||||||
_colors=NULL;
|
|
||||||
}
|
|
||||||
if(_title_string)
|
|
||||||
delete _title_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Updates the decorator's color set
|
\brief Updates the decorator's color set
|
||||||
\param cset The color set to update from
|
\param cset The color set to update from
|
||||||
*/
|
*/
|
||||||
void Decorator::SetColors(const ColorSet &cset)
|
void
|
||||||
|
Decorator::SetColors(const ColorSet &cset)
|
||||||
{
|
{
|
||||||
_colors->SetColors(cset);
|
_colors->SetColors(cset);
|
||||||
_SetColors();
|
_SetColors();
|
||||||
@@ -103,48 +91,15 @@ void Decorator::SetColors(const ColorSet &cset)
|
|||||||
\brief Assigns a display driver to the decorator
|
\brief Assigns a display driver to the decorator
|
||||||
\param driver A valid DisplayDriver object
|
\param driver A valid DisplayDriver object
|
||||||
*/
|
*/
|
||||||
void Decorator::SetDriver(DisplayDriver *driver)
|
void
|
||||||
|
Decorator::SetDriver(DisplayDriver *driver)
|
||||||
{
|
{
|
||||||
|
_driver = driver;
|
||||||
// lots of subclasses will depend on the driver for text support, so call
|
// lots of subclasses will depend on the driver for text support, so call
|
||||||
// _DoLayout() after this
|
// _DoLayout() after we have it
|
||||||
_driver=driver;
|
if (_driver) {
|
||||||
_DoLayout();
|
_DoLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Sets the close button's value.
|
|
||||||
\param is_down Whether the button is down or not
|
|
||||||
|
|
||||||
Note that this does not update the button's look - it just updates the
|
|
||||||
internal button value
|
|
||||||
*/
|
|
||||||
void Decorator::SetClose(bool is_down)
|
|
||||||
{
|
|
||||||
_close_state=is_down;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Sets the minimize button's value.
|
|
||||||
\param is_down Whether the button is down or not
|
|
||||||
|
|
||||||
Note that this does not update the button's look - it just updates the
|
|
||||||
internal button value
|
|
||||||
*/
|
|
||||||
void Decorator::SetMinimize(bool is_down)
|
|
||||||
{
|
|
||||||
_zoom_state=is_down;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Sets the zoom button's value.
|
|
||||||
\param is_down Whether the button is down or not
|
|
||||||
|
|
||||||
Note that this does not update the button's look - it just updates the
|
|
||||||
internal button value
|
|
||||||
*/
|
|
||||||
void Decorator::SetZoom(bool is_down)
|
|
||||||
{
|
|
||||||
_minimize_state=is_down;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -154,9 +109,10 @@ void Decorator::SetZoom(bool is_down)
|
|||||||
While this call will not update the screen, it will affect how future
|
While this call will not update the screen, it will affect how future
|
||||||
updates work and immediately affects input handling.
|
updates work and immediately affects input handling.
|
||||||
*/
|
*/
|
||||||
void Decorator::SetFlags(int32 wflags)
|
void
|
||||||
|
Decorator::SetFlags(int32 wflags)
|
||||||
{
|
{
|
||||||
_flags=wflags;
|
_flags = wflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -166,21 +122,22 @@ void Decorator::SetFlags(int32 wflags)
|
|||||||
While this call will not update the screen, it will affect how future
|
While this call will not update the screen, it will affect how future
|
||||||
updates work and immediately affects input handling.
|
updates work and immediately affects input handling.
|
||||||
*/
|
*/
|
||||||
void Decorator::SetFeel(int32 wfeel)
|
void
|
||||||
|
Decorator::SetFeel(int32 wfeel)
|
||||||
{
|
{
|
||||||
_feel=wfeel;
|
_feel = wfeel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
\brief Sets the decorator's font
|
\brief Sets the decorator's font
|
||||||
\param font The new font object to copy from
|
\param font The new font object to copy from
|
||||||
*/
|
*/
|
||||||
void Decorator::SetFont(ServerFont *font)
|
void
|
||||||
|
Decorator::SetFont(ServerFont *font)
|
||||||
{
|
{
|
||||||
if(!font)
|
if (font) {
|
||||||
return;
|
_drawdata.SetFont(*font);
|
||||||
|
}
|
||||||
_drawdata.SetFont(*font);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -190,43 +147,79 @@ void Decorator::SetFont(ServerFont *font)
|
|||||||
While this call will not update the screen, it will affect how future
|
While this call will not update the screen, it will affect how future
|
||||||
updates work and immediately affects input handling.
|
updates work and immediately affects input handling.
|
||||||
*/
|
*/
|
||||||
void Decorator::SetLook(int32 wlook)
|
void
|
||||||
|
Decorator::SetLook(int32 wlook)
|
||||||
{
|
{
|
||||||
_look=wlook;
|
_look = wlook;
|
||||||
|
// TODO: relayout and redraw, no?
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the value of the close button
|
\brief Sets the close button's value.
|
||||||
\return true if down, false if up
|
\param is_down Whether the button is down or not
|
||||||
|
|
||||||
|
Note that this does not update the button's look - it just updates the
|
||||||
|
internal button value
|
||||||
*/
|
*/
|
||||||
bool Decorator::GetClose(void)
|
void
|
||||||
|
Decorator::SetClose(bool is_down)
|
||||||
{
|
{
|
||||||
return _close_state;
|
if (is_down != fClosePressed) {
|
||||||
|
fClosePressed = is_down;
|
||||||
|
DrawClose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the value of the minimize button
|
\brief Sets the minimize button's value.
|
||||||
\return true if down, false if up
|
\param is_down Whether the button is down or not
|
||||||
|
|
||||||
|
Note that this does not update the button's look - it just updates the
|
||||||
|
internal button value
|
||||||
*/
|
*/
|
||||||
bool Decorator::GetMinimize(void)
|
void
|
||||||
|
Decorator::SetMinimize(bool is_down)
|
||||||
{
|
{
|
||||||
return _minimize_state;
|
if (is_down != fMinimizePressed) {
|
||||||
|
fMinimizePressed = is_down;
|
||||||
|
DrawMinimize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the value of the zoom button
|
\brief Sets the zoom button's value.
|
||||||
\return true if down, false if up
|
\param is_down Whether the button is down or not
|
||||||
|
|
||||||
|
Note that this does not update the button's look - it just updates the
|
||||||
|
internal button value
|
||||||
*/
|
*/
|
||||||
bool Decorator::GetZoom(void)
|
void
|
||||||
|
Decorator::SetZoom(bool is_down)
|
||||||
{
|
{
|
||||||
return _zoom_state;
|
if (is_down != fZoomPressed) {
|
||||||
|
fZoomPressed = is_down;
|
||||||
|
DrawZoom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Updates the value of the decorator title
|
||||||
|
\param string New title value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::SetTitle(const char *string)
|
||||||
|
{
|
||||||
|
fTitle.SetTo(string);
|
||||||
|
_DoLayout();
|
||||||
|
// TODO: redraw?
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the decorator's window look
|
\brief Returns the decorator's window look
|
||||||
\return the decorator's window look
|
\return the decorator's window look
|
||||||
*/
|
*/
|
||||||
int32 Decorator::GetLook(void)
|
int32
|
||||||
|
Decorator::GetLook() const
|
||||||
{
|
{
|
||||||
return _look;
|
return _look;
|
||||||
}
|
}
|
||||||
@@ -235,7 +228,8 @@ int32 Decorator::GetLook(void)
|
|||||||
\brief Returns the decorator's window feel
|
\brief Returns the decorator's window feel
|
||||||
\return the decorator's window feel
|
\return the decorator's window feel
|
||||||
*/
|
*/
|
||||||
int32 Decorator::GetFeel(void)
|
int32
|
||||||
|
Decorator::GetFeel() const
|
||||||
{
|
{
|
||||||
return _feel;
|
return _feel;
|
||||||
}
|
}
|
||||||
@@ -244,28 +238,20 @@ int32 Decorator::GetFeel(void)
|
|||||||
\brief Returns the decorator's window flags
|
\brief Returns the decorator's window flags
|
||||||
\return the decorator's window flags
|
\return the decorator's window flags
|
||||||
*/
|
*/
|
||||||
int32 Decorator::GetFlags(void)
|
int32
|
||||||
|
Decorator::GetFlags() const
|
||||||
{
|
{
|
||||||
return _flags;
|
return _flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Updates the value of the decorator title
|
|
||||||
\param string New title value
|
|
||||||
*/
|
|
||||||
void Decorator::SetTitle(const char *string)
|
|
||||||
{
|
|
||||||
_title_string->SetTo(string);
|
|
||||||
_DoLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the decorator's title
|
\brief Returns the decorator's title
|
||||||
\return the decorator's title
|
\return the decorator's title
|
||||||
*/
|
*/
|
||||||
const char *Decorator::GetTitle(void)
|
const char*
|
||||||
|
Decorator::GetTitle() const
|
||||||
{
|
{
|
||||||
return _title_string->String();
|
return fTitle.String();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -273,7 +259,9 @@ const char *Decorator::GetTitle(void)
|
|||||||
\return the decorator's border rectangle
|
\return the decorator's border rectangle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BRect Decorator::GetBorderRect(void){
|
BRect
|
||||||
|
Decorator::GetBorderRect() const
|
||||||
|
{
|
||||||
return _borderrect;
|
return _borderrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,10 +270,49 @@ BRect Decorator::GetBorderRect(void){
|
|||||||
\return the decorator's tab rectangle
|
\return the decorator's tab rectangle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BRect Decorator::GetTabRect(void){
|
BRect
|
||||||
|
Decorator::GetTabRect() const
|
||||||
|
{
|
||||||
return _tabrect;
|
return _tabrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the value of the close button
|
||||||
|
\return true if down, false if up
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Decorator::GetClose()
|
||||||
|
{
|
||||||
|
return fClosePressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the value of the minimize button
|
||||||
|
\return true if down, false if up
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Decorator::GetMinimize()
|
||||||
|
{
|
||||||
|
return fMinimizePressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the value of the zoom button
|
||||||
|
\return true if down, false if up
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Decorator::GetZoom()
|
||||||
|
{
|
||||||
|
return fZoomPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSizeLimits
|
||||||
|
void
|
||||||
|
Decorator::GetSizeLimits(float* minWidth, float* minHeight,
|
||||||
|
float* maxWidth, float* maxHeight) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Changes the focus value of the decorator
|
\brief Changes the focus value of the decorator
|
||||||
\param is_active True if active, false if not
|
\param is_active True if active, false if not
|
||||||
@@ -293,258 +320,26 @@ BRect Decorator::GetTabRect(void){
|
|||||||
While this call will not update the screen, it will affect how future
|
While this call will not update the screen, it will affect how future
|
||||||
updates work.
|
updates work.
|
||||||
*/
|
*/
|
||||||
void Decorator::SetFocus(bool is_active)
|
void
|
||||||
|
Decorator::SetFocus(bool is_active)
|
||||||
{
|
{
|
||||||
_has_focus=is_active;
|
fIsFocused = is_active;
|
||||||
_SetFocus();
|
_SetFocus();
|
||||||
}
|
// TODO: maybe it would be cleaner to handle the redraw here.
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Provides the number of characters that will fit in the given width
|
|
||||||
\param width Maximum number of pixels the title can be
|
|
||||||
\return the number of characters that will fit in the given width
|
|
||||||
*/
|
|
||||||
int32 Decorator::_ClipTitle(float width)
|
|
||||||
{
|
|
||||||
if(_driver)
|
|
||||||
{
|
|
||||||
int32 strlength=_title_string->CountChars();
|
|
||||||
float pixwidth=_driver->StringWidth(_title_string->String(),strlength,&_drawdata);
|
|
||||||
|
|
||||||
while(strlength>=0)
|
|
||||||
{
|
|
||||||
if(pixwidth<width)
|
|
||||||
return strlength;
|
|
||||||
|
|
||||||
strlength--;
|
|
||||||
pixwidth=_driver->StringWidth(_title_string->String(),strlength,&_drawdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Virtual Methods
|
// Virtual Methods
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Moves the decorator frame and all default rectangles
|
|
||||||
\param x X Offset
|
|
||||||
\param y y Offset
|
|
||||||
|
|
||||||
If a subclass implements this method, be sure to call Decorator::MoveBy
|
|
||||||
to ensure that internal members are also updated. All members of the Decorator
|
|
||||||
class are automatically moved in this method
|
|
||||||
*/
|
|
||||||
void Decorator::MoveBy(float x, float y)
|
|
||||||
{
|
|
||||||
_zoomrect.OffsetBy(x,y);
|
|
||||||
_closerect.OffsetBy(x,y);
|
|
||||||
_minimizerect.OffsetBy(x,y);
|
|
||||||
_minimizerect.OffsetBy(x,y);
|
|
||||||
_tabrect.OffsetBy(x,y);
|
|
||||||
_frame.OffsetBy(x,y);
|
|
||||||
_resizerect.OffsetBy(x,y);
|
|
||||||
_borderrect.OffsetBy(x,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Moves the decorator frame and all default rectangles
|
|
||||||
\param pt Point containing the offsets
|
|
||||||
|
|
||||||
If a subclass implements this method, be sure to call Decorator::MoveBy
|
|
||||||
to ensure that internal members are also updated. All members of the Decorator
|
|
||||||
class are automatically moved in this method
|
|
||||||
*/
|
|
||||||
void 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
|
|
||||||
\param dy y offset
|
|
||||||
|
|
||||||
This is a required function for subclasses to implement - the default does nothing.
|
|
||||||
Note that window resize flags should be followed and _frame should be resized
|
|
||||||
accordingly. It would also be a wise idea to ensure that the window's rectangles
|
|
||||||
are not inverted.
|
|
||||||
*/
|
|
||||||
void Decorator::ResizeBy(float x, float y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Resizes the decorator frame
|
|
||||||
\param pt Point containing the offsets
|
|
||||||
|
|
||||||
This is a required function for subclasses to implement - the default does nothing.
|
|
||||||
Note that window resize flags should be followed and _frame should be resized
|
|
||||||
accordingly. It would also be a wise idea to ensure that the window's rectangles
|
|
||||||
are not inverted.
|
|
||||||
*/
|
|
||||||
void Decorator::ResizeBy(BPoint pt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Updates the decorator's look in the area r
|
|
||||||
\param r The area to update.
|
|
||||||
|
|
||||||
The default version updates all areas which intersect the frame and tab.
|
|
||||||
*/
|
|
||||||
void Decorator::Draw(BRect r)
|
|
||||||
{
|
|
||||||
_DrawTab(r & _tabrect);
|
|
||||||
_DrawFrame(r & _frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Forces a complete decorator update
|
|
||||||
void Decorator::Draw(void)
|
|
||||||
{
|
|
||||||
_DrawTab(_tabrect);
|
|
||||||
_DrawFrame(_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Draws the close button
|
|
||||||
void Decorator::DrawClose(void)
|
|
||||||
{
|
|
||||||
_DrawClose(_closerect);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! draws the frame
|
|
||||||
void Decorator::DrawFrame(void)
|
|
||||||
{
|
|
||||||
_DrawFrame(_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! draws the minimize button
|
|
||||||
void Decorator::DrawMinimize(void)
|
|
||||||
{
|
|
||||||
_DrawTab(_minimizerect);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! draws the tab, title, and buttons
|
|
||||||
void Decorator::DrawTab(void)
|
|
||||||
{
|
|
||||||
_DrawTab(_tabrect);
|
|
||||||
_DrawZoom(_zoomrect);
|
|
||||||
_DrawMinimize(_minimizerect);
|
|
||||||
_DrawTitle(_tabrect);
|
|
||||||
_DrawClose(_closerect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draws the title
|
|
||||||
void Decorator::DrawTitle(void)
|
|
||||||
{
|
|
||||||
_DrawTitle(_tabrect);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! draws the zoom button
|
|
||||||
void Decorator::DrawZoom(void)
|
|
||||||
{
|
|
||||||
_DrawZoom(_zoomrect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the close button
|
|
||||||
\param r Area of the button to update
|
|
||||||
|
|
||||||
Unless a subclass has a particularly large button, it is probably unnecessary
|
|
||||||
to check the update rectangle.
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawClose(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the frame
|
|
||||||
\param r Area of the frame to update
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawFrame(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the minimize button
|
|
||||||
\param r Area of the button to update
|
|
||||||
|
|
||||||
Unless a subclass has a particularly large button, it is probably unnecessary
|
|
||||||
to check the update rectangle.
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawMinimize(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the tab
|
|
||||||
\param r Area of the tab to update
|
|
||||||
|
|
||||||
This function is called when the tab itself needs drawn. Other items, like the
|
|
||||||
window title or buttons, should not be drawn here.
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawTab(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the title
|
|
||||||
\param r area of the title to update
|
|
||||||
|
|
||||||
The main tasks for this function are to ensure that the decorator draws the title
|
|
||||||
only in its own area and drawing the title itself. Using B_OP_COPY for drawing
|
|
||||||
the title is recommended because of the marked performance hit of the other
|
|
||||||
drawing modes, but it is not a requirement.
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawTitle(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Actually draws the zoom button
|
|
||||||
\param r Area of the button to update
|
|
||||||
|
|
||||||
Unless a subclass has a particularly large button, it is probably unnecessary
|
|
||||||
to check the update rectangle.
|
|
||||||
*/
|
|
||||||
void Decorator::_DrawZoom(BRect r)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Hook function for when the color set is updated
|
|
||||||
|
|
||||||
This function is called after the decorator's color set is updated. Quite useful
|
|
||||||
if the decorator uses colors based on those in the system.
|
|
||||||
*/
|
|
||||||
void Decorator::_SetColors(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the "footprint" of the entire window, including decorator
|
\brief Returns the "footprint" of the entire window, including decorator
|
||||||
\param region Region to be changed to represent the window's screen footprint
|
\param region Region to be changed to represent the window's screen footprint
|
||||||
|
|
||||||
This function is required by all subclasses.
|
This function is required by all subclasses.
|
||||||
*/
|
*/
|
||||||
void Decorator::GetFootprint(BRegion *region)
|
void
|
||||||
|
Decorator::GetFootprint(BRegion *region)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,18 +376,278 @@ void Decorator::GetFootprint(BRegion *region)
|
|||||||
This function is required by all subclasses.
|
This function is required by all subclasses.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
click_type Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
|
click_type
|
||||||
|
Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
|
||||||
{
|
{
|
||||||
return DEC_NONE;
|
return DEC_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Hook function called when the decorator changes focus
|
/*!
|
||||||
void Decorator::_SetFocus(void)
|
\brief Moves the decorator frame and all default rectangles
|
||||||
|
\param x X Offset
|
||||||
|
\param y y Offset
|
||||||
|
|
||||||
|
If a subclass implements this method, be sure to call Decorator::MoveBy
|
||||||
|
to ensure that internal members are also updated. All members of the Decorator
|
||||||
|
class are automatically moved in this method
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::MoveBy(float x, float y)
|
||||||
|
{
|
||||||
|
_zoomrect.OffsetBy(x, y);
|
||||||
|
_closerect.OffsetBy(x, y);
|
||||||
|
_minimizerect.OffsetBy(x, y);
|
||||||
|
_minimizerect.OffsetBy(x, y);
|
||||||
|
_tabrect.OffsetBy(x, y);
|
||||||
|
_frame.OffsetBy(x, y);
|
||||||
|
_resizerect.OffsetBy(x, y);
|
||||||
|
_borderrect.OffsetBy(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Moves the decorator frame and all default rectangles
|
||||||
|
\param pt Point containing the offsets
|
||||||
|
|
||||||
|
If a subclass implements this method, be sure to call Decorator::MoveBy
|
||||||
|
to ensure that internal members are also updated. All members of the Decorator
|
||||||
|
class are automatically moved in this method
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
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
|
||||||
|
\param dy y offset
|
||||||
|
|
||||||
|
This is a required function for subclasses to implement - the default does nothing.
|
||||||
|
Note that window resize flags should be followed and _frame should be resized
|
||||||
|
accordingly. It would also be a wise idea to ensure that the window's rectangles
|
||||||
|
are not inverted.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::ResizeBy(float x, float y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Function for calculating layout for the decorator
|
/*!
|
||||||
void Decorator::_DoLayout(void)
|
\brief Resizes the decorator frame
|
||||||
{
|
\param pt Point containing the offsets
|
||||||
|
|
||||||
|
This is a required function for subclasses to implement - the default does nothing.
|
||||||
|
Note that window resize flags should be followed and _frame should be resized
|
||||||
|
accordingly. It would also be a wise idea to ensure that the window's rectangles
|
||||||
|
are not inverted.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::ResizeBy(BPoint pt)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Updates the decorator's look in the area r
|
||||||
|
\param r The area to update.
|
||||||
|
|
||||||
|
The default version updates all areas which intersect the frame and tab.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::Draw(BRect r)
|
||||||
|
{
|
||||||
|
_DrawFrame(r & _frame);
|
||||||
|
_DrawTab(r & _tabrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Forces a complete decorator update
|
||||||
|
void
|
||||||
|
Decorator::Draw()
|
||||||
|
{
|
||||||
|
_DrawFrame(_frame);
|
||||||
|
_DrawTab(_tabrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Draws the close button
|
||||||
|
void
|
||||||
|
Decorator::DrawClose()
|
||||||
|
{
|
||||||
|
_DrawClose(_closerect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws the frame
|
||||||
|
void
|
||||||
|
Decorator::DrawFrame()
|
||||||
|
{
|
||||||
|
_DrawFrame(_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws the minimize button
|
||||||
|
void
|
||||||
|
Decorator::DrawMinimize(void)
|
||||||
|
{
|
||||||
|
_DrawTab(_minimizerect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws the tab, title, and buttons
|
||||||
|
void
|
||||||
|
Decorator::DrawTab()
|
||||||
|
{
|
||||||
|
_DrawTab(_tabrect);
|
||||||
|
_DrawZoom(_zoomrect);
|
||||||
|
_DrawMinimize(_minimizerect);
|
||||||
|
_DrawTitle(_tabrect);
|
||||||
|
_DrawClose(_closerect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws the title
|
||||||
|
void
|
||||||
|
Decorator::DrawTitle()
|
||||||
|
{
|
||||||
|
_DrawTitle(_tabrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws the zoom button
|
||||||
|
void
|
||||||
|
Decorator::DrawZoom(void)
|
||||||
|
{
|
||||||
|
_DrawZoom(_zoomrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Provides the number of characters that will fit in the given width
|
||||||
|
\param width Maximum number of pixels the title can be
|
||||||
|
\return the number of characters that will fit in the given width
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
Decorator::_ClipTitle(float width)
|
||||||
|
{
|
||||||
|
// TODO: eventually, use ServerFont::TruncateString()
|
||||||
|
// when it exists (if it doesn't already)
|
||||||
|
if (_driver) {
|
||||||
|
int32 strlength = fTitle.CountChars();
|
||||||
|
float pixwidth=_driver->StringWidth(fTitle.String(),strlength,&_drawdata);
|
||||||
|
|
||||||
|
while (strlength >= 0) {
|
||||||
|
if (pixwidth < width)
|
||||||
|
return strlength;
|
||||||
|
|
||||||
|
strlength--;
|
||||||
|
pixwidth=_driver->StringWidth(fTitle.String(), strlength, &_drawdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Function for calculating layout for the decorator
|
||||||
|
void
|
||||||
|
Decorator::_DoLayout()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the frame
|
||||||
|
\param r Area of the frame to update
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawFrame(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the tab
|
||||||
|
\param r Area of the tab to update
|
||||||
|
|
||||||
|
This function is called when the tab itself needs drawn. Other items, like the
|
||||||
|
window title or buttons, should not be drawn here.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawTab(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the close button
|
||||||
|
\param r Area of the button to update
|
||||||
|
|
||||||
|
Unless a subclass has a particularly large button, it is probably unnecessary
|
||||||
|
to check the update rectangle.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawClose(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the title
|
||||||
|
\param r area of the title to update
|
||||||
|
|
||||||
|
The main tasks for this function are to ensure that the decorator draws the title
|
||||||
|
only in its own area and drawing the title itself. Using B_OP_COPY for drawing
|
||||||
|
the title is recommended because of the marked performance hit of the other
|
||||||
|
drawing modes, but it is not a requirement.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawTitle(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the zoom button
|
||||||
|
\param r Area of the button to update
|
||||||
|
|
||||||
|
Unless a subclass has a particularly large button, it is probably unnecessary
|
||||||
|
to check the update rectangle.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawZoom(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Actually draws the minimize button
|
||||||
|
\param r Area of the button to update
|
||||||
|
|
||||||
|
Unless a subclass has a particularly large button, it is probably unnecessary
|
||||||
|
to check the update rectangle.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_DrawMinimize(BRect r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Hook function called when the decorator changes focus
|
||||||
|
void
|
||||||
|
Decorator::_SetFocus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Hook function for when the color set is updated
|
||||||
|
|
||||||
|
This function is called after the decorator's color set is updated. Quite useful
|
||||||
|
if the decorator uses colors based on those in the system.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Decorator::_SetColors()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,52 +30,74 @@
|
|||||||
#include "Decorator.h"
|
#include "Decorator.h"
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
|
|
||||||
class DefaultDecorator: public Decorator
|
class DefaultDecorator: public Decorator {
|
||||||
{
|
public:
|
||||||
public:
|
DefaultDecorator(BRect frame,
|
||||||
DefaultDecorator(BRect frame, int32 wlook, int32 wfeel, int32 wflags);
|
int32 look,
|
||||||
virtual ~DefaultDecorator(void);
|
int32 feel,
|
||||||
|
int32 flags);
|
||||||
|
virtual ~DefaultDecorator();
|
||||||
|
|
||||||
virtual void MoveBy(float x, float y);
|
virtual void MoveBy(float x, float y);
|
||||||
virtual void MoveBy(BPoint pt);
|
virtual void MoveBy(BPoint pt);
|
||||||
virtual void ResizeBy(float x, float y);
|
virtual void ResizeBy(float x, float y);
|
||||||
virtual void ResizeBy(BPoint pt);
|
virtual void ResizeBy(BPoint pt);
|
||||||
|
|
||||||
virtual void Draw(BRect r);
|
virtual void Draw(BRect r);
|
||||||
virtual void Draw(void);
|
virtual void Draw();
|
||||||
virtual void GetFootprint(BRegion *region);
|
|
||||||
virtual BRect SlideTab(float dx, float dy);
|
virtual void GetSizeLimits(float* minWidth, float* minHeight,
|
||||||
virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers);
|
float* maxWidth, float* maxHeight) const;
|
||||||
|
|
||||||
|
virtual void GetFootprint(BRegion *region);
|
||||||
|
|
||||||
|
virtual BRect SlideTab(float dx, float dy);
|
||||||
|
virtual click_type Clicked(BPoint pt, int32 buttons,
|
||||||
|
int32 modifiers);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _DrawClose(BRect r);
|
virtual void _DoLayout();
|
||||||
virtual void _DrawFrame(BRect r);
|
|
||||||
virtual void _DrawTab(BRect r);
|
|
||||||
virtual void _DrawTitle(BRect r);
|
|
||||||
virtual void _DrawZoom(BRect r);
|
|
||||||
virtual void _DoLayout(void);
|
|
||||||
virtual void _SetFocus(void);
|
|
||||||
virtual void _SetColors(void);
|
|
||||||
void DrawBlendedRect(BRect r, bool down);
|
|
||||||
uint32 taboffset;
|
|
||||||
|
|
||||||
RGBColor tab_highcol, tab_lowcol;
|
virtual void _DrawFrame(BRect r);
|
||||||
RGBColor button_highcol, button_lowcol;
|
virtual void _DrawTab(BRect r);
|
||||||
RGBColor frame_highcol, frame_midcol, frame_lowcol, frame_highercol,
|
|
||||||
frame_lowercol;
|
|
||||||
RGBColor textcol;
|
|
||||||
|
|
||||||
RGBColor *framecolors;
|
virtual void _DrawClose(BRect r);
|
||||||
|
virtual void _DrawTitle(BRect r);
|
||||||
|
virtual void _DrawZoom(BRect r);
|
||||||
|
|
||||||
|
virtual void _SetFocus();
|
||||||
|
virtual void _SetColors();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _DrawBlendedRect(BRect r, bool down);
|
||||||
|
void _GetButtonSizeAndOffset(const BRect& tabRect,
|
||||||
|
float* offset, float*size) const;
|
||||||
|
void _LayoutTabItems(const BRect& tabRect);
|
||||||
|
|
||||||
|
RGBColor fButtonHighColor;
|
||||||
|
RGBColor fButtonLowColor;
|
||||||
|
RGBColor fTextColor;
|
||||||
|
RGBColor fTabColor;
|
||||||
|
|
||||||
|
RGBColor* fFrameColors;
|
||||||
|
|
||||||
// Individual rects for handling window frame rendering the proper way
|
// Individual rects for handling window frame
|
||||||
BRect rightborder,leftborder,topborder,bottomborder;
|
// rendering the proper way
|
||||||
uint64 solidhigh, solidlow;
|
BRect fRightBorder;
|
||||||
|
BRect fLeftBorder;
|
||||||
int32 borderwidth;
|
BRect fTopBorder;
|
||||||
|
BRect fBottomBorder;
|
||||||
|
|
||||||
bool slidetab;
|
int32 fBorderWidth;
|
||||||
int textoffset;
|
|
||||||
float titlepixelwidth;
|
// bool fSlidingTab;
|
||||||
|
// uint32 fTabOffset;
|
||||||
|
float fTextOffset;
|
||||||
|
|
||||||
|
float fMinTabWidth;
|
||||||
|
float fMaxTabWidth;
|
||||||
|
BString fTruncatedTitle;
|
||||||
|
int32 fTruncatedTitleLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ FontServer::FontServer(void)
|
|||||||
&& init)
|
&& init)
|
||||||
init=false;
|
init=false;
|
||||||
|
|
||||||
families=new BList(0);
|
families=new BList(20);
|
||||||
plain=NULL;
|
plain=NULL;
|
||||||
bold=NULL;
|
bold=NULL;
|
||||||
fixed=NULL;
|
fixed=NULL;
|
||||||
@@ -86,9 +86,10 @@ FontServer::~FontServer(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Locks access to the font server
|
//! Locks access to the font server
|
||||||
void FontServer::Lock(void)
|
bool
|
||||||
|
FontServer::Lock(void)
|
||||||
{
|
{
|
||||||
acquire_sem(lock);
|
return acquire_sem(lock) >= B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Unlocks access to the font server
|
//! Unlocks access to the font server
|
||||||
@@ -248,15 +249,21 @@ status_t FontServer::ScanDirectory(const char *fontspath)
|
|||||||
|
|
||||||
if (error!=0)
|
if (error!=0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
charmap=_GetSupportedCharmap(face);
|
// TODO: Commenting this out makes my "Unicode glyph lookup"
|
||||||
|
// work with our default fonts. The real fix is to select the
|
||||||
|
// Unicode char map (if supported), and/or adjust the
|
||||||
|
// utf8 -> glyph-index mapping everywhere to handle other
|
||||||
|
// char maps. We could also ignore fonts that don't support
|
||||||
|
// the Unicode lookup as a temporary "solution".
|
||||||
|
/* charmap=_GetSupportedCharmap(face);
|
||||||
if(!charmap)
|
if(!charmap)
|
||||||
{
|
{
|
||||||
FT_Done_Face(face);
|
FT_Done_Face(face);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
face->charmap=charmap;
|
face->charmap=charmap;*/
|
||||||
|
|
||||||
family=GetFamily(face->family_name);
|
family=GetFamily(face->family_name);
|
||||||
|
|
||||||
|
|||||||
@@ -847,19 +847,13 @@ Layer::Redraw(const BRegion& reg, Layer *startFrom)
|
|||||||
void
|
void
|
||||||
Layer::Draw(const BRect &r)
|
Layer::Draw(const BRect &r)
|
||||||
{
|
{
|
||||||
// TODO/NOTE: this should be an empty method! the next lines are for testing only
|
|
||||||
|
|
||||||
#ifdef DEBUG_LAYER
|
#ifdef DEBUG_LAYER
|
||||||
printf("Layer(%s)::Draw: ", GetName());
|
printf("Layer(%s)::Draw: ", GetName());
|
||||||
r.PrintToStream();
|
r.PrintToStream();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: don't do this if ViewColor() is B_TRANSPARENT_COLOR
|
if (!fLayerData->ViewColor().IsTransparentMagic())
|
||||||
fDriver->FillRect(r, fLayerData->ViewColor());
|
fDriver->FillRect(r, fLayerData->ViewColor());
|
||||||
// RGBColor c(rand()%255,rand()%255,rand()%255);
|
|
||||||
// fDriver->FillRect(r, c);
|
|
||||||
|
|
||||||
// empty HOOK function.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmptyGlobals
|
// EmptyGlobals
|
||||||
|
|||||||
+287
-265
@@ -61,41 +61,68 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152);
|
static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152);
|
||||||
|
static int32 kMaxWorkspaceCount = 32;
|
||||||
|
|
||||||
RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||||
Desktop *desktop, DisplayDriver *driver)
|
Desktop *desktop, DisplayDriver *driver)
|
||||||
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
|
: Layer(BRect(0, 0, 0, 0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver),
|
||||||
|
|
||||||
|
fDesktop(desktop),
|
||||||
|
fDragMessage(NULL),
|
||||||
|
fLastMouseMoved(this),
|
||||||
|
fMouseTargetWinBorder(NULL),
|
||||||
|
fViewAction(B_ENTERED_VIEW),
|
||||||
|
fEventMaskLayer(NULL),
|
||||||
|
|
||||||
|
fCursorManager(),
|
||||||
|
|
||||||
|
fAllRegionsLock("root layer region lock"),
|
||||||
|
|
||||||
|
fThreadID(B_ERROR),
|
||||||
|
fListenPort(-1),
|
||||||
|
|
||||||
|
fScreenPtrList(32),
|
||||||
|
fRows(0),
|
||||||
|
fColumns(0),
|
||||||
|
|
||||||
|
fScreenWidth(0),
|
||||||
|
fScreenHeight(0),
|
||||||
|
fColorSpace(B_RGB32),
|
||||||
|
fFrequency(60.0),
|
||||||
|
|
||||||
|
fButtons(0),
|
||||||
|
fLastMousePosition(0.0, 0.0),
|
||||||
|
// fMovingWindow(false),
|
||||||
|
// fResizingWindow(false),
|
||||||
|
fHaveWinBorderList(false),
|
||||||
|
|
||||||
|
fActiveWksIndex(0),
|
||||||
|
fWsCount(0),
|
||||||
|
fWorkspace(new Workspace*[kMaxWorkspaceCount]),
|
||||||
|
|
||||||
|
fWinBorderListLength(64),
|
||||||
|
fWinBorderList2((WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*))),
|
||||||
|
fWinBorderList((WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*))),
|
||||||
|
fWinBorderCount(0),
|
||||||
|
fWinBorderIndex(0),
|
||||||
|
|
||||||
|
fScreenShotIndex(1),
|
||||||
|
|
||||||
|
#if ON_SCREEN_DEBUGGING_INFO
|
||||||
|
fQuiting(false),
|
||||||
|
fDebugInfo("")
|
||||||
|
#else
|
||||||
|
fQuiting(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
fDesktop = desktop;
|
|
||||||
|
|
||||||
fWinBorderListLength = 64;
|
|
||||||
fWinBorderList2 = (WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*));
|
|
||||||
fWinBorderList = (WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*));
|
|
||||||
fWinBorderCount = 0;
|
|
||||||
fWinBorderIndex = 0;
|
|
||||||
fWsCount = 0;
|
|
||||||
|
|
||||||
fMovingWindow = false;
|
|
||||||
fResizingWindow = false;
|
|
||||||
fHaveWinBorderList = false;
|
|
||||||
fLastMouseMoved = this;
|
|
||||||
fViewAction = B_ENTERED_VIEW;
|
|
||||||
fEventMaskLayer = NULL;
|
|
||||||
fDragMessage = NULL;
|
|
||||||
fScreenShotIndex = 1;
|
|
||||||
|
|
||||||
fQuiting = false;
|
|
||||||
|
|
||||||
//NOTE: be careful about this one.
|
//NOTE: be careful about this one.
|
||||||
fRootLayer = this;
|
fRootLayer = this;
|
||||||
fRows = 0;
|
|
||||||
fColumns = 0;
|
|
||||||
|
|
||||||
// easy way to identify this class.
|
// easy way to identify this class.
|
||||||
fClassID = AS_ROOTLAYER_CLASS;
|
fClassID = AS_ROOTLAYER_CLASS;
|
||||||
fHidden = false;
|
fHidden = false;
|
||||||
|
|
||||||
memset(&fWorkspace[0], 0, sizeof(Workspace*)*32);
|
memset(fWorkspace, 0, sizeof(Workspace*) * kMaxWorkspaceCount);
|
||||||
SetWorkspaceCount(workspaceCount);
|
SetWorkspaceCount(workspaceCount);
|
||||||
|
|
||||||
// TODO: this should eventually be replaced by a method to convert the monitor
|
// TODO: this should eventually be replaced by a method to convert the monitor
|
||||||
@@ -103,13 +130,12 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
// ReadWorkspaceData(WORKSPACE_DATA_LIST);
|
// ReadWorkspaceData(WORKSPACE_DATA_LIST);
|
||||||
|
|
||||||
// TODO: read these 4 from a configuration file.
|
// TODO: read these 4 from a configuration file.
|
||||||
fScreenWidth = 0;
|
// fScreenWidth = 0;
|
||||||
fScreenHeight = 0;
|
// fScreenHeight = 0;
|
||||||
fColorSpace = B_RGB32;
|
// fColorSpace = B_RGB32;
|
||||||
fFrequency = 60.f;
|
// fFrequency = 60.f;
|
||||||
|
|
||||||
// init the first, default workspace
|
// init the first, default workspace
|
||||||
fActiveWksIndex = 0;
|
|
||||||
fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00,
|
fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00,
|
||||||
kDefaultWorkspaceColor);
|
kDefaultWorkspaceColor);
|
||||||
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
||||||
@@ -121,7 +147,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
fListenPort = find_port(SERVER_INPUT_PORT);
|
fListenPort = find_port(SERVER_INPUT_PORT);
|
||||||
if (fListenPort == B_NAME_NOT_FOUND) {
|
if (fListenPort == B_NAME_NOT_FOUND) {
|
||||||
fListenPort = -1;
|
fListenPort = -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#if ON_SCREEN_DEBUGGING_INFO
|
#if ON_SCREEN_DEBUGGING_INFO
|
||||||
DebugInfoManager::Default()->SetRootLayer(this);
|
DebugInfoManager::Default()->SetRootLayer(this);
|
||||||
@@ -131,20 +156,24 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
|
|
||||||
RootLayer::~RootLayer()
|
RootLayer::~RootLayer()
|
||||||
{
|
{
|
||||||
int32 exitValue;
|
fQuiting = true;
|
||||||
fQuiting = true;
|
|
||||||
BPortLink msg(fListenPort, -1);
|
BPortLink msg(fListenPort, -1);
|
||||||
msg.StartMessage(B_QUIT_REQUESTED);
|
msg.StartMessage(B_QUIT_REQUESTED);
|
||||||
msg.EndMessage();
|
msg.EndMessage();
|
||||||
msg.Flush();
|
msg.Flush();
|
||||||
|
|
||||||
wait_for_thread(fThreadID, &exitValue);
|
status_t dummy;
|
||||||
|
wait_for_thread(fThreadID, &dummy);
|
||||||
|
|
||||||
delete fDragMessage;
|
delete fDragMessage;
|
||||||
|
|
||||||
for (int32 i = 0; i < fWsCount; i++)
|
for (int32 i = 0; i < fWsCount; i++)
|
||||||
delete fWorkspace[i];
|
delete fWorkspace[i];
|
||||||
|
delete[] fWorkspace;
|
||||||
|
|
||||||
|
free(fWinBorderList2);
|
||||||
|
free(fWinBorderList);
|
||||||
// RootLayer object just uses Screen objects, it is not allowed to delete them.
|
// RootLayer object just uses Screen objects, it is not allowed to delete them.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +332,7 @@ int32 RootLayer::WorkingThread(void *data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
STRACE(("RootLayer(%s)::WorkingThread received unexpected code %lx\n",oneRootLayer->GetName(), code));
|
printf("RootLayer(%s)::WorkingThread received unexpected code %lx\n", oneRootLayer->GetName(), code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,9 +580,12 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
if (index >= fWsCount || index == fActiveWksIndex || index < 0)
|
if (index >= fWsCount || index == fActiveWksIndex || index < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// you cannot switch workspaces on R5 if there is an event mask layer
|
||||||
|
if (fEventMaskLayer)
|
||||||
|
return false;
|
||||||
|
|
||||||
// if fWorkspace[index] object does not exist, create and add allowed WinBorders
|
// if fWorkspace[index] object does not exist, create and add allowed WinBorders
|
||||||
if (!fWorkspace[index])
|
if (!fWorkspace[index]) {
|
||||||
{
|
|
||||||
// TODO: we NEED datas from a file!!!
|
// TODO: we NEED datas from a file!!!
|
||||||
fWorkspace[index] = new Workspace(index, 0xFF00FF00, kDefaultWorkspaceColor);
|
fWorkspace[index] = new Workspace(index, 0xFF00FF00, kDefaultWorkspaceColor);
|
||||||
|
|
||||||
@@ -565,10 +597,8 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
int32 ptrCount = windowList.CountItems();
|
int32 ptrCount = windowList.CountItems();
|
||||||
WinBorder **ptrWin = (WinBorder**)windowList.Items();
|
WinBorder **ptrWin = (WinBorder**)windowList.Items();
|
||||||
|
|
||||||
for (int32 i = 0; i < ptrCount; i++)
|
for (int32 i = 0; i < ptrCount; i++) {
|
||||||
{
|
if (ptrWin[i]->Workspaces() & (0x00000001UL << index)) {
|
||||||
if (ptrWin[i]->Workspaces() & (0x00000001UL << index))
|
|
||||||
{
|
|
||||||
fWorkspace[index]->AddWinBorder(ptrWin[i]);
|
fWorkspace[index]->AddWinBorder(ptrWin[i]);
|
||||||
if (!ptrWin[i]->IsHidden())
|
if (!ptrWin[i]->IsHidden())
|
||||||
fWorkspace[index]->ShowWinBorder(ptrWin[i]);
|
fWorkspace[index]->ShowWinBorder(ptrWin[i]);
|
||||||
@@ -577,6 +607,7 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
|
|
||||||
fDesktop->Unlock();
|
fDesktop->Unlock();
|
||||||
}
|
}
|
||||||
|
// adjust our DrawData to workspace colors
|
||||||
rgb_color bg = fWorkspace[index]->BGColor().GetColor32();
|
rgb_color bg = fWorkspace[index]->BGColor().GetColor32();
|
||||||
if ((bg.red + bg.green + bg.blue) / 3 > 128)
|
if ((bg.red + bg.green + bg.blue) / 3 > 128)
|
||||||
fLayerData->SetHighColor(RGBColor(0, 0, 0));
|
fLayerData->SetHighColor(RGBColor(0, 0, 0));
|
||||||
@@ -584,10 +615,11 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
||||||
fLayerData->SetLowColor(fWorkspace[index]->BGColor());
|
fLayerData->SetLowColor(fWorkspace[index]->BGColor());
|
||||||
|
|
||||||
int32 exIndex = ActiveWorkspaceIndex();
|
int32 exIndex = ActiveWorkspaceIndex();
|
||||||
|
|
||||||
|
// send the workspace changed message for the old workspace
|
||||||
{
|
{
|
||||||
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
||||||
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
||||||
activatedMsg.AddInt32("workspace", fActiveWksIndex);
|
activatedMsg.AddInt32("workspace", fActiveWksIndex);
|
||||||
activatedMsg.AddBool("active", false);
|
activatedMsg.AddBool("active", false);
|
||||||
@@ -596,48 +628,49 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
fWinBorderList[i]->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false);
|
fWinBorderList[i]->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fActiveWksIndex = index;
|
fActiveWksIndex = index;
|
||||||
|
|
||||||
if (fMovingWindow && fEventMaskLayer)
|
if (fMouseTargetWinBorder) {
|
||||||
{
|
// if (fMovingWindow && fEventMaskLayer) {
|
||||||
WinBorder *movingWinBorder = (WinBorder*)fEventMaskLayer;
|
// WinBorder *movingWinBorder = (WinBorder*)fEventMaskLayer;
|
||||||
|
|
||||||
movingWinBorder->MouseUp(DEC_NONE);
|
// movingWinBorder->MouseUp(DEC_NONE);
|
||||||
|
|
||||||
// NOTE: DO NOT reset these 2 members! We still want to move our window in the new workspace
|
// NOTE: DO NOT reset these 2 members! We still want to move our window in the new workspace
|
||||||
//fEventMaskLayer = NULL;
|
//fEventMaskLayer = NULL;
|
||||||
//fMovingWindow = false;
|
//fMovingWindow = false;
|
||||||
fResizingWindow = false;
|
// fResizingWindow = false;
|
||||||
|
|
||||||
|
// Take the WinBorder we're currently dragging with us to the new workspace
|
||||||
|
// NOTE: The code looks broken for WinBorders that show on multiple workspaces
|
||||||
|
// at the same time.
|
||||||
|
|
||||||
// only normal windows can change workspaces
|
// only normal windows can change workspaces
|
||||||
if (movingWinBorder->Feel() == B_NORMAL_WINDOW_FEEL
|
if (fMouseTargetWinBorder->Feel() == B_NORMAL_WINDOW_FEEL
|
||||||
&& !ActiveWorkspace()->HasWinBorder(movingWinBorder))
|
&& !ActiveWorkspace()->HasWinBorder(fMouseTargetWinBorder)) {
|
||||||
{
|
|
||||||
// Workspace class expects a window to be hidden when it's about to be removed.
|
// Workspace class expects a window to be hidden when it's about to be removed.
|
||||||
// As we surely know this windows is visible, we simply set fHidden to true and then
|
// As we surely know this windows is visible, we simply set fHidden to true and then
|
||||||
// change it back when adding winBorder to the current workspace.
|
// change it back when adding winBorder to the current workspace.
|
||||||
movingWinBorder->fHidden = true;
|
fMouseTargetWinBorder->fHidden = true;
|
||||||
fWorkspace[exIndex]->HideWinBorder(movingWinBorder);
|
fWorkspace[exIndex]->HideWinBorder(fMouseTargetWinBorder);
|
||||||
fWorkspace[exIndex]->RemoveWinBorder(movingWinBorder);
|
fWorkspace[exIndex]->RemoveWinBorder(fMouseTargetWinBorder);
|
||||||
|
|
||||||
movingWinBorder->fHidden = false;
|
fMouseTargetWinBorder->fHidden = false;
|
||||||
ActiveWorkspace()->AddWinBorder(movingWinBorder);
|
ActiveWorkspace()->AddWinBorder(fMouseTargetWinBorder);
|
||||||
ActiveWorkspace()->ShowWinBorder(movingWinBorder);
|
ActiveWorkspace()->ShowWinBorder(fMouseTargetWinBorder);
|
||||||
|
|
||||||
// TODO: can you call SetWinBorderWorskpaces() instead of this?
|
// TODO: can you call SetWinBorderWorskpaces() instead of this?
|
||||||
uint32 wks = movingWinBorder->Workspaces();
|
uint32 wks = fMouseTargetWinBorder->Workspaces();
|
||||||
BMessage changedMsg(B_WORKSPACES_CHANGED);
|
BMessage changedMsg(B_WORKSPACES_CHANGED);
|
||||||
changedMsg.AddInt64("when", real_time_clock_usecs());
|
changedMsg.AddInt64("when", real_time_clock_usecs());
|
||||||
changedMsg.AddInt32("old", wks);
|
changedMsg.AddInt32("old", wks);
|
||||||
wks &= ~(0x00000001 << exIndex);
|
wks &= ~(0x00000001 << exIndex);
|
||||||
wks |= (0x00000001 << fActiveWksIndex);
|
wks |= (0x00000001 << fActiveWksIndex);
|
||||||
changedMsg.AddInt32("new", wks);
|
changedMsg.AddInt32("new", wks);
|
||||||
movingWinBorder->QuietlySetWorkspaces(wks);
|
fMouseTargetWinBorder->QuietlySetWorkspaces(wks);
|
||||||
movingWinBorder->Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false);
|
fMouseTargetWinBorder->Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false);
|
||||||
}
|
}
|
||||||
}
|
}/* else if (fEventMaskLayer) {
|
||||||
else if (fEventMaskLayer)
|
|
||||||
{
|
|
||||||
// is this a WinBorder object?
|
// is this a WinBorder object?
|
||||||
if (!fEventMaskLayer->fOwner)
|
if (!fEventMaskLayer->fOwner)
|
||||||
{
|
{
|
||||||
@@ -648,11 +681,12 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
|||||||
fEventMaskLayer = NULL;
|
fEventMaskLayer = NULL;
|
||||||
fMovingWindow = false;
|
fMovingWindow = false;
|
||||||
fResizingWindow = false;
|
fResizingWindow = false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fHaveWinBorderList = true;
|
fHaveWinBorderList = true;
|
||||||
get_workspace_windows();
|
get_workspace_windows();
|
||||||
|
|
||||||
|
// send the workspace changed message for the new workspace
|
||||||
{
|
{
|
||||||
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
||||||
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
||||||
@@ -707,7 +741,7 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// do nothing. winBorder was, and it's still is a member of this workspace
|
// do nothing. winBorder was, and it still is a member of this workspace
|
||||||
// OR, winBorder wasn't and it will not be in this workspace
|
// OR, winBorder wasn't and it will not be in this workspace
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,6 +750,7 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: look into this...
|
||||||
if (fEventMaskLayer)
|
if (fEventMaskLayer)
|
||||||
{
|
{
|
||||||
WinBorder *wb = fEventMaskLayer->fOwner?
|
WinBorder *wb = fEventMaskLayer->fOwner?
|
||||||
@@ -723,12 +758,12 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
|||||||
(WinBorder*)fEventMaskLayer;
|
(WinBorder*)fEventMaskLayer;
|
||||||
if (!fWorkspace[fActiveWksIndex]->HasWinBorder(wb))
|
if (!fWorkspace[fActiveWksIndex]->HasWinBorder(wb))
|
||||||
{
|
{
|
||||||
if (wb == fEventMaskLayer)
|
/* if (wb == fEventMaskLayer)
|
||||||
{
|
{
|
||||||
fMovingWindow = false;
|
fMovingWindow = false;
|
||||||
fResizingWindow = false;
|
fResizingWindow = false;
|
||||||
wb->MouseUp(DEC_NONE);
|
wb->MouseUp(DEC_NONE);
|
||||||
}
|
}*/
|
||||||
fEventMaskLayer = NULL;
|
fEventMaskLayer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,23 +779,20 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
|||||||
show_final_scene(exFocus, exActive);
|
show_final_scene(exFocus, exActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootLayer::SetWorkspaceCount(int32 wksCount)
|
void
|
||||||
|
RootLayer::SetWorkspaceCount(int32 wksCount)
|
||||||
{
|
{
|
||||||
if (wksCount < 1)
|
if (wksCount < 1)
|
||||||
wksCount = 1;
|
wksCount = 1;
|
||||||
if (wksCount > 32)
|
if (wksCount > kMaxWorkspaceCount)
|
||||||
wksCount = 32;
|
wksCount = kMaxWorkspaceCount;
|
||||||
|
|
||||||
for (int32 i = wksCount; i < fWsCount; i++)
|
for (int32 i = wksCount; i < fWsCount; i++) {
|
||||||
{
|
delete fWorkspace[i];
|
||||||
if (fWorkspace[i])
|
fWorkspace[i] = NULL;
|
||||||
{
|
|
||||||
delete fWorkspace[i];
|
|
||||||
fWorkspace[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fWsCount = wksCount;
|
fWsCount = wksCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootLayer::ReadWorkspaceData(const char *path)
|
void RootLayer::ReadWorkspaceData(const char *path)
|
||||||
@@ -946,13 +978,12 @@ RootLayer::SetScreenMode(int32 width, int32 height, uint32 colorSpace, float fre
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Input related methods
|
// Input related methods
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
inline
|
inline void
|
||||||
void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||||
{
|
{
|
||||||
switch(code)
|
switch(code) {
|
||||||
{
|
case B_MOUSE_DOWN: {
|
||||||
case B_MOUSE_DOWN:
|
//printf("RootLayer::MouseEventHandler(B_MOUSE_DOWN)\n");
|
||||||
{
|
|
||||||
// Attached data:
|
// Attached data:
|
||||||
// 1) int64 - time of mouse click
|
// 1) int64 - time of mouse click
|
||||||
// 2) float - x coordinate of mouse click
|
// 2) float - x coordinate of mouse click
|
||||||
@@ -970,7 +1001,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
|||||||
msg.Read<int32>(&evt.buttons);
|
msg.Read<int32>(&evt.buttons);
|
||||||
msg.Read<int32>(&evt.clicks);
|
msg.Read<int32>(&evt.clicks);
|
||||||
|
|
||||||
if (fLastMousePossition != evt.where) {
|
if (fLastMousePosition != evt.where) {
|
||||||
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
|
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
|
||||||
// correctly trigger entered/exited view transits.
|
// correctly trigger entered/exited view transits.
|
||||||
// Commented for now, since it is not _that_ critical and happens frequently with the Haiku
|
// Commented for now, since it is not _that_ critical and happens frequently with the Haiku
|
||||||
@@ -978,11 +1009,15 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
|||||||
// CRITICAL("mouse position changed in B_MOUSE_DOWN from last B_MOUSE_MOVED\n");
|
// CRITICAL("mouse position changed in B_MOUSE_DOWN from last B_MOUSE_MOVED\n");
|
||||||
// update on screen mouse pos
|
// update on screen mouse pos
|
||||||
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
||||||
fLastMousePossition = evt.where;
|
fLastMousePosition = evt.where;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll need this so that GetMouse can query for which buttons
|
||||||
|
// are down.
|
||||||
|
fButtons = evt.buttons;
|
||||||
|
|
||||||
if (fLastMouseMoved == NULL) {
|
if (fLastMouseMoved == NULL) {
|
||||||
CRITICAL("RootLayer: fLastMouseMoved is null!\n");
|
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_DOWN) fLastMouseMoved is null!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,21 +1026,16 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
|||||||
|
|
||||||
// we are clicking a WinBorder
|
// we are clicking a WinBorder
|
||||||
|
|
||||||
click_type action;
|
WinBorder* exActive = ActiveWinBorder();
|
||||||
bool invalidate;
|
WinBorder* exFocus = FocusWinBorder();
|
||||||
bool sendMessage = true;
|
WinBorder* target = fLastMouseMoved->fOwner ? fLastMouseMoved->fOwner
|
||||||
WinBorder *exActive = ActiveWinBorder();
|
: (WinBorder*)fLastMouseMoved;
|
||||||
WinBorder *exFocus = FocusWinBorder();
|
|
||||||
WinBorder *target = fLastMouseMoved->fOwner?
|
|
||||||
fLastMouseMoved->fOwner:
|
|
||||||
(WinBorder*)fLastMouseMoved;
|
|
||||||
|
|
||||||
action = target->TellWhat(evt);
|
click_type action = target->MouseDown(evt);
|
||||||
|
|
||||||
if (action == DEC_MOVETOBACK)
|
// TODO: only move to front if *not* in Focus Follows Mouse mode!
|
||||||
invalidate = ActiveWorkspace()->MoveToBack(target);
|
bool invalidate = action == DEC_MOVETOBACK ? ActiveWorkspace()->MoveToBack(target)
|
||||||
else
|
: ActiveWorkspace()->MoveToFront(target);
|
||||||
invalidate = ActiveWorkspace()->MoveToFront(target);
|
|
||||||
|
|
||||||
// Performance: MoveToFront() often returns true although it shouldn't do that.
|
// Performance: MoveToFront() often returns true although it shouldn't do that.
|
||||||
// This is because internaly it calls Workspace::ShowWinBorder() and this imposes
|
// This is because internaly it calls Workspace::ShowWinBorder() and this imposes
|
||||||
@@ -1014,55 +1044,57 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
|||||||
if (invalidate)
|
if (invalidate)
|
||||||
show_final_scene(exFocus, exActive);
|
show_final_scene(exFocus, exActive);
|
||||||
|
|
||||||
if (action == DEC_DRAG)
|
// some of the actions are handled by the WinBorder itself,
|
||||||
{
|
// others are handled by RootLayer
|
||||||
fMovingWindow = true;
|
fMouseTargetWinBorder = NULL;
|
||||||
}
|
switch (action) {
|
||||||
else if (action == DEC_RESIZE)
|
case DEC_MOVETOBACK:
|
||||||
{
|
// TODO: handle here once we support FFM...
|
||||||
fResizingWindow = true;
|
// now it is handled above
|
||||||
}
|
break;
|
||||||
else if (action != DEC_NONE && action != DEC_MOVETOBACK)
|
case DEC_NONE: {
|
||||||
{
|
// TODO: bring to front if not in FFM...
|
||||||
target->MouseDown(action);
|
// now it is handled above
|
||||||
}
|
bool sendMessage = true;
|
||||||
else if (action != DEC_MOVETOBACK)
|
// supress mouse down events if the window has no focus or
|
||||||
{
|
// does not accept first clicks
|
||||||
// we are inside WinBorder
|
if (target != FocusWinBorder())
|
||||||
|
sendMessage = false;
|
||||||
|
else if (exFocus != FocusWinBorder()
|
||||||
|
&& !(target->WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK))
|
||||||
|
sendMessage = false;
|
||||||
|
|
||||||
|
if (sendMessage && fLastMouseMoved != target->fTopLayer) {
|
||||||
|
BMessage msg;
|
||||||
|
msg.what = B_MOUSE_DOWN;
|
||||||
|
msg.AddInt64("when", evt.when);
|
||||||
|
msg.AddPoint("where", evt.where);
|
||||||
|
msg.AddInt32("modifiers", evt.modifiers);
|
||||||
|
msg.AddInt32("buttons", evt.buttons);
|
||||||
|
msg.AddInt32("clicks", evt.clicks);
|
||||||
|
|
||||||
|
target->Window()->SendMessageToClient(&msg, fLastMouseMoved->fViewToken, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (target != FocusWinBorder())
|
if (fLastMouseMoved->EventMask() & B_POINTER_EVENTS) {
|
||||||
sendMessage = false;
|
fEventMaskLayer = fLastMouseMoved;
|
||||||
else if (exFocus != FocusWinBorder()
|
}
|
||||||
&& !(target->WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK))
|
break;
|
||||||
sendMessage = false;
|
|
||||||
|
|
||||||
if (sendMessage && fLastMouseMoved != target->fTopLayer)
|
|
||||||
{
|
|
||||||
BMessage msg;
|
|
||||||
msg.what = B_MOUSE_DOWN;
|
|
||||||
msg.AddInt64("when", evt.when);
|
|
||||||
msg.AddPoint("where", evt.where);
|
|
||||||
msg.AddInt32("modifiers", evt.modifiers);
|
|
||||||
msg.AddInt32("buttons", evt.buttons);
|
|
||||||
msg.AddInt32("clicks", evt.clicks);
|
|
||||||
|
|
||||||
target->Window()->SendMessageToClient(&msg, fLastMouseMoved->fViewToken, false);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (fLastMouseMoved->EventMask() & B_POINTER_EVENTS)
|
case DEC_DRAG:
|
||||||
{
|
case DEC_RESIZE:
|
||||||
fEventMaskLayer = fLastMouseMoved;
|
default:
|
||||||
|
// TODO: bring to front if not in FFM...
|
||||||
|
// now it is handled above
|
||||||
|
fMouseTargetWinBorder = target;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll need this so that GetMouse can query for which buttons
|
|
||||||
// are down.
|
|
||||||
fButtons=evt.buttons;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case B_MOUSE_UP:
|
case B_MOUSE_UP: {
|
||||||
{
|
//printf("RootLayer::MouseEventHandler(B_MOUSE_UP)\n");
|
||||||
// Attached data:
|
// Attached data:
|
||||||
// 1) int64 - time of mouse click
|
// 1) int64 - time of mouse click
|
||||||
// 2) float - x coordinate of mouse click
|
// 2) float - x coordinate of mouse click
|
||||||
@@ -1076,42 +1108,41 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
|||||||
msg.Read<float>(&evt.where.y);
|
msg.Read<float>(&evt.where.y);
|
||||||
msg.Read<int32>(&evt.modifiers);
|
msg.Read<int32>(&evt.modifiers);
|
||||||
|
|
||||||
if (fLastMousePossition != evt.where) {
|
if (fLastMouseMoved == NULL) {
|
||||||
|
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastMouseMoved is null!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fLastMousePosition != evt.where) {
|
||||||
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
|
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
|
||||||
// correctly trigger entered/exited view transits.
|
// correctly trigger entered/exited view transits.
|
||||||
fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!",
|
fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!\n",
|
||||||
evt.where.x, evt.where.y, fLastMousePossition.x, fLastMousePossition.y);
|
evt.where.x, evt.where.y, fLastMousePosition.x, fLastMousePosition.y);
|
||||||
// update on screen mouse pos
|
// update on screen mouse pos
|
||||||
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
||||||
fLastMousePossition = evt.where;
|
fLastMousePosition = evt.where;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what if 'fEventMaskLayer' is deleted in the mean time.
|
// TODO: what if 'fEventMaskLayer' is deleted in the mean time.
|
||||||
if (fEventMaskLayer)
|
if (fEventMaskLayer) {
|
||||||
{
|
|
||||||
// if this is a regular Layer, sent message to counterpart BView.
|
// if this is a regular Layer, sent message to counterpart BView.
|
||||||
if (fEventMaskLayer->fOwner)
|
if (fEventMaskLayer->fOwner) {
|
||||||
{
|
|
||||||
BMessage upmsg(B_MOUSE_UP);
|
BMessage upmsg(B_MOUSE_UP);
|
||||||
upmsg.AddInt64("when",evt.when);
|
upmsg.AddInt64("when",evt.when);
|
||||||
upmsg.AddPoint("where",evt.where);
|
upmsg.AddPoint("where",evt.where);
|
||||||
upmsg.AddInt32("modifiers",evt.modifiers);
|
upmsg.AddInt32("modifiers",evt.modifiers);
|
||||||
|
|
||||||
fEventMaskLayer->Window()->SendMessageToClient(&upmsg, fEventMaskLayer->fViewToken, false);
|
fEventMaskLayer->Window()->SendMessageToClient(&upmsg, fEventMaskLayer->fViewToken, false);
|
||||||
}
|
} else {
|
||||||
// this surely is a WinBorder
|
// this surely is a WinBorder
|
||||||
else
|
// TODO: This code is too confusing. There should be a clear separation.
|
||||||
{
|
// ((WinBorder*)fEventMaskLayer)->MouseUp(((WinBorder*)fEventMaskLayer)->TellWhat(evt));
|
||||||
((WinBorder*)fEventMaskLayer)->MouseUp(((WinBorder*)fEventMaskLayer)->TellWhat(evt));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fEventMaskLayer = NULL;
|
fEventMaskLayer = NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: focus may be NULL
|
// NOTE: focus may be NULL
|
||||||
if (fLastMouseMoved->Window() && fLastMouseMoved->fOwner == FocusWinBorder())
|
if (fLastMouseMoved->Window() && fLastMouseMoved->fOwner == FocusWinBorder()) {
|
||||||
{
|
|
||||||
// send B_MOUSE_UP for regular Layers/BViews
|
// send B_MOUSE_UP for regular Layers/BViews
|
||||||
BMessage upmsg(B_MOUSE_UP);
|
BMessage upmsg(B_MOUSE_UP);
|
||||||
upmsg.AddInt64("when",evt.when);
|
upmsg.AddInt64("when",evt.when);
|
||||||
@@ -1119,17 +1150,19 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
upmsg.AddInt32("modifiers",evt.modifiers);
|
upmsg.AddInt32("modifiers",evt.modifiers);
|
||||||
|
|
||||||
fLastMouseMoved->Window()->SendMessageToClient(&upmsg, fLastMouseMoved->fViewToken, false);
|
fLastMouseMoved->Window()->SendMessageToClient(&upmsg, fLastMouseMoved->fViewToken, false);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// WinBorders don't need _UP_ messages unless they received _DOWN_ messages,
|
// WinBorders don't need _UP_ messages unless they received _DOWN_ messages,
|
||||||
// and that case is threated above - WinBorders use Layer::fEventMask to
|
// and that case is threated above - WinBorders use Layer::fEventMask to
|
||||||
// capture the mouse.
|
// capture the mouse.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fMovingWindow = false;
|
// fMovingWindow = false;
|
||||||
fResizingWindow = false;
|
// fResizingWindow = false;
|
||||||
|
if (fMouseTargetWinBorder) {
|
||||||
|
fMouseTargetWinBorder->MouseUp(evt);
|
||||||
|
fMouseTargetWinBorder = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
|
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
|
||||||
|
|
||||||
@@ -1139,8 +1172,8 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case B_MOUSE_MOVED:
|
case B_MOUSE_MOVED: {
|
||||||
{
|
//printf("RootLayer::MouseEventHandler(B_MOUSE_MOVED)\n");
|
||||||
// Attached data:
|
// Attached data:
|
||||||
// 1) int64 - time of mouse click
|
// 1) int64 - time of mouse click
|
||||||
// 2) float - x coordinate of mouse click
|
// 2) float - x coordinate of mouse click
|
||||||
@@ -1156,12 +1189,26 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
|
|
||||||
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
||||||
|
|
||||||
|
fLastMousePosition = evt.where;
|
||||||
|
|
||||||
|
// NOTE: The mouse does NOT have to be over the fMouseTargetWinBorder for
|
||||||
|
// it to be still the valid target of the event. In fact, it is
|
||||||
|
// the only valid target until MOUSE_UP. So don't move this block farther
|
||||||
|
// down.
|
||||||
|
if (fMouseTargetWinBorder) {
|
||||||
|
fMouseTargetWinBorder->MouseMoved(evt);
|
||||||
|
fLastMouseMoved = fMouseTargetWinBorder;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: lock ServerWindow here! Don't forget, you need to add/remove Layers
|
// TODO: lock ServerWindow here! Don't forget, you need to add/remove Layers
|
||||||
// from within RootLayer's thread!!!
|
// from within RootLayer's thread!!!
|
||||||
Layer *target = LayerAt(evt.where);
|
Layer* target = LayerAt(evt.where);
|
||||||
if (target == NULL)
|
if (target == NULL) {
|
||||||
CRITICAL("RootLayer::MouseEventHandler: 'target' can't be null.\n");
|
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_MOVED) 'target' can't be null.\n");
|
||||||
WinBorder *winBorderUnder = NULL;
|
break;
|
||||||
|
}
|
||||||
|
WinBorder* winBorderUnder = NULL;
|
||||||
|
|
||||||
// TODO: I think that windows created without the B_ASYNCHRONOUS_CONTROLS flag
|
// TODO: I think that windows created without the B_ASYNCHRONOUS_CONTROLS flag
|
||||||
// don't receive B_MOUSE_MOVED events after a B_MOUSE_DOWN. Test.
|
// don't receive B_MOUSE_MOVED events after a B_MOUSE_DOWN. Test.
|
||||||
@@ -1169,53 +1216,40 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
// is very hard.
|
// is very hard.
|
||||||
|
|
||||||
// fEventMaskLayer is always != this
|
// fEventMaskLayer is always != this
|
||||||
if (fEventMaskLayer)
|
if (fEventMaskLayer) {
|
||||||
{
|
if (fEventMaskLayer == target) {
|
||||||
if (fEventMaskLayer == target)
|
|
||||||
{
|
|
||||||
if (target == fLastMouseMoved)
|
if (target == fLastMouseMoved)
|
||||||
{
|
|
||||||
fViewAction = B_INSIDE_VIEW;
|
fViewAction = B_INSIDE_VIEW;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
fViewAction = B_ENTERED_VIEW;
|
fViewAction = B_ENTERED_VIEW;
|
||||||
}
|
|
||||||
}
|
} else if (fEventMaskLayer == fLastMouseMoved) {
|
||||||
else if (fEventMaskLayer == fLastMouseMoved)
|
|
||||||
{
|
|
||||||
fViewAction = B_EXITED_VIEW;
|
fViewAction = B_EXITED_VIEW;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
fViewAction = B_OUTSIDE_VIEW;
|
fViewAction = B_OUTSIDE_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fEventMaskLayer->fOwner)
|
if (fEventMaskLayer->fOwner) {
|
||||||
{
|
|
||||||
// top layer does not have B_POINTER_EVENTS in its event mask
|
// top layer does not have B_POINTER_EVENTS in its event mask
|
||||||
BMessage movemsg(B_MOUSE_MOVED);
|
BMessage movemsg(B_MOUSE_MOVED);
|
||||||
movemsg.AddInt64("when",evt.when);
|
movemsg.AddInt64("when", evt.when);
|
||||||
movemsg.AddPoint("where",evt.where);
|
movemsg.AddPoint("where", evt.where);
|
||||||
movemsg.AddInt32("buttons",evt.buttons);
|
movemsg.AddInt32("buttons", evt.buttons);
|
||||||
movemsg.AddInt32("transit", fViewAction);
|
movemsg.AddInt32("transit", fViewAction);
|
||||||
|
|
||||||
fEventMaskLayer->Window()->SendMessageToClient(&movemsg, fEventMaskLayer->fViewToken, false);
|
fEventMaskLayer->Window()->SendMessageToClient(&movemsg, fEventMaskLayer->fViewToken, false);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
winBorderUnder = (WinBorder*)fEventMaskLayer;
|
winBorderUnder = (WinBorder*)fEventMaskLayer;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (fLastMouseMoved != target) {
|
||||||
{
|
|
||||||
if (fLastMouseMoved != target)
|
|
||||||
{
|
|
||||||
fViewAction = B_EXITED_VIEW;
|
fViewAction = B_EXITED_VIEW;
|
||||||
if (fLastMouseMoved->fOwner)
|
if (fLastMouseMoved->fOwner) {
|
||||||
{
|
if (fLastMouseMoved != fLastMouseMoved->fOwner->fTopLayer) {
|
||||||
if (fLastMouseMoved != fLastMouseMoved->fOwner->fTopLayer)
|
|
||||||
{
|
|
||||||
BMessage movemsg(B_MOUSE_MOVED);
|
BMessage movemsg(B_MOUSE_MOVED);
|
||||||
movemsg.AddInt64("when",evt.when);
|
movemsg.AddInt64("when",evt.when);
|
||||||
movemsg.AddPoint("where",evt.where);
|
movemsg.AddPoint("where",evt.where);
|
||||||
@@ -1223,21 +1257,16 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
movemsg.AddInt32("transit",fViewAction);
|
movemsg.AddInt32("transit",fViewAction);
|
||||||
fLastMouseMoved->Window()->SendMessageToClient(&movemsg, fLastMouseMoved->fViewToken, false);
|
fLastMouseMoved->Window()->SendMessageToClient(&movemsg, fLastMouseMoved->fViewToken, false);
|
||||||
}
|
}
|
||||||
}
|
}// else if (fLastMouseMoved != this)
|
||||||
else if (fLastMouseMoved != this)
|
// ((WinBorder*)fLastMouseMoved)->MouseMoved(DEC_NONE);
|
||||||
((WinBorder*)fLastMouseMoved)->MouseMoved(DEC_NONE);
|
|
||||||
|
|
||||||
fViewAction = B_ENTERED_VIEW;
|
fViewAction = B_ENTERED_VIEW;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
fViewAction = B_INSIDE_VIEW;
|
fViewAction = B_INSIDE_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->fOwner)
|
if (target->fOwner) {
|
||||||
{
|
if (target != target->fOwner->fTopLayer) {
|
||||||
if (target != target->fOwner->fTopLayer)
|
|
||||||
{
|
|
||||||
BMessage movemsg(B_MOUSE_MOVED);
|
BMessage movemsg(B_MOUSE_MOVED);
|
||||||
movemsg.AddInt64("when",evt.when);
|
movemsg.AddInt64("when",evt.when);
|
||||||
movemsg.AddPoint("where",evt.where);
|
movemsg.AddPoint("where",evt.where);
|
||||||
@@ -1245,16 +1274,14 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
movemsg.AddInt32("transit",fViewAction);
|
movemsg.AddInt32("transit",fViewAction);
|
||||||
target->Window()->SendMessageToClient(&movemsg, target->fViewToken, false);
|
target->Window()->SendMessageToClient(&movemsg, target->fViewToken, false);
|
||||||
}
|
}
|
||||||
}
|
} else if (target != this) {
|
||||||
else if (target != this)
|
|
||||||
{
|
|
||||||
winBorderUnder = (WinBorder*)target;
|
winBorderUnder = (WinBorder*)target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (winBorderUnder) {
|
/* if (winBorderUnder) {
|
||||||
|
|
||||||
BPoint delta = evt.where - fLastMousePossition;
|
BPoint delta = evt.where - fLastMousePosition;
|
||||||
|
|
||||||
if (fMovingWindow) {
|
if (fMovingWindow) {
|
||||||
|
|
||||||
@@ -1280,15 +1307,14 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
} else {
|
} else {
|
||||||
winBorderUnder->MouseMoved(winBorderUnder->TellWhat(evt));
|
winBorderUnder->MouseMoved(winBorderUnder->TellWhat(evt));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fLastMouseMoved = target;
|
fLastMouseMoved = target;
|
||||||
fLastMousePossition = evt.where;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case B_MOUSE_WHEEL_CHANGED:
|
case B_MOUSE_WHEEL_CHANGED: {
|
||||||
{
|
//printf("RootLayer::MouseEventHandler(B_MOUSE_WHEEL_CHANGED)\n");
|
||||||
// FEATURE: This is a tentative change: mouse wheel messages are always sent to the window
|
// FEATURE: This is a tentative change: mouse wheel messages are always sent to the window
|
||||||
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
||||||
// view has locked focus via SetMouseEventMask
|
// view has locked focus via SetMouseEventMask
|
||||||
@@ -1299,12 +1325,9 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
msg.Read<float>(&evt.wheel_delta_x);
|
msg.Read<float>(&evt.wheel_delta_x);
|
||||||
msg.Read<float>(&evt.wheel_delta_y);
|
msg.Read<float>(&evt.wheel_delta_y);
|
||||||
|
|
||||||
if (fLastMouseMoved != this)
|
if (fLastMouseMoved && fLastMouseMoved != this) {
|
||||||
{
|
if (fLastMouseMoved->fOwner) { // is a Layer object not a WinBorder one
|
||||||
if (fLastMouseMoved->fOwner) // is a Layer object not a WinBorder one
|
if (fLastMouseMoved->fOwner->fTopLayer != fLastMouseMoved) { // must not be the top_view's counterpart
|
||||||
{
|
|
||||||
if (fLastMouseMoved->fOwner->fTopLayer != fLastMouseMoved) // must not be the top_view's counterpart
|
|
||||||
{
|
|
||||||
BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED);
|
BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED);
|
||||||
wheelmsg.AddInt64("when", evt.when);
|
wheelmsg.AddInt64("when", evt.when);
|
||||||
wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x);
|
wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x);
|
||||||
@@ -1312,9 +1335,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
|
|
||||||
fLastMouseMoved->Window()->SendMessageToClient(&wheelmsg, fLastMouseMoved->fViewToken, false);
|
fLastMouseMoved->Window()->SendMessageToClient(&wheelmsg, fLastMouseMoved->fViewToken, false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: WinBorder::MouseWheel() should dissapear or get other params!
|
// TODO: WinBorder::MouseWheel() should dissapear or get other params!
|
||||||
// ((WinBorder*)fLastMouseMoved)->MouseWheel(...)
|
// ((WinBorder*)fLastMouseMoved)->MouseWheel(...)
|
||||||
}
|
}
|
||||||
@@ -1323,7 +1344,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
printf("\nDesktop::MouseEventHandler(): WARNING: unknown message\n\n");
|
printf("RootLayer::MouseEventHandler(): WARNING: unknown message\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1430,6 +1451,7 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg)
|
|||||||
{
|
{
|
||||||
fScreenShotIndex++;
|
fScreenShotIndex++;
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
entry.SetTo(filename);
|
||||||
}
|
}
|
||||||
fScreenShotIndex++;
|
fScreenShotIndex++;
|
||||||
GetDisplayDriver()->DumpToFile(filename);
|
GetDisplayDriver()->DumpToFile(filename);
|
||||||
@@ -1512,6 +1534,7 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg)
|
|||||||
{
|
{
|
||||||
fScreenShotIndex++;
|
fScreenShotIndex++;
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
entry.SetTo(filename);
|
||||||
}
|
}
|
||||||
fScreenShotIndex++;
|
fScreenShotIndex++;
|
||||||
|
|
||||||
@@ -1897,7 +1920,8 @@ void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
|
|||||||
{
|
{
|
||||||
if (fEventMaskLayer)
|
if (fEventMaskLayer)
|
||||||
{
|
{
|
||||||
WinBorder *wb = fEventMaskLayer->fOwner?
|
// TODO: What was this supposed to do?!?
|
||||||
|
/* WinBorder *wb = fEventMaskLayer->fOwner?
|
||||||
fEventMaskLayer->fOwner:
|
fEventMaskLayer->fOwner:
|
||||||
(WinBorder*)fEventMaskLayer;
|
(WinBorder*)fEventMaskLayer;
|
||||||
if (wb == fEventMaskLayer)
|
if (wb == fEventMaskLayer)
|
||||||
@@ -1905,7 +1929,7 @@ void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
|
|||||||
fMovingWindow = false;
|
fMovingWindow = false;
|
||||||
fResizingWindow = false;
|
fResizingWindow = false;
|
||||||
wb->MouseUp(DEC_NONE);
|
wb->MouseUp(DEC_NONE);
|
||||||
}
|
}*/
|
||||||
fEventMaskLayer = NULL;
|
fEventMaskLayer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1970,18 +1994,17 @@ bool RootLayer::get_workspace_windows()
|
|||||||
return aChange;
|
return aChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootLayer::draw_window_tab(WinBorder *exFocus)
|
void
|
||||||
|
RootLayer::draw_window_tab(WinBorder *exFocus)
|
||||||
{
|
{
|
||||||
WinBorder *focus = FocusWinBorder();
|
WinBorder *focus = FocusWinBorder();
|
||||||
if (exFocus || focus)
|
if (exFocus || focus) {
|
||||||
{
|
|
||||||
if (exFocus && exFocus != focus && exFocus->fDecorator)
|
if (exFocus && exFocus != focus && exFocus->fDecorator)
|
||||||
exFocus->fDecorator->SetFocus(false);
|
exFocus->fDecorator->SetFocus(false);
|
||||||
if (focus && exFocus != focus && focus->fDecorator)
|
if (focus && exFocus != focus && focus->fDecorator)
|
||||||
focus->fDecorator->SetFocus(true);
|
focus->fDecorator->SetFocus(true);
|
||||||
|
|
||||||
if (exFocus && focus != exFocus)
|
if (exFocus && focus != exFocus) {
|
||||||
{
|
|
||||||
// TODO: this line is a hack, decorator is drawn twice.
|
// TODO: this line is a hack, decorator is drawn twice.
|
||||||
BRegion reg(exFocus->fVisible);
|
BRegion reg(exFocus->fVisible);
|
||||||
if (focus)
|
if (focus)
|
||||||
@@ -1991,8 +2014,8 @@ void RootLayer::draw_window_tab(WinBorder *exFocus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline void
|
||||||
void RootLayer::empty_visible_regions(Layer *layer)
|
RootLayer::empty_visible_regions(Layer *layer)
|
||||||
{
|
{
|
||||||
// TODO: optimize by avoiding recursion?
|
// TODO: optimize by avoiding recursion?
|
||||||
// NOTE: first 'layer' must be a WinBorder
|
// NOTE: first 'layer' must be a WinBorder
|
||||||
@@ -2002,36 +2025,32 @@ void RootLayer::empty_visible_regions(Layer *layer)
|
|||||||
layer->fVisible.MakeEmpty();
|
layer->fVisible.MakeEmpty();
|
||||||
|
|
||||||
child = layer->VirtualBottomChild();
|
child = layer->VirtualBottomChild();
|
||||||
while(child)
|
while(child) {
|
||||||
{
|
|
||||||
empty_visible_regions(child);
|
empty_visible_regions(child);
|
||||||
child = layer->VirtualUpperSibling();
|
child = layer->VirtualUpperSibling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline void
|
||||||
void RootLayer::winborder_activation(WinBorder* exActive)
|
RootLayer::winborder_activation(WinBorder* exActive)
|
||||||
{
|
{
|
||||||
if (exActive && (FocusWinBorder() != exActive || FrontWinBorder() != exActive))
|
if (exActive && (FocusWinBorder() != exActive || FrontWinBorder() != exActive)) {
|
||||||
{
|
BMessage msg(B_WINDOW_ACTIVATED);
|
||||||
BMessage msg(B_WINDOW_ACTIVATED);
|
|
||||||
msg.AddBool("active", false);
|
msg.AddBool("active", false);
|
||||||
exActive->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
exActive->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||||
}
|
}
|
||||||
if (FocusWinBorder() == FrontWinBorder()
|
if (FocusWinBorder() == FrontWinBorder()
|
||||||
&& FrontWinBorder() != NULL && FrontWinBorder() != exActive)
|
&& FrontWinBorder() != NULL && FrontWinBorder() != exActive) {
|
||||||
{
|
BMessage msg(B_WINDOW_ACTIVATED);
|
||||||
BMessage msg(B_WINDOW_ACTIVATED);
|
|
||||||
msg.AddBool("active", true);
|
msg.AddBool("active", true);
|
||||||
FrontWinBorder()->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
FrontWinBorder()->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline void
|
||||||
void RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
||||||
{
|
{
|
||||||
if(fHaveWinBorderList || get_workspace_windows())
|
if (fHaveWinBorderList || get_workspace_windows()) {
|
||||||
{
|
|
||||||
// next call should call get_workspace_windows()
|
// next call should call get_workspace_windows()
|
||||||
fHaveWinBorderList = false;
|
fHaveWinBorderList = false;
|
||||||
// TODO: should it be improved by calling with region of hidden windows
|
// TODO: should it be improved by calling with region of hidden windows
|
||||||
@@ -2050,12 +2069,15 @@ void RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
|||||||
// the same mouse position with B_ENTERD_VIEW??? Same when changing workspaces!!!
|
// the same mouse position with B_ENTERD_VIEW??? Same when changing workspaces!!!
|
||||||
// INVESTIGATE, INVESTIGATE, INVESTIGATE!!!
|
// INVESTIGATE, INVESTIGATE, INVESTIGATE!!!
|
||||||
// NOTE: the following 3 lines are here for safety reasons!
|
// NOTE: the following 3 lines are here for safety reasons!
|
||||||
fLastMouseMoved = LayerAt(fLastMousePossition);
|
fLastMouseMoved = LayerAt(fLastMousePosition);
|
||||||
if (fLastMouseMoved == NULL)
|
if (fLastMouseMoved == NULL) {
|
||||||
CRITICAL("RootLayer::KeyboardEventHandler: 'fLastMouseMoved' can't be null.\n");
|
CRITICAL("RootLayer::show_final_scene: 'fLastMouseMoved' can't be null.\n");
|
||||||
|
fLastMouseMoved = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootLayer::Draw(const BRect &r)
|
void
|
||||||
|
RootLayer::Draw(const BRect &r)
|
||||||
{
|
{
|
||||||
fDriver->FillRect(r, fWorkspace[fActiveWksIndex]->BGColor());
|
fDriver->FillRect(r, fWorkspace[fActiveWksIndex]->BGColor());
|
||||||
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
|
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
|
||||||
|
|||||||
@@ -164,12 +164,15 @@ friend class Desktop;
|
|||||||
void MouseEventHandler(int32 code, BPortLink& link);
|
void MouseEventHandler(int32 code, BPortLink& link);
|
||||||
void KeyboardEventHandler(int32 code, BPortLink& link);
|
void KeyboardEventHandler(int32 code, BPortLink& link);
|
||||||
|
|
||||||
Desktop *fDesktop;
|
Desktop* fDesktop;
|
||||||
BMessage *fDragMessage;
|
BMessage* fDragMessage;
|
||||||
Layer *fLastMouseMoved;
|
Layer* fLastMouseMoved;
|
||||||
|
WinBorder* fMouseTargetWinBorder;
|
||||||
int32 fViewAction;
|
int32 fViewAction;
|
||||||
Layer *fEventMaskLayer;
|
Layer* fEventMaskLayer;
|
||||||
|
|
||||||
CursorManager fCursorManager;
|
CursorManager fCursorManager;
|
||||||
|
|
||||||
BLocker fAllRegionsLock;
|
BLocker fAllRegionsLock;
|
||||||
|
|
||||||
thread_id fThreadID;
|
thread_id fThreadID;
|
||||||
@@ -185,19 +188,20 @@ friend class Desktop;
|
|||||||
float fFrequency;
|
float fFrequency;
|
||||||
|
|
||||||
int32 fButtons;
|
int32 fButtons;
|
||||||
BPoint fLastMousePossition;
|
BPoint fLastMousePosition;
|
||||||
bool fMovingWindow;
|
bool fMovingWindow;
|
||||||
bool fResizingWindow;
|
bool fResizingWindow;
|
||||||
bool fHaveWinBorderList;
|
bool fHaveWinBorderList;
|
||||||
|
|
||||||
int32 fActiveWksIndex;
|
int32 fActiveWksIndex;
|
||||||
int32 fWsCount;
|
int32 fWsCount;
|
||||||
Workspace* fWorkspace[32];
|
Workspace** fWorkspace;
|
||||||
|
|
||||||
|
int32 fWinBorderListLength;
|
||||||
WinBorder** fWinBorderList2;
|
WinBorder** fWinBorderList2;
|
||||||
WinBorder** fWinBorderList;
|
WinBorder** fWinBorderList;
|
||||||
int32 fWinBorderCount;
|
int32 fWinBorderCount;
|
||||||
mutable int32 fWinBorderIndex;
|
mutable int32 fWinBorderIndex;
|
||||||
int32 fWinBorderListLength;
|
|
||||||
|
|
||||||
int32 fScreenShotIndex;
|
int32 fScreenShotIndex;
|
||||||
bool fQuiting;
|
bool fQuiting;
|
||||||
|
|||||||
@@ -1220,12 +1220,12 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
|||||||
replylink.Attach<float>(width);
|
replylink.Attach<float>(width);
|
||||||
replylink.Flush();
|
replylink.Flush();
|
||||||
|
|
||||||
free(string);
|
|
||||||
} else {
|
} else {
|
||||||
replylink.StartMessage(SERVER_FALSE);
|
replylink.StartMessage(SERVER_FALSE);
|
||||||
replylink.Flush();
|
replylink.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(string);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1875,6 +1875,84 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* case AS_GET_TRUNCATED_STRINGS:
|
||||||
|
{
|
||||||
|
// Attached data
|
||||||
|
|
||||||
|
// 1) uint16 family id
|
||||||
|
// 2) uint16 style id
|
||||||
|
// 3) float size
|
||||||
|
// 4) uint8 spacing
|
||||||
|
|
||||||
|
// 5) uint32 mode - B_TRUNCATE_END...
|
||||||
|
// 6) float width - desired width
|
||||||
|
// 7) int32 count - count of attached strings
|
||||||
|
// 8) strings
|
||||||
|
|
||||||
|
// Returns:
|
||||||
|
// 1) strings - as many strings as requested, all of "width" maximum width
|
||||||
|
|
||||||
|
// font attribs
|
||||||
|
uint16 family;
|
||||||
|
uint16 style;
|
||||||
|
float size;
|
||||||
|
uint8 spacing;
|
||||||
|
|
||||||
|
msg.Read<uint16>(&family);
|
||||||
|
msg.Read<uint16>(&style);
|
||||||
|
msg.Read<float>(&size);
|
||||||
|
msg.Read<uint8>(&spacing);
|
||||||
|
|
||||||
|
// params
|
||||||
|
uint32 mode;
|
||||||
|
float width;
|
||||||
|
int32 count;
|
||||||
|
|
||||||
|
msg.Read<uint32>(&mode);
|
||||||
|
msg.Read<float>(&width);
|
||||||
|
msg.Read<int32>(&count);
|
||||||
|
|
||||||
|
char** strings = NULL;
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
if (count > 0) {
|
||||||
|
strings = new char*[count];
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
msg.ReadString(&strings[i]);
|
||||||
|
}
|
||||||
|
// TODO: truncate strings here
|
||||||
|
ServerFont font;
|
||||||
|
if (font.SetFamilyAndStyle(family, style) >= B_OK) {
|
||||||
|
font.SetSize(size);
|
||||||
|
// TODO: implement: font.SetSpacing(spacing);
|
||||||
|
success = font.GetTruncatedStrings(strings, count, width, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 replyport;
|
||||||
|
msg.Read<int32>(&replyport);
|
||||||
|
|
||||||
|
replylink.SetSendPort(replyport);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
replylink.StartMessage(SERVER_TRUE);
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
replylink.AttachString(strings[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
replylink.StartMessage(SERVER_FALSE);
|
||||||
|
}
|
||||||
|
replylink.Flush();
|
||||||
|
|
||||||
|
// free used resources
|
||||||
|
if (count > 0) {
|
||||||
|
for (int32 i = 0; i < count; i++)
|
||||||
|
free(strings[i]);
|
||||||
|
}
|
||||||
|
delete[] strings;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
case AS_SCREEN_GET_MODE:
|
case AS_SCREEN_GET_MODE:
|
||||||
{
|
{
|
||||||
// Attached data
|
// Attached data
|
||||||
@@ -1944,12 +2022,20 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
|||||||
replylink.Flush();
|
replylink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
STRACE(("ServerApp %s received unhandled message code offset %s\n",fSignature.String(),
|
printf("ServerApp %s received unhandled message code offset %s\n", fSignature.String(),
|
||||||
MsgCodeToBString(code).String()));
|
MsgCodeToBString(code).String());
|
||||||
|
|
||||||
|
// TODO: completely broken. The reply port seems to be unkown!
|
||||||
|
// It is in the data, but the position is unkown. Man, I find
|
||||||
|
// this comm stuff really clumsy. -Stephan)
|
||||||
|
// And BTW: the client is now blocking and waiting for a reply!
|
||||||
|
/*replylink.SetSendPort(msg.GetPort());
|
||||||
|
replylink.StartMessage(SERVER_FALSE);
|
||||||
|
replylink.Flush();
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+173
-117
@@ -26,11 +26,13 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
#include <Shape.h>
|
#include <Shape.h>
|
||||||
|
#include <String.h>
|
||||||
#include <UTF8.h>
|
#include <UTF8.h>
|
||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
#include "FontServer.h"
|
#include "FontServer.h"
|
||||||
#include "moreUTF8.h"
|
#include "moreUTF8.h"
|
||||||
|
#include "truncate_string.h"
|
||||||
|
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
@@ -47,20 +49,22 @@
|
|||||||
\param flags Style flags as defined in <Font.h>
|
\param flags Style flags as defined in <Font.h>
|
||||||
\param spacing String spacing flag as defined in <Font.h>
|
\param spacing String spacing flag as defined in <Font.h>
|
||||||
*/
|
*/
|
||||||
ServerFont::ServerFont(FontStyle *style, float size, float rotation, float shear,
|
ServerFont::ServerFont(FontStyle *style, float size,
|
||||||
uint16 flags, uint8 spacing)
|
float rotation, float shear,
|
||||||
|
uint16 flags, uint8 spacing)
|
||||||
|
: fStyle(style),
|
||||||
|
fSize(size),
|
||||||
|
fRotation(rotation),
|
||||||
|
fShear(shear),
|
||||||
|
fBounds(0, 0, 0, 0),
|
||||||
|
fFlags(flags),
|
||||||
|
fSpacing(spacing),
|
||||||
|
fDirection(B_FONT_LEFT_TO_RIGHT),
|
||||||
|
fFace(B_REGULAR_FACE),
|
||||||
|
fEncoding(B_UNICODE_UTF8)
|
||||||
|
|
||||||
{
|
{
|
||||||
fStyle=style;
|
if (fStyle)
|
||||||
fSize=size;
|
|
||||||
fRotation=rotation;
|
|
||||||
fShear=shear;
|
|
||||||
fFlags=flags;
|
|
||||||
fSpacing=spacing;
|
|
||||||
fDirection=B_FONT_LEFT_TO_RIGHT;
|
|
||||||
fFace=B_REGULAR_FACE;
|
|
||||||
fEncoding=B_UNICODE_UTF8;
|
|
||||||
fBounds.Set(0,0,0,0);
|
|
||||||
if(fStyle)
|
|
||||||
fStyle->AddDependent();
|
fStyle->AddDependent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,18 +72,18 @@ ServerFont::ServerFont(FontStyle *style, float size, float rotation, float shear
|
|||||||
// constructor, that initializes without actually interfacing with
|
// constructor, that initializes without actually interfacing with
|
||||||
// freetype, so that a ServerFont can be guaranteed to be "valid".
|
// freetype, so that a ServerFont can be guaranteed to be "valid".
|
||||||
|
|
||||||
ServerFont::ServerFont(void)
|
ServerFont::ServerFont()
|
||||||
|
: fStyle(NULL),
|
||||||
|
fSize(0.0),
|
||||||
|
fRotation(0.0),
|
||||||
|
fShear(90.0),
|
||||||
|
fBounds(0, 0, 0, 0),
|
||||||
|
fFlags(0),
|
||||||
|
fSpacing(B_STRING_SPACING),
|
||||||
|
fDirection(B_FONT_LEFT_TO_RIGHT),
|
||||||
|
fFace(B_REGULAR_FACE),
|
||||||
|
fEncoding(B_UNICODE_UTF8)
|
||||||
{
|
{
|
||||||
fStyle=NULL;
|
|
||||||
fSize=0.0;
|
|
||||||
fRotation=0.0;
|
|
||||||
fShear=90.0;
|
|
||||||
fFlags=0;
|
|
||||||
fSpacing=B_STRING_SPACING;
|
|
||||||
fDirection=B_FONT_LEFT_TO_RIGHT;
|
|
||||||
fFace=B_REGULAR_FACE;
|
|
||||||
fEncoding=B_UNICODE_UTF8;
|
|
||||||
fBounds.Set(0,0,0,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -87,27 +91,27 @@ ServerFont::ServerFont(void)
|
|||||||
\param font ServerFont to copy
|
\param font ServerFont to copy
|
||||||
*/
|
*/
|
||||||
ServerFont::ServerFont(const ServerFont &font)
|
ServerFont::ServerFont(const ServerFont &font)
|
||||||
|
: fStyle(font.fStyle),
|
||||||
|
fSize(font.fSize),
|
||||||
|
fRotation(font.fRotation),
|
||||||
|
fShear(font.fShear),
|
||||||
|
fBounds(0, 0, 0, 0),
|
||||||
|
fFlags(font.fFlags),
|
||||||
|
fSpacing(font.fSpacing),
|
||||||
|
fDirection(font.fDirection),
|
||||||
|
fFace(font.fFace),
|
||||||
|
fEncoding(font.fEncoding)
|
||||||
{
|
{
|
||||||
fStyle=font.fStyle;
|
if (fStyle)
|
||||||
fSize=font.fSize;
|
|
||||||
fRotation=font.fRotation;
|
|
||||||
fShear=font.fShear;
|
|
||||||
fFlags=font.fFlags;
|
|
||||||
fSpacing=font.fSpacing;
|
|
||||||
fDirection=font.fDirection;
|
|
||||||
fFace=font.fFace;
|
|
||||||
fEncoding=font.fEncoding;
|
|
||||||
fBounds.Set(0,0,0,0);
|
|
||||||
if(fStyle)
|
|
||||||
fStyle->AddDependent();
|
fStyle->AddDependent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Removes itself as a dependency of its owning style.
|
\brief Removes itself as a dependency of its owning style.
|
||||||
*/
|
*/
|
||||||
ServerFont::~ServerFont(void)
|
ServerFont::~ServerFont()
|
||||||
{
|
{
|
||||||
if(fStyle)
|
if (fStyle)
|
||||||
fStyle->RemoveDependent();
|
fStyle->RemoveDependent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +120,21 @@ ServerFont::~ServerFont(void)
|
|||||||
\param The font to copy from.
|
\param The font to copy from.
|
||||||
\return A copy of the specified font
|
\return A copy of the specified font
|
||||||
*/
|
*/
|
||||||
ServerFont& ServerFont::operator=(const ServerFont& font){
|
ServerFont&
|
||||||
fStyle = font.fStyle;
|
ServerFont::operator=(const ServerFont& font)
|
||||||
|
{
|
||||||
fSize = font.fSize;
|
fSize = font.fSize;
|
||||||
fRotation = font.fRotation;
|
fRotation = font.fRotation;
|
||||||
fShear = font.fShear;
|
fShear = font.fShear;
|
||||||
fFlags = font.fFlags;
|
fFlags = font.fFlags;
|
||||||
fSpacing = font.fSpacing;
|
fSpacing = font.fSpacing;
|
||||||
fDirection = B_FONT_LEFT_TO_RIGHT;
|
fDirection = font.fDirection;
|
||||||
fFace = B_REGULAR_FACE;
|
fFace = font.fFace;
|
||||||
fEncoding = B_UNICODE_UTF8;
|
fEncoding = font.fEncoding;
|
||||||
fBounds.Set(0,0,0,0);
|
fBounds = font.fBounds;
|
||||||
if(fStyle)
|
|
||||||
fStyle->AddDependent();
|
_SetStyle(font.fStyle);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,10 +142,11 @@ ServerFont& ServerFont::operator=(const ServerFont& font){
|
|||||||
\brief Returns the number of strikes in the font
|
\brief Returns the number of strikes in the font
|
||||||
\return The number of strikes in the font
|
\return The number of strikes in the font
|
||||||
*/
|
*/
|
||||||
int32 ServerFont::CountTuned(void)
|
int32
|
||||||
|
ServerFont::CountTuned()
|
||||||
{
|
{
|
||||||
if(fStyle)
|
if (fStyle)
|
||||||
fStyle->TunedCount();
|
return fStyle->TunedCount();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -148,42 +155,77 @@ int32 ServerFont::CountTuned(void)
|
|||||||
\brief Returns the file format of the font. Currently unimplemented.
|
\brief Returns the file format of the font. Currently unimplemented.
|
||||||
\return B_TRUETYPE_WINDOWS
|
\return B_TRUETYPE_WINDOWS
|
||||||
*/
|
*/
|
||||||
font_file_format ServerFont::FileFormat(void)
|
font_file_format
|
||||||
|
ServerFont::FileFormat()
|
||||||
{
|
{
|
||||||
// TODO: implement ServerFont::FileFormat
|
// TODO: implement ServerFont::FileFormat
|
||||||
return B_TRUETYPE_WINDOWS;
|
return B_TRUETYPE_WINDOWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
const char*
|
||||||
\brief Returns a BRect which encloses the entire font
|
ServerFont::GetStyle() const
|
||||||
\return A BRect which encloses the entire font
|
{
|
||||||
|
if (fStyle)
|
||||||
|
return fStyle->Name();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
ServerFont::GetFamily() const
|
||||||
|
{
|
||||||
|
if (fStyle)
|
||||||
|
return fStyle->Family()->Name();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Sets the ServerFont instance to whatever font is specified
|
||||||
|
\param familyID ID number of the family to set
|
||||||
|
\param styleID ID number of the style to set
|
||||||
|
\return B_OK if successful, B_ERROR if not
|
||||||
*/
|
*/
|
||||||
BRect ServerFont::BoundingBox(void)
|
status_t
|
||||||
|
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
||||||
{
|
{
|
||||||
return fBounds;
|
FontStyle* style = NULL;
|
||||||
|
|
||||||
|
if (fontserver->Lock()) {
|
||||||
|
style = fontserver->GetStyle(familyID, styleID);
|
||||||
|
fontserver->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!style)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
_SetStyle(style);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ServerFont::GetStyle(void) const
|
/*!
|
||||||
{
|
\brief Sets the ServerFont instance to whatever font is specified
|
||||||
return fStyle->Name();
|
\param fontID the combination of family and style ID numbers
|
||||||
}
|
\return B_OK if successful, B_ERROR if not
|
||||||
|
|
||||||
const char *ServerFont::GetFamily(void) const
|
|
||||||
{
|
|
||||||
return fStyle->Family()->Name();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Obtains the height values for characters in the font in its current state
|
|
||||||
\param fh pointer to a font_height object to receive the values for the font
|
|
||||||
*/
|
*/
|
||||||
void ServerFont::Height(font_height *fh)
|
status_t
|
||||||
|
ServerFont::SetFamilyAndStyle(uint32 fontID)
|
||||||
{
|
{
|
||||||
if(!fh)
|
uint16 style = fontID & 0xFFFF;
|
||||||
return;
|
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
||||||
|
|
||||||
if(fStyle)
|
return SetFamilyAndStyle(family, style);
|
||||||
*fh=fStyle->GetHeight(fSize);
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Gets the ID values for the ServerFont instance in one shot
|
||||||
|
\return the combination of family and style ID numbers
|
||||||
|
*/
|
||||||
|
uint32
|
||||||
|
ServerFont::GetFamilyAndStyle(void) const
|
||||||
|
{
|
||||||
|
return (FamilyID() << 16) | StyleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// functions needed to convert a freetype vector graphics to a BShape
|
// functions needed to convert a freetype vector graphics to a BShape
|
||||||
@@ -295,7 +337,7 @@ BPoint*
|
|||||||
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
||||||
BPoint offsetArray[]) const
|
BPoint offsetArray[]) const
|
||||||
{
|
{
|
||||||
if (!charArray || numChars <= 0 || !offsetArray)
|
if (!fStyle || !charArray || numChars <= 0 || !offsetArray)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
FT_Face face = fStyle->GetFTFace();
|
FT_Face face = fStyle->GetFTFace();
|
||||||
@@ -349,7 +391,7 @@ inline bool
|
|||||||
is_white_space(uint16 glyph)
|
is_white_space(uint16 glyph)
|
||||||
{
|
{
|
||||||
// TODO: handle them all!
|
// TODO: handle them all!
|
||||||
if (glyph == ' ')
|
if (glyph == ' ' || glyph == B_TAB)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -359,7 +401,7 @@ bool
|
|||||||
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
||||||
float widthArray[], escapement_delta delta) const
|
float widthArray[], escapement_delta delta) const
|
||||||
{
|
{
|
||||||
if (!charArray || numChars <= 0)
|
if (!fStyle || !charArray || numChars <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FT_Face face = fStyle->GetFTFace();
|
FT_Face face = fStyle->GetFTFace();
|
||||||
@@ -404,7 +446,7 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
|||||||
float
|
float
|
||||||
ServerFont::StringWidth(const char* string, int32 numBytes) const
|
ServerFont::StringWidth(const char* string, int32 numBytes) const
|
||||||
{
|
{
|
||||||
if (!string || numBytes <= 0)
|
if (!fStyle || !string || numBytes <= 0)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
FT_Face face = fStyle->GetFTFace();
|
FT_Face face = fStyle->GetFTFace();
|
||||||
@@ -439,55 +481,69 @@ ServerFont::StringWidth(const char* string, int32 numBytes) const
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets the ServerFont instance to whatever font is specified
|
\brief Returns a BRect which encloses the entire font
|
||||||
\param familyID ID number of the family to set
|
\return A BRect which encloses the entire font
|
||||||
\param styleID ID number of the style to set
|
|
||||||
\return B_OK if successful, B_ERROR if not
|
|
||||||
*/
|
*/
|
||||||
status_t ServerFont::SetFamilyAndStyle(const uint16 &familyID,const uint16 &styleID)
|
BRect
|
||||||
|
ServerFont::BoundingBox()
|
||||||
{
|
{
|
||||||
fontserver->Lock();
|
// TODO: fBounds is nowhere calculated!
|
||||||
FontStyle *sty=fontserver->GetStyle(familyID,styleID);
|
return fBounds;
|
||||||
fontserver->Unlock();
|
|
||||||
if(!sty)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fStyle=sty;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets the ServerFont instance to whatever font is specified
|
\brief Obtains the height values for characters in the font in its current state
|
||||||
\param fontID the combination of family and style ID numbers
|
\param fh pointer to a font_height object to receive the values for the font
|
||||||
\return B_OK if successful, B_ERROR if not
|
|
||||||
*/
|
*/
|
||||||
status_t ServerFont::SetFamilyAndStyle(const uint32 &fontID)
|
void
|
||||||
|
ServerFont::Height(font_height *fh) const
|
||||||
{
|
{
|
||||||
uint16 style = fontID & 0xFFFF;
|
if (fh && fStyle)
|
||||||
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
*fh = fStyle->GetHeight(fSize);
|
||||||
|
|
||||||
fontserver->Lock();
|
|
||||||
FontStyle *sty=fontserver->GetStyle(family,style);
|
|
||||||
fontserver->Unlock();
|
|
||||||
if(!sty)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fStyle=sty;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
// TruncateString
|
||||||
\brief Gets the ID values for the ServerFont instance in one shot
|
void
|
||||||
\return the combination of family and style ID numbers
|
ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
||||||
*/
|
|
||||||
uint32 ServerFont::GetFamilyAndStyle(void) const
|
|
||||||
{
|
{
|
||||||
uint32 famsty=0;
|
if (inOut) {
|
||||||
|
// the width of the "…" glyph
|
||||||
famsty|=FamilyID() << 16;
|
float ellipsisWidth = StringWidth(B_UTF8_ELLIPSIS, 3);
|
||||||
famsty|=StyleID();
|
const char* string = inOut->String();
|
||||||
|
int32 length = strlen(string);
|
||||||
return famsty;
|
// temporary array to hold result
|
||||||
|
char* result = new char[length + 3];
|
||||||
|
// count the individual glyphs
|
||||||
|
int32 numChars = UTF8CountChars(string, length);
|
||||||
|
// get the escapement of each glyph in font units
|
||||||
|
float* escapementArray = new float[numChars];
|
||||||
|
static escapement_delta delta = (escapement_delta){ 0.0, 0.0 };
|
||||||
|
GetEscapements(string, numChars, escapementArray, delta);
|
||||||
|
|
||||||
|
truncate_string(string, mode, width, result,
|
||||||
|
escapementArray, fSize, ellipsisWidth, length, numChars);
|
||||||
|
|
||||||
|
inOut->SetTo(result);
|
||||||
|
|
||||||
|
delete[] escapementArray;
|
||||||
|
delete[] result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _SetStyle
|
||||||
|
void
|
||||||
|
ServerFont::_SetStyle(FontStyle* style)
|
||||||
|
{
|
||||||
|
if (style != fStyle) {
|
||||||
|
// detach from old style
|
||||||
|
if (fStyle)
|
||||||
|
fStyle->RemoveDependent();
|
||||||
|
|
||||||
|
fStyle = style;
|
||||||
|
|
||||||
|
// attach to new style
|
||||||
|
if (fStyle)
|
||||||
|
fStyle->AddDependent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// File Name: ServerWindow.cpp
|
// File Name: ServerWindow.cpp
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
// Adi Oanca <[email protected]>
|
// Adi Oanca <[email protected]>
|
||||||
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Shadow BWindow class
|
// Description: Shadow BWindow class
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -74,7 +75,6 @@
|
|||||||
# define DTRACE(x) ;
|
# define DTRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -230,7 +230,7 @@ ServerWindow::Minimize(bool status)
|
|||||||
|
|
||||||
//! Sends a message to the client to perform a Zoom
|
//! Sends a message to the client to perform a Zoom
|
||||||
void
|
void
|
||||||
ServerWindow::Zoom(void)
|
ServerWindow::Zoom()
|
||||||
{
|
{
|
||||||
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
||||||
BMessage msg(B_ZOOM);
|
BMessage msg(B_ZOOM);
|
||||||
@@ -259,7 +259,7 @@ ServerWindow::ScreenModeChanged(const BRect frame, const color_space colorSpace)
|
|||||||
\return B_OK if everything is ok, B_ERROR if something went wrong
|
\return B_OK if everything is ok, B_ERROR if something went wrong
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
ServerWindow::Lock(void)
|
ServerWindow::Lock()
|
||||||
{
|
{
|
||||||
STRACE(("\nServerWindow %s: Lock\n", fName));
|
STRACE(("\nServerWindow %s: Lock\n", fName));
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ ServerWindow::Lock(void)
|
|||||||
|
|
||||||
//! Unlocks the window
|
//! Unlocks the window
|
||||||
void
|
void
|
||||||
ServerWindow::Unlock(void)
|
ServerWindow::Unlock()
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow %s: Unlock\n\n", fName));
|
STRACE(("ServerWindow %s: Unlock\n\n", fName));
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ ServerWindow::Unlock(void)
|
|||||||
\return True if locked, false if not.
|
\return True if locked, false if not.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
ServerWindow::IsLocked(void) const
|
ServerWindow::IsLocked() const
|
||||||
{
|
{
|
||||||
return fLocker.IsLocked();
|
return fLocker.IsLocked();
|
||||||
}
|
}
|
||||||
@@ -289,8 +289,7 @@ ServerWindow::IsLocked(void) const
|
|||||||
\brief Sets the font state for a layer
|
\brief Sets the font state for a layer
|
||||||
\param layer The layer to set the font
|
\param layer The layer to set the font
|
||||||
*/
|
*/
|
||||||
inline
|
inline void
|
||||||
void
|
|
||||||
ServerWindow::SetLayerFontState(Layer *layer, LinkMsgReader &link)
|
ServerWindow::SetLayerFontState(Layer *layer, LinkMsgReader &link)
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow %s: SetLayerFontStateMessage for layer %s\n",
|
STRACE(("ServerWindow %s: SetLayerFontStateMessage for layer %s\n",
|
||||||
@@ -301,8 +300,7 @@ ServerWindow::SetLayerFontState(Layer *layer, LinkMsgReader &link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline void
|
||||||
void
|
|
||||||
ServerWindow::SetLayerState(Layer *layer, LinkMsgReader &link)
|
ServerWindow::SetLayerState(Layer *layer, LinkMsgReader &link)
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow %s: SetLayerState for layer %s\n",fName,
|
STRACE(("ServerWindow %s: SetLayerState for layer %s\n",fName,
|
||||||
@@ -314,8 +312,7 @@ ServerWindow::SetLayerState(Layer *layer, LinkMsgReader &link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline Layer*
|
||||||
Layer *
|
|
||||||
ServerWindow::CreateLayerTree(Layer *localRoot, LinkMsgReader &link)
|
ServerWindow::CreateLayerTree(Layer *localRoot, LinkMsgReader &link)
|
||||||
{
|
{
|
||||||
// NOTE: no need to check for a lock. This is a private method.
|
// NOTE: no need to check for a lock. This is a private method.
|
||||||
@@ -991,8 +988,11 @@ ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
|||||||
link.Read<BRect>(&invalRect);
|
link.Read<BRect>(&invalRect);
|
||||||
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
|
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
|
||||||
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
|
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
|
||||||
|
BRegion invalidRegion(converted);
|
||||||
|
// invalidRegion.IntersectWith(&fCurrentLayer->fVisible);
|
||||||
|
|
||||||
myRootLayer->GoRedraw(fWinBorder, BRegion(converted));
|
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||||
|
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_LAYER_INVAL_REGION:
|
case AS_LAYER_INVAL_REGION:
|
||||||
@@ -1236,17 +1236,29 @@ ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
|||||||
// 3) float minimum height
|
// 3) float minimum height
|
||||||
// 4) float maximum height
|
// 4) float maximum height
|
||||||
|
|
||||||
float wmin,wmax,hmin,hmax;
|
float minWidth;
|
||||||
|
float maxWidth;
|
||||||
|
float minHeight;
|
||||||
|
float maxHeight;
|
||||||
|
|
||||||
link.Read<float>(&wmin);
|
link.Read<float>(&minWidth);
|
||||||
link.Read<float>(&wmax);
|
link.Read<float>(&maxWidth);
|
||||||
link.Read<float>(&hmin);
|
link.Read<float>(&minHeight);
|
||||||
link.Read<float>(&hmax);
|
link.Read<float>(&maxHeight);
|
||||||
|
|
||||||
fWinBorder->SetSizeLimits(wmin,wmax,hmin,hmax);
|
|
||||||
|
|
||||||
|
fWinBorder->SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
|
||||||
|
|
||||||
|
// and now, sync the client to the limits that we were able to enforce
|
||||||
|
fWinBorder->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
|
||||||
|
|
||||||
fMsgSender->StartMessage(SERVER_TRUE);
|
fMsgSender->StartMessage(SERVER_TRUE);
|
||||||
|
fMsgSender->Attach<float>(minWidth);
|
||||||
|
fMsgSender->Attach<float>(maxWidth);
|
||||||
|
fMsgSender->Attach<float>(minHeight);
|
||||||
|
fMsgSender->Attach<float>(maxHeight);
|
||||||
|
|
||||||
fMsgSender->Flush();
|
fMsgSender->Flush();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case B_MINIMIZE:
|
case B_MINIMIZE:
|
||||||
@@ -2061,7 +2073,8 @@ ServerWindow::_CopyBits(RootLayer* rootLayer, Layer* layer,
|
|||||||
layer->GetDisplayDriver()->CopyRegion(©Region, xOffset, yOffset);
|
layer->GetDisplayDriver()->CopyRegion(©Region, xOffset, yOffset);
|
||||||
|
|
||||||
// trigger the redraw
|
// trigger the redraw
|
||||||
rootLayer->GoRedraw(fWinBorder, invalidRegion);
|
// rootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||||
|
rootLayer->RequestDraw(invalidRegion, fWinBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+310
-182
@@ -22,27 +22,31 @@
|
|||||||
// File Name: WinBorder.cpp
|
// File Name: WinBorder.cpp
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
// Adi Oanca <[email protected]>
|
// Adi Oanca <[email protected]>
|
||||||
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Layer subclass which handles window management
|
// Description: Layer subclass which handles window management
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
#include <Locker.h>
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Locker.h>
|
#include <View.h> // for mouse button defines
|
||||||
|
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include "PortLink.h"
|
#include "DebugInfoManager.h"
|
||||||
#include "View.h" // for mouse button defines
|
|
||||||
#include "MessagePrivate.h"
|
|
||||||
#include "ServerWindow.h"
|
|
||||||
#include "Decorator.h"
|
|
||||||
#include "DisplayDriver.h"
|
|
||||||
#include "Desktop.h"
|
|
||||||
#include "WinBorder.h"
|
|
||||||
#include "AppServer.h" // for new_decorator()
|
#include "AppServer.h" // for new_decorator()
|
||||||
#include "TokenHandler.h"
|
#include "Decorator.h"
|
||||||
|
#include "Desktop.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "MessagePrivate.h"
|
||||||
|
#include "PortLink.h"
|
||||||
#include "RootLayer.h"
|
#include "RootLayer.h"
|
||||||
|
#include "ServerWindow.h"
|
||||||
|
#include "TokenHandler.h"
|
||||||
#include "Workspace.h"
|
#include "Workspace.h"
|
||||||
|
|
||||||
|
#include "WinBorder.h"
|
||||||
|
|
||||||
// Toggle general function call output
|
// Toggle general function call output
|
||||||
//#define DEBUG_WINBORDER
|
//#define DEBUG_WINBORDER
|
||||||
|
|
||||||
@@ -71,80 +75,89 @@
|
|||||||
# define STRACE_CLICK(x) ;
|
# define STRACE_CLICK(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! TokenHandler object used to provide IDs for all WinBorder objects
|
WinBorder::WinBorder(const BRect &r,
|
||||||
TokenHandler border_token_handler;
|
const char *name,
|
||||||
|
const uint32 wlook,
|
||||||
bool gMouseDown = false;
|
const uint32 wfeel,
|
||||||
|
const uint32 wflags,
|
||||||
|
const uint32 wwksindex,
|
||||||
WinBorder::WinBorder( const BRect &r,
|
ServerWindow *win,
|
||||||
const char *name,
|
DisplayDriver *driver)
|
||||||
const uint32 wlook,
|
|
||||||
const uint32 wfeel,
|
|
||||||
const uint32 wflags,
|
|
||||||
const uint32 wwksindex,
|
|
||||||
ServerWindow *win,
|
|
||||||
DisplayDriver *driver)
|
|
||||||
: Layer(r, name, B_NULL_TOKEN, B_FOLLOW_NONE, 0UL, driver),
|
: Layer(r, name, B_NULL_TOKEN, B_FOLLOW_NONE, 0UL, driver),
|
||||||
fLook(wlook),
|
fDecorator(NULL),
|
||||||
fLevel(-100),
|
fTopLayer(NULL),
|
||||||
fWindowFlags(wflags),
|
|
||||||
fWorkspaces(wwksindex)
|
zUpdateReg(),
|
||||||
|
yUpdateReg(),
|
||||||
|
fUpdateReg(),
|
||||||
|
|
||||||
|
fMouseButtons(0),
|
||||||
|
fKeyModifiers(0),
|
||||||
|
fLastMousePosition(-1.0, -1.0),
|
||||||
|
|
||||||
|
fIsClosing(false),
|
||||||
|
fIsMinimizing(false),
|
||||||
|
fIsZooming(false),
|
||||||
|
|
||||||
|
fIsDragging(false),
|
||||||
|
fBringToFrontOnRelease(false),
|
||||||
|
|
||||||
|
fIsResizing(false),
|
||||||
|
|
||||||
|
fInUpdate(false),
|
||||||
|
fRequestSent(false),
|
||||||
|
|
||||||
|
fLook(wlook),
|
||||||
|
fFeel(-1),
|
||||||
|
fLevel(-100),
|
||||||
|
fWindowFlags(wflags),
|
||||||
|
fWorkspaces(wwksindex),
|
||||||
|
|
||||||
|
fMinWidth(1.0),
|
||||||
|
fMaxWidth(10000.0),
|
||||||
|
fMinHeight(1.0),
|
||||||
|
fMaxHeight(10000.0),
|
||||||
|
|
||||||
|
cnt(0) // for debugging
|
||||||
{
|
{
|
||||||
// unlike BViews, windows start off as hidden
|
// unlike BViews, windows start off as hidden
|
||||||
fHidden = true;
|
fHidden = true;
|
||||||
fInUpdate = false;
|
|
||||||
fRequestSent = false;
|
|
||||||
fServerWin = win;
|
fServerWin = win;
|
||||||
fClassID = AS_WINBORDER_CLASS;
|
fClassID = AS_WINBORDER_CLASS;
|
||||||
cnt = 0; // for debugging
|
|
||||||
fMouseButtons = 0;
|
|
||||||
fKeyModifiers = 0;
|
|
||||||
fDecorator = NULL;
|
|
||||||
fTopLayer = NULL;
|
|
||||||
fAdFlags = fAdFlags | B_LAYER_CHILDREN_DEPENDANT;
|
fAdFlags = fAdFlags | B_LAYER_CHILDREN_DEPENDANT;
|
||||||
fFlags = B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE;
|
fFlags = B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE;
|
||||||
fEventMask = B_POINTER_EVENTS;
|
fEventMask = B_POINTER_EVENTS;
|
||||||
|
|
||||||
fIsClosing = false;
|
|
||||||
fIsMinimizing = false;
|
|
||||||
fIsZooming = false;
|
|
||||||
|
|
||||||
fLastMousePosition.Set(-1,-1);
|
|
||||||
QuietlySetFeel(wfeel);
|
QuietlySetFeel(wfeel);
|
||||||
|
|
||||||
if (fFeel != B_NO_BORDER_WINDOW_LOOK)
|
if (fFeel != B_NO_BORDER_WINDOW_LOOK) {
|
||||||
fDecorator = new_decorator(r, name, fLook, fFeel, fWindowFlags, fDriver);
|
fDecorator = new_decorator(r, name, fLook, fFeel, fWindowFlags, fDriver);
|
||||||
|
if (fDecorator)
|
||||||
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
RebuildFullRegion();
|
RebuildFullRegion();
|
||||||
|
|
||||||
gDesktop->AddWinBorder(this);
|
gDesktop->AddWinBorder(this);
|
||||||
|
|
||||||
STRACE(("WinBorder %s:\n",GetName()));
|
STRACE(("WinBorder %s:\n", GetName()));
|
||||||
STRACE(("\tFrame: (%.1f,%.1f,%.1f,%.1f)\n",r.left,r.top,r.right,r.bottom));
|
STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", r.left, r.top, r.right, r.bottom));
|
||||||
STRACE(("\tWindow %s\n",win?win->Title():"NULL"));
|
STRACE(("\tWindow %s\n",win ? win->Title() : "NULL"));
|
||||||
}
|
}
|
||||||
|
|
||||||
WinBorder::~WinBorder(void)
|
WinBorder::~WinBorder()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder(%s)::~WinBorder()\n",GetName()));
|
STRACE(("WinBorder(%s)::~WinBorder()\n",GetName()));
|
||||||
|
|
||||||
gDesktop->RemoveWinBorder(this);
|
gDesktop->RemoveWinBorder(this);
|
||||||
|
|
||||||
if (fTopLayer){
|
delete fTopLayer;
|
||||||
delete fTopLayer;
|
delete fDecorator;
|
||||||
fTopLayer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fDecorator)
|
|
||||||
{
|
|
||||||
delete fDecorator;
|
|
||||||
fDecorator = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator
|
//! Rebuilds the WinBorder's "fully-visible" region based on info from the decorator
|
||||||
void WinBorder::RebuildFullRegion(void)
|
void
|
||||||
|
WinBorder::RebuildFullRegion()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName()));
|
STRACE(("WinBorder(%s)::RebuildFullRegion()\n",GetName()));
|
||||||
|
|
||||||
@@ -155,16 +168,6 @@ void WinBorder::RebuildFullRegion(void)
|
|||||||
fDecorator->GetFootprint(&fFull);
|
fDecorator->GetFootprint(&fFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
click_type WinBorder::TellWhat(PointerEvent& evt) const
|
|
||||||
{
|
|
||||||
if (fTopLayer->fFullVisible.Contains(evt.where))
|
|
||||||
return DEC_NONE;
|
|
||||||
else if (fDecorator)
|
|
||||||
return fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers);
|
|
||||||
else
|
|
||||||
return DEC_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Handles B_MOUSE_DOWN events and takes appropriate actions
|
\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 evt PointerEvent object containing the info from the last B_MOUSE_DOWN message
|
||||||
@@ -174,41 +177,51 @@ click_type WinBorder::TellWhat(PointerEvent& evt) const
|
|||||||
or frame. If it is not, the message is passed on to the appropriate view in the client
|
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.
|
BWindow. If the WinBorder is the target, then the proper action flag is set.
|
||||||
*/
|
*/
|
||||||
void WinBorder::MouseDown(click_type action)
|
click_type
|
||||||
|
WinBorder::MouseDown(const PointerEvent& event)
|
||||||
{
|
{
|
||||||
// find out where user clicked in Decorator
|
click_type action = _ActionFor(event);
|
||||||
switch(action)
|
|
||||||
{
|
if (fDecorator) {
|
||||||
case DEC_CLOSE:
|
// find out where user clicked in Decorator
|
||||||
{
|
switch(action) {
|
||||||
fIsClosing = true;
|
case DEC_CLOSE:
|
||||||
fDecorator->SetClose(true);
|
fIsClosing = true;
|
||||||
fDecorator->DrawClose();
|
fDecorator->SetClose(true);
|
||||||
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case DEC_ZOOM:
|
case DEC_ZOOM:
|
||||||
{
|
fIsZooming = true;
|
||||||
fIsZooming = true;
|
fDecorator->SetZoom(true);
|
||||||
fDecorator->SetZoom(true);
|
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
||||||
fDecorator->DrawZoom();
|
break;
|
||||||
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
|
||||||
break;
|
case DEC_MINIMIZE:
|
||||||
}
|
fIsMinimizing = true;
|
||||||
case DEC_MINIMIZE:
|
fDecorator->SetMinimize(true);
|
||||||
{
|
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
||||||
fIsMinimizing = true;
|
break;
|
||||||
fDecorator->SetMinimize(true);
|
|
||||||
fDecorator->DrawMinimize();
|
case DEC_DRAG:
|
||||||
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
fIsDragging = true;
|
||||||
break;
|
fBringToFrontOnRelease = true;
|
||||||
}
|
fLastMousePosition = event.where;
|
||||||
default:
|
STRACE_CLICK(("===> DEC_DRAG\n"));
|
||||||
{
|
break;
|
||||||
debugger("WinBorder::MouseDown - default case - not allowed!\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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -219,25 +232,32 @@ void WinBorder::MouseDown(click_type action)
|
|||||||
or check to see if the user clicked on a tab button (close, zoom, etc.) and then moused
|
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
|
away to prevent the operation from occurring
|
||||||
*/
|
*/
|
||||||
void WinBorder::MouseMoved(click_type action)
|
void
|
||||||
|
WinBorder::MouseMoved(const PointerEvent& event)
|
||||||
{
|
{
|
||||||
if (fIsZooming && action!=DEC_ZOOM)
|
if (fDecorator) {
|
||||||
{
|
if (fIsZooming) {
|
||||||
fDecorator->SetZoom(false);
|
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
|
||||||
fDecorator->DrawZoom();
|
} else if (fIsClosing) {
|
||||||
|
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
|
||||||
|
} else if (fIsMinimizing) {
|
||||||
|
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (fIsDragging) {
|
||||||
if (fIsClosing && action!=DEC_CLOSE)
|
// we will not come to front if we ever actually moved
|
||||||
{
|
fBringToFrontOnRelease = false;
|
||||||
fDecorator->SetClose(false);
|
|
||||||
fDecorator->DrawClose();
|
BPoint delta = event.where - fLastMousePosition;
|
||||||
|
MoveBy(delta.x, delta.y);
|
||||||
}
|
}
|
||||||
else
|
if (fIsResizing) {
|
||||||
if(fIsMinimizing && action!=DEC_MINIMIZE)
|
BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset);
|
||||||
{
|
|
||||||
fDecorator->SetMinimize(false);
|
BPoint delta = frame.RightBottom() - fFrame.RightBottom();
|
||||||
fDecorator->DrawMinimize();
|
ResizeBy(delta.x, delta.y);
|
||||||
}
|
}
|
||||||
|
fLastMousePosition = event.where;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -248,46 +268,57 @@ void WinBorder::MouseMoved(click_type action)
|
|||||||
button click flag, takes the appropriate action (i.e. clearing the close button flag also
|
button click flag, takes the appropriate action (i.e. clearing the close button flag also
|
||||||
takes steps to close the window).
|
takes steps to close the window).
|
||||||
*/
|
*/
|
||||||
void WinBorder::MouseUp(click_type action)
|
void
|
||||||
|
WinBorder::MouseUp(const PointerEvent& event)
|
||||||
{
|
{
|
||||||
if (fIsZooming)
|
if (fDecorator) {
|
||||||
{
|
click_type action = _ActionFor(event);
|
||||||
fIsZooming = false;
|
|
||||||
fDecorator->SetZoom(false);
|
if (fIsZooming) {
|
||||||
fDecorator->DrawZoom();
|
fIsZooming = false;
|
||||||
if(action==DEC_ZOOM)
|
fDecorator->SetZoom(false);
|
||||||
Window()->Zoom();
|
if (action == DEC_ZOOM)
|
||||||
return;
|
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(fIsClosing)
|
if (fBringToFrontOnRelease) {
|
||||||
{
|
// TODO: We would have dragged the window if
|
||||||
fIsClosing = false;
|
// the mouse would have moved, but it didn't
|
||||||
fDecorator->SetClose(false);
|
// move -> This will bring the window to the
|
||||||
fDecorator->DrawClose();
|
// front on R5 in FFM mode!
|
||||||
if(action==DEC_CLOSE)
|
|
||||||
Window()->Quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(fIsMinimizing)
|
|
||||||
{
|
|
||||||
fIsMinimizing = false;
|
|
||||||
fDecorator->SetMinimize(false);
|
|
||||||
fDecorator->DrawMinimize();
|
|
||||||
if(action==DEC_MINIMIZE)
|
|
||||||
Window()->Minimize(true);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
fIsDragging = false;
|
||||||
|
fIsResizing = false;
|
||||||
|
fBringToFrontOnRelease = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets the decorator focus to active or inactive colors
|
//! Sets the decorator focus to active or inactive colors
|
||||||
void WinBorder::HighlightDecorator(const bool &active)
|
void
|
||||||
|
WinBorder::HighlightDecorator(const bool &active)
|
||||||
{
|
{
|
||||||
STRACE(("Decorator->Highlight\n"));
|
STRACE(("Decorator->Highlight\n"));
|
||||||
fDecorator->SetFocus(active);
|
if (fDecorator)
|
||||||
|
fDecorator->SetFocus(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! redraws a certain section of the window border
|
//! redraws a certain section of the window border
|
||||||
void WinBorder::Draw(const BRect &r)
|
void
|
||||||
|
WinBorder::Draw(const BRect &r)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_WINBORDER
|
#ifdef DEBUG_WINBORDER
|
||||||
printf("WinBorder(%s)::Draw() : ", GetName());
|
printf("WinBorder(%s)::Draw() : ", GetName());
|
||||||
@@ -295,10 +326,9 @@ void WinBorder::Draw(const BRect &r)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if we have a visible region, it is decorator's one.
|
// if we have a visible region, it is decorator's one.
|
||||||
if(fDecorator)
|
if (fDecorator) {
|
||||||
{
|
WinBorder* wb = GetRootLayer()->FocusWinBorder();
|
||||||
WinBorder *wb = GetRootLayer()->FocusWinBorder();
|
if (wb == this)
|
||||||
if (wb && wb == this)
|
|
||||||
fDecorator->SetFocus(true);
|
fDecorator->SetFocus(true);
|
||||||
else
|
else
|
||||||
fDecorator->SetFocus(false);
|
fDecorator->SetFocus(false);
|
||||||
@@ -307,10 +337,14 @@ void WinBorder::Draw(const BRect &r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Moves the winborder with redraw
|
//! Moves the winborder with redraw
|
||||||
void WinBorder::MoveBy(float x, float y)
|
void
|
||||||
|
WinBorder::MoveBy(float x, float y)
|
||||||
{
|
{
|
||||||
|
if (x == 0.0 && y == 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
STRACE(("WinBorder(%s)::MoveBy(%.1f, %.1f) fDecorator: %p\n", GetName(), x, y, fDecorator));
|
STRACE(("WinBorder(%s)::MoveBy(%.1f, %.1f) fDecorator: %p\n", GetName(), x, y, fDecorator));
|
||||||
if(fDecorator)
|
if (fDecorator)
|
||||||
fDecorator->MoveBy(x,y);
|
fDecorator->MoveBy(x,y);
|
||||||
|
|
||||||
// NOTE: I moved this here from Layer::move_layer()
|
// NOTE: I moved this here from Layer::move_layer()
|
||||||
@@ -343,78 +377,159 @@ fUpdateReg.OffsetBy(x, y);
|
|||||||
} else {
|
} else {
|
||||||
move_layer(x, y);
|
move_layer(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Resizes the winborder with redraw
|
//! Resizes the winborder with redraw
|
||||||
void WinBorder::ResizeBy(float x, float y)
|
void
|
||||||
|
WinBorder::ResizeBy(float x, float y)
|
||||||
{
|
{
|
||||||
// TODO: account for size limits
|
|
||||||
// NOTE: size limits are also regarded in BWindow::ResizeXX()
|
|
||||||
|
|
||||||
STRACE(("WinBorder(%s)::ResizeBy()\n", GetName()));
|
STRACE(("WinBorder(%s)::ResizeBy()\n", GetName()));
|
||||||
if(fDecorator)
|
|
||||||
fDecorator->ResizeBy(x,y);
|
|
||||||
|
|
||||||
resize_layer(x,y);
|
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();
|
||||||
|
|
||||||
|
if (x != 0.0 || y != 0.0) {
|
||||||
|
if (fDecorator)
|
||||||
|
fDecorator->ResizeBy(x, y);
|
||||||
|
|
||||||
|
resize_layer(x, y);
|
||||||
|
|
||||||
|
if (Window()) {
|
||||||
|
// send a message to the client informing about the changed size
|
||||||
|
BRect frame(fTopLayer->Frame());
|
||||||
|
BMessage msg(B_WINDOW_RESIZED);
|
||||||
|
msg.AddInt32("width", frame.Width());
|
||||||
|
msg.AddInt32("height", frame.Height());
|
||||||
|
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets the minimum and maximum sizes of the window
|
//! Sets the minimum and maximum sizes of the window
|
||||||
void WinBorder::SetSizeLimits(float minwidth, float maxwidth, float minheight, float maxheight)
|
void
|
||||||
|
WinBorder::SetSizeLimits(float minWidth, float maxWidth,
|
||||||
|
float minHeight, float maxHeight)
|
||||||
{
|
{
|
||||||
if(minwidth<0)
|
if (minWidth < 0)
|
||||||
minwidth=0;
|
minWidth = 0;
|
||||||
|
|
||||||
if(minheight<0)
|
if (minHeight < 0)
|
||||||
minheight=0;
|
minHeight = 0;
|
||||||
|
|
||||||
if(maxwidth<=minwidth)
|
fMinWidth = minWidth;
|
||||||
maxwidth=minwidth+1;
|
fMaxWidth = maxWidth;
|
||||||
|
fMinHeight = minHeight;
|
||||||
if(maxheight<=minheight)
|
fMaxHeight = maxHeight;
|
||||||
maxheight=minheight+1;
|
|
||||||
|
// give the Decorator a say in this too
|
||||||
fMinWidth=minwidth;
|
if (fDecorator)
|
||||||
fMaxWidth=maxwidth;
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
|
||||||
fMinHeight=minheight;
|
&fMaxWidth, &fMaxHeight);
|
||||||
fMaxHeight=maxheight;
|
|
||||||
|
if (fMaxWidth < fMinWidth)
|
||||||
|
fMaxWidth = fMinWidth;
|
||||||
|
|
||||||
|
if (fMaxHeight < fMinHeight)
|
||||||
|
fMaxHeight = fMinHeight;
|
||||||
|
|
||||||
|
#if 0 // On R5, Windows don't automatically resize
|
||||||
|
// Automatically resize the window to fit these new limits
|
||||||
|
// if it does not already.
|
||||||
|
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);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSizeLimits
|
||||||
|
void
|
||||||
|
WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
|
||||||
|
float* minHeight, float* maxHeight) const
|
||||||
|
{
|
||||||
|
*minWidth = fMinWidth;
|
||||||
|
*maxWidth = fMaxWidth;
|
||||||
|
*minHeight = fMinHeight;
|
||||||
|
*maxHeight = fMaxHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns true if the point is in the WinBorder's screen area
|
//! Returns true if the point is in the WinBorder's screen area
|
||||||
bool WinBorder::HasPoint(const BPoint& pt) const
|
bool
|
||||||
|
WinBorder::HasPoint(const BPoint& pt) const
|
||||||
{
|
{
|
||||||
return fFullVisible.Contains(pt);
|
return fFullVisible.Contains(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented. Hook function for handling when system GUI colors change
|
// Unimplemented. Hook function for handling when system GUI colors change
|
||||||
void WinBorder::UpdateColors(void)
|
void
|
||||||
|
WinBorder::UpdateColors()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder %s: UpdateColors unimplemented\n",GetName()));
|
STRACE(("WinBorder %s: UpdateColors unimplemented\n",GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented. Hook function for handling when the system decorator changes
|
// Unimplemented. Hook function for handling when the system decorator changes
|
||||||
void WinBorder::UpdateDecorator(void)
|
void
|
||||||
|
WinBorder::UpdateDecorator()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder %s: UpdateDecorator unimplemented\n",GetName()));
|
STRACE(("WinBorder %s: UpdateDecorator unimplemented\n",GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented. Hook function for handling when a system font changes
|
// Unimplemented. Hook function for handling when a system font changes
|
||||||
void WinBorder::UpdateFont(void)
|
void
|
||||||
|
WinBorder::UpdateFont()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder %s: UpdateFont unimplemented\n",GetName()));
|
STRACE(("WinBorder %s: UpdateFont unimplemented\n",GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented. Hook function for handling when the screen resolution changes
|
// Unimplemented. Hook function for handling when the screen resolution changes
|
||||||
void WinBorder::UpdateScreen(void)
|
void
|
||||||
|
WinBorder::UpdateScreen()
|
||||||
{
|
{
|
||||||
STRACE(("WinBorder %s: UpdateScreen unimplemented\n",GetName()));
|
STRACE(("WinBorder %s: UpdateScreen unimplemented\n",GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinBorder::QuietlySetFeel(int32 feel)
|
// QuietlySetFeel
|
||||||
|
void
|
||||||
|
WinBorder::QuietlySetFeel(int32 feel)
|
||||||
{
|
{
|
||||||
fFeel = feel;
|
fFeel = feel;
|
||||||
|
|
||||||
switch(fFeel)
|
switch(fFeel) {
|
||||||
{
|
|
||||||
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
||||||
case B_FLOATING_APP_WINDOW_FEEL:
|
case B_FLOATING_APP_WINDOW_FEEL:
|
||||||
fLevel = B_FLOATING_APP;
|
fLevel = B_FLOATING_APP;
|
||||||
@@ -452,8 +567,7 @@ void WinBorder::QuietlySetFeel(int32 feel)
|
|||||||
// floating and modal windows must appear in every workspace where
|
// floating and modal windows must appear in every workspace where
|
||||||
// their main window is present. Thus their wksIndex will be set to
|
// their main window is present. Thus their wksIndex will be set to
|
||||||
// '0x0' and they will be made visible when needed.
|
// '0x0' and they will be made visible when needed.
|
||||||
switch (fFeel)
|
switch (fFeel) {
|
||||||
{
|
|
||||||
case B_MODAL_APP_WINDOW_FEEL:
|
case B_MODAL_APP_WINDOW_FEEL:
|
||||||
break;
|
break;
|
||||||
case B_MODAL_SUBSET_WINDOW_FEEL:
|
case B_MODAL_SUBSET_WINDOW_FEEL:
|
||||||
@@ -470,4 +584,18 @@ void WinBorder::QuietlySetFeel(int32 feel)
|
|||||||
case B_NORMAL_WINDOW_FEEL:
|
case B_NORMAL_WINDOW_FEEL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _ActionFor
|
||||||
|
click_type
|
||||||
|
WinBorder::_ActionFor(const PointerEvent& event) const
|
||||||
|
{
|
||||||
|
if (fTopLayer->fFullVisible.Contains(event.where))
|
||||||
|
return DEC_NONE;
|
||||||
|
else if (fDecorator)
|
||||||
|
return fDecorator->Clicked(event.where, event.buttons, event.modifiers);
|
||||||
|
else
|
||||||
|
return DEC_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+70
-57
@@ -1,5 +1,5 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Copyright (c) 2001-2002, Haiku, Inc.
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
// File Name: WinBorder.h
|
// File Name: WinBorder.h
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
// Adi Oanca <[email protected]>
|
// Adi Oanca <[email protected]>
|
||||||
|
// Stephan Aßmus <[email protected]>
|
||||||
// Description: Layer subclass which handles window management
|
// Description: Layer subclass which handles window management
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -36,13 +37,15 @@
|
|||||||
|
|
||||||
// these are used by window manager to properly place window.
|
// these are used by window manager to properly place window.
|
||||||
enum {
|
enum {
|
||||||
B_SYSTEM_LAST = -10L,
|
B_SYSTEM_LAST = -10L,
|
||||||
B_FLOATING_APP = 0L,
|
|
||||||
B_MODAL_APP = 1L,
|
B_FLOATING_APP = 0L,
|
||||||
B_NORMAL = 2L,
|
B_MODAL_APP = 1L,
|
||||||
B_FLOATING_ALL = 3L,
|
B_NORMAL = 2L,
|
||||||
B_MODAL_ALL = 4L,
|
B_FLOATING_ALL = 3L,
|
||||||
B_SYSTEM_FIRST = 10L,
|
B_MODAL_ALL = 4L,
|
||||||
|
|
||||||
|
B_SYSTEM_FIRST = 10L,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServerWindow;
|
class ServerWindow;
|
||||||
@@ -50,64 +53,66 @@ class Decorator;
|
|||||||
class DisplayDriver;
|
class DisplayDriver;
|
||||||
class Desktop;
|
class Desktop;
|
||||||
|
|
||||||
class PointerEvent
|
class PointerEvent {
|
||||||
{
|
public:
|
||||||
public:
|
int32 code; // B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED,
|
||||||
int32 code; //B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED
|
// B_MOUSE_WHEEL_CHANGED
|
||||||
//B_MOUSE_WHEEL_CHANGED
|
bigtime_t when;
|
||||||
bigtime_t when;
|
BPoint where;
|
||||||
BPoint where;
|
float wheel_delta_x;
|
||||||
float wheel_delta_x;
|
float wheel_delta_y;
|
||||||
float wheel_delta_y;
|
int32 modifiers;
|
||||||
int32 modifiers;
|
int32 buttons; // B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
|
||||||
int32 buttons; //B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
|
// B_TERTIARY_MOUSE_BUTTON
|
||||||
//B_TERTIARY_MOUSE_BUTTON
|
int32 clicks;
|
||||||
int32 clicks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class WinBorder : public Layer
|
class WinBorder : public Layer {
|
||||||
{
|
public:
|
||||||
public:
|
WinBorder(const BRect &r,
|
||||||
WinBorder( const BRect &r,
|
const char *name,
|
||||||
const char *name,
|
const uint32 wlook,
|
||||||
const uint32 wlook,
|
const uint32 wfeel,
|
||||||
const uint32 wfeel,
|
const uint32 wflags,
|
||||||
const uint32 wflags,
|
const uint32 wwksindex,
|
||||||
const uint32 wwksindex,
|
ServerWindow *win,
|
||||||
ServerWindow *win,
|
DisplayDriver *driver);
|
||||||
DisplayDriver *driver);
|
virtual ~WinBorder();
|
||||||
virtual ~WinBorder(void);
|
|
||||||
|
|
||||||
virtual void Draw(const BRect &r);
|
virtual void Draw(const BRect &r);
|
||||||
|
|
||||||
virtual void MoveBy(float x, float y);
|
virtual void MoveBy(float x, float y);
|
||||||
virtual void ResizeBy(float x, float y);
|
virtual void ResizeBy(float x, float y);
|
||||||
|
|
||||||
virtual void RebuildFullRegion(void);
|
virtual void RebuildFullRegion();
|
||||||
|
|
||||||
void SetSizeLimits( float minwidth,
|
void SetSizeLimits(float minWidth,
|
||||||
float maxwidth,
|
float maxWidth,
|
||||||
float minheight,
|
float minHeight,
|
||||||
float maxheight);
|
float maxHeight);
|
||||||
|
|
||||||
click_type TellWhat(PointerEvent& evt) const;
|
void GetSizeLimits(float* minWidth,
|
||||||
void MouseDown(click_type action);
|
float* maxWidth,
|
||||||
void MouseMoved(click_type action);
|
float* minHeight,
|
||||||
void MouseUp(click_type action);
|
float* maxHeight) const;
|
||||||
|
|
||||||
|
click_type MouseDown(const PointerEvent& evt);
|
||||||
|
void MouseMoved(const PointerEvent& evt);
|
||||||
|
void MouseUp(const PointerEvent& evt);
|
||||||
|
|
||||||
void UpdateColors(void);
|
void UpdateColors();
|
||||||
void UpdateDecorator(void);
|
void UpdateDecorator();
|
||||||
void UpdateFont(void);
|
void UpdateFont();
|
||||||
void UpdateScreen(void);
|
void UpdateScreen();
|
||||||
|
|
||||||
virtual bool HasClient(void) { return false; }
|
virtual bool HasClient() { return false; }
|
||||||
inline Decorator* GetDecorator(void) const { return fDecorator; }
|
inline Decorator* GetDecorator() const { return fDecorator; }
|
||||||
|
|
||||||
inline int32 Look(void) const { return fLook; }
|
inline int32 Look() const { return fLook; }
|
||||||
inline int32 Feel(void) const { return fFeel; }
|
inline int32 Feel() const { return fFeel; }
|
||||||
inline int32 Level() const { return fLevel; }
|
inline int32 Level() const { return fLevel; }
|
||||||
inline uint32 WindowFlags(void) const { return fWindowFlags; }
|
inline uint32 WindowFlags() const { return fWindowFlags; }
|
||||||
inline uint32 Workspaces(void) const { return fWorkspaces; }
|
inline uint32 Workspaces() const { return fWorkspaces; }
|
||||||
|
|
||||||
void HighlightDecorator(const bool &active);
|
void HighlightDecorator(const bool &active);
|
||||||
|
|
||||||
@@ -118,11 +123,13 @@ public:
|
|||||||
|
|
||||||
FMWList fFMWList;
|
FMWList fFMWList;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Layer;
|
friend class Layer;
|
||||||
friend class ServerWindow;
|
friend class ServerWindow;
|
||||||
friend class RootLayer;
|
friend class RootLayer;
|
||||||
|
|
||||||
|
click_type _ActionFor(const PointerEvent& evt) const;
|
||||||
|
|
||||||
Decorator* fDecorator;
|
Decorator* fDecorator;
|
||||||
Layer* fTopLayer;
|
Layer* fTopLayer;
|
||||||
|
|
||||||
@@ -133,11 +140,17 @@ protected:
|
|||||||
int32 fMouseButtons;
|
int32 fMouseButtons;
|
||||||
int32 fKeyModifiers;
|
int32 fKeyModifiers;
|
||||||
BPoint fLastMousePosition;
|
BPoint fLastMousePosition;
|
||||||
|
BPoint fResizingClickOffset;
|
||||||
|
|
||||||
bool fIsClosing;
|
bool fIsClosing;
|
||||||
bool fIsMinimizing;
|
bool fIsMinimizing;
|
||||||
bool fIsZooming;
|
bool fIsZooming;
|
||||||
|
|
||||||
|
bool fIsDragging;
|
||||||
|
bool fBringToFrontOnRelease;
|
||||||
|
|
||||||
|
bool fIsResizing;
|
||||||
|
|
||||||
bool fInUpdate;
|
bool fInUpdate;
|
||||||
bool fRequestSent;
|
bool fRequestSent;
|
||||||
|
|
||||||
@@ -147,10 +160,10 @@ protected:
|
|||||||
int32 fWindowFlags;
|
int32 fWindowFlags;
|
||||||
uint32 fWorkspaces;
|
uint32 fWorkspaces;
|
||||||
|
|
||||||
float fMinWidth,
|
float fMinWidth;
|
||||||
fMaxWidth;
|
float fMaxWidth;
|
||||||
float fMinHeight,
|
float fMinHeight;
|
||||||
fMaxHeight;
|
float fMaxHeight;
|
||||||
|
|
||||||
int cnt; // for debugging
|
int cnt; // for debugging
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user