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:
parent
e4f0f510a9
commit
59345e264f
22
headers/private/interface/truncate_string.h
Normal file
22
headers/private/interface/truncate_string.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2005, Stephan Aßmus <superstippi@gmx.de>. 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
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@ -21,119 +21,164 @@
|
||||
//
|
||||
// File Name: Decorator.h
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Base class for window decorators
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
#ifndef _DECORATOR_H_
|
||||
#define _DECORATOR_H_
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <Rect.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
#include "LayerData.h"
|
||||
|
||||
#include "ColorSet.h"
|
||||
#include "LayerData.h"
|
||||
|
||||
class DisplayDriver;
|
||||
class ServerFont;
|
||||
class BRegion;
|
||||
|
||||
typedef enum { DEC_NONE=0, DEC_ZOOM, DEC_CLOSE, DEC_MINIMIZE,
|
||||
DEC_TAB, DEC_DRAG, DEC_MOVETOBACK, DEC_MOVETOFRONT, DEC_SLIDETAB,
|
||||
typedef enum {
|
||||
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,
|
||||
CLICK_RESIZE_R, CLICK_RESIZE_B, CLICK_RESIZE_LT, CLICK_RESIZE_RT,
|
||||
CLICK_RESIZE_LB, CLICK_RESIZE_RB } click_type;
|
||||
DEC_RESIZE,
|
||||
CLICK_RESIZE_L,
|
||||
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
|
||||
{
|
||||
public:
|
||||
Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
||||
virtual ~Decorator(void);
|
||||
class Decorator {
|
||||
public:
|
||||
Decorator(BRect rect,
|
||||
int32 wlook,
|
||||
int32 wfeel,
|
||||
int32 wflags);
|
||||
virtual ~Decorator();
|
||||
|
||||
void SetColors(const ColorSet &cset);
|
||||
void SetDriver(DisplayDriver *driver);
|
||||
void SetFlags(int32 wflags);
|
||||
void SetFeel(int32 wfeel);
|
||||
void SetFont(ServerFont *font);
|
||||
void SetLook(int32 wlook);
|
||||
void SetColors(const ColorSet &cset);
|
||||
void SetDriver(DisplayDriver *driver);
|
||||
void SetFlags(int32 wflags);
|
||||
void SetFeel(int32 wfeel);
|
||||
void SetFont(ServerFont *font);
|
||||
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);
|
||||
void SetMinimize(bool is_down);
|
||||
void SetZoom(bool is_down);
|
||||
virtual void SetTitle(const char *string);
|
||||
virtual void GetFootprint(BRegion *region);
|
||||
virtual click_type Clicked(BPoint pt, int32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
int32 GetLook(void);
|
||||
int32 GetFeel(void);
|
||||
int32 GetFlags(void);
|
||||
const char *GetTitle(void);
|
||||
// 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(void);
|
||||
BRect GetTabRect(void);
|
||||
virtual void MoveBy(float x, float y);
|
||||
virtual void MoveBy(BPoint pt);
|
||||
virtual BRect SlideTab(float dx, float dy = 0);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
virtual void ResizeBy(BPoint pt);
|
||||
|
||||
bool GetClose(void);
|
||||
bool GetMinimize(void);
|
||||
bool GetZoom(void);
|
||||
|
||||
|
||||
void SetFocus(bool is_active);
|
||||
bool GetFocus(void) { return _has_focus; };
|
||||
ColorSet GetColors(void) { return (_colors)?*_colors:ColorSet(); }
|
||||
virtual void Draw(BRect r);
|
||||
virtual void Draw();
|
||||
virtual void DrawClose();
|
||||
virtual void DrawFrame();
|
||||
virtual void DrawMinimize();
|
||||
virtual void DrawTab();
|
||||
virtual void DrawTitle();
|
||||
virtual void DrawZoom();
|
||||
|
||||
virtual BRect SlideTab(float dx, float dy=0);
|
||||
virtual void GetFootprint(BRegion *region);
|
||||
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);
|
||||
protected:
|
||||
int32 _ClipTitle(float width);
|
||||
|
||||
/*!
|
||||
\brief Returns the number of characters in the title
|
||||
\return The title character count
|
||||
*/
|
||||
int32 _TitleWidth(void) { return (_title_string)?_title_string->CountChars():0; }
|
||||
|
||||
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;
|
||||
int32 _TitleWidth() const
|
||||
{ return fTitle.CountChars(); }
|
||||
|
||||
private:
|
||||
bool _close_state, _zoom_state, _minimize_state;
|
||||
bool _has_focus;
|
||||
BString *_title_string;
|
||||
virtual void _DoLayout();
|
||||
|
||||
virtual void _DrawFrame(BRect r);
|
||||
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 Decorator *create_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
||||
typedef Decorator* create_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags);
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@ class FontServer
|
||||
public:
|
||||
FontServer(void);
|
||||
~FontServer(void);
|
||||
void Lock(void);
|
||||
bool Lock(void);
|
||||
void Unlock(void);
|
||||
|
||||
/*!
|
||||
|
@ -108,10 +108,12 @@ class DrawData {
|
||||
inline const ServerFont& Font() const
|
||||
{ return fFont; }
|
||||
|
||||
// TODO: remove (is contained in SeverFont::Flags())
|
||||
void SetFontAntiAliasing(bool antiAliasing);
|
||||
inline bool FontAntiAliasing() const
|
||||
{ return fFontAntiAliasing; }
|
||||
|
||||
// TODO: remove (should be part of DisplayDriver::DrawString() as in BView)
|
||||
void SetEscapementDelta(escapement_delta delta);
|
||||
inline escapement_delta EscapementDelta() const
|
||||
{ return fEscapementDelta; }
|
||||
|
@ -27,10 +27,14 @@
|
||||
#ifndef SERVERFONT_H_
|
||||
#define SERVERFONT_H_
|
||||
|
||||
#include <Rect.h>
|
||||
#include <Font.h>
|
||||
#include <Rect.h>
|
||||
|
||||
#include "FontFamily.h"
|
||||
|
||||
class BShape;
|
||||
class BString;
|
||||
|
||||
class ServerFont {
|
||||
public:
|
||||
ServerFont();
|
||||
@ -48,6 +52,9 @@ class ServerFont {
|
||||
{ return fStyle ? B_OK : B_NO_INIT; }
|
||||
|
||||
|
||||
ServerFont &operator=(const ServerFont& font);
|
||||
|
||||
|
||||
font_direction Direction() const
|
||||
{ return fDirection; }
|
||||
uint32 Encoding() const
|
||||
@ -70,11 +77,24 @@ class ServerFont {
|
||||
{ return fStyle->GlyphCount(); }
|
||||
int32 CountTuned();
|
||||
|
||||
|
||||
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,
|
||||
const uint16& styleID);
|
||||
status_t SetFamilyAndStyle(const uint32& fontID);
|
||||
status_t SetFamilyAndStyle(uint16 familyID,
|
||||
uint16 styleID);
|
||||
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)
|
||||
{ fDirection = dir; }
|
||||
@ -109,6 +129,7 @@ class ServerFont {
|
||||
{ return fStyle->GlyphCount(); }
|
||||
uint16 CharMapCount() const
|
||||
{ return fStyle->CharMapCount(); }
|
||||
|
||||
BShape** GetGlyphShapes(const char charArray[],
|
||||
int32 numChars) const;
|
||||
|
||||
@ -125,24 +146,17 @@ class ServerFont {
|
||||
FT_Face GetFTFace() const
|
||||
{ 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();
|
||||
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:
|
||||
friend class FontStyle;
|
||||
void _SetStyle(FontStyle* style);
|
||||
|
||||
|
||||
FontStyle* fStyle;
|
||||
edge_info fEdges;
|
||||
@ -152,8 +166,8 @@ protected:
|
||||
BRect fBounds;
|
||||
uint32 fFlags;
|
||||
uint32 fSpacing;
|
||||
uint16 fFace;
|
||||
font_direction fDirection;
|
||||
uint16 fFace;
|
||||
uint32 fEncoding;
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <String.h>
|
||||
|
||||
#include <moreUTF8.h>
|
||||
#include <truncate_string.h>
|
||||
|
||||
#include <Font.h>
|
||||
|
||||
@ -765,115 +766,69 @@ BFont::GetTunedInfo(int32 index, tuned_font_info *info) const
|
||||
link.Read<tuned_font_info>(info);
|
||||
}
|
||||
|
||||
|
||||
// TruncateString
|
||||
void
|
||||
BFont::TruncateString(BString *inOut, uint32 mode, float width) const
|
||||
{
|
||||
if(!inOut)
|
||||
return;
|
||||
|
||||
if(width<=0)
|
||||
{
|
||||
*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);
|
||||
|
||||
// NOTE: Careful, we cannot directly use "inOut->String()" as result
|
||||
// array, because the string length increases by 3 bytes in the worst case scenario.
|
||||
const char* array[1];
|
||||
array[0] = inOut->String();
|
||||
GetTruncatedStrings(array, 1, mode, width, inOut);
|
||||
}
|
||||
|
||||
|
||||
// GetTruncatedStrings
|
||||
void
|
||||
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
||||
uint32 mode, float width, BString resultArray[]) const
|
||||
{
|
||||
if(!stringArray || numStrings<1 || !resultArray)
|
||||
return;
|
||||
if (stringArray && resultArray && numStrings > 0) {
|
||||
// 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;
|
||||
BPrivate::BAppServerLink link;
|
||||
GetTruncatedStrings(stringArray, numStrings, mode, width, truncatedStrings);
|
||||
|
||||
link.StartMessage(AS_GET_TRUNCATED_STRINGS);
|
||||
|
||||
link.Attach<uint32>(mode);
|
||||
link.Attach<float>(width);
|
||||
link.Attach<int32>(numStrings);
|
||||
|
||||
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);
|
||||
// copy the strings into the BString array and free each one
|
||||
for (int32 i = 0; i < numStrings; i++) {
|
||||
resultArray[i].SetTo(truncatedStrings[i]);
|
||||
delete[] truncatedStrings[i];
|
||||
}
|
||||
delete[] truncatedStrings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GetTruncatedStrings
|
||||
void
|
||||
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
|
||||
uint32 mode, float width, char *resultArray[]) const
|
||||
{
|
||||
if(!stringArray || numStrings<1 || !resultArray)
|
||||
return;
|
||||
|
||||
int32 code;
|
||||
BPrivate::BAppServerLink link;
|
||||
|
||||
link.StartMessage(AS_GET_TRUNCATED_STRINGS);
|
||||
|
||||
link.Attach<uint32>(mode);
|
||||
link.Attach<float>(width);
|
||||
link.Attach<int32>(numStrings);
|
||||
|
||||
for(int32 i=0; i<numStrings; i++)
|
||||
link.AttachString(stringArray[i]);
|
||||
|
||||
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);
|
||||
if (stringArray && numStrings > 0) {
|
||||
// the width of the "…" glyph
|
||||
float ellipsisWidth = StringWidth(B_UTF8_ELLIPSIS);
|
||||
for (int32 i = 0; i < numStrings; i++) {
|
||||
int32 length = strlen(stringArray[i]);
|
||||
// count the individual glyphs
|
||||
int32 numChars = UTF8CountChars(stringArray[i], length);
|
||||
// get the escapement of each glyph in font units
|
||||
float* escapementArray = new float[numChars];
|
||||
GetEscapements(stringArray[i], numChars, NULL, escapementArray);
|
||||
|
||||
truncate_string(stringArray[i], mode, width, resultArray[i],
|
||||
escapementArray, fSize, ellipsisWidth, length, numChars);
|
||||
|
||||
delete[] escapementArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// StringWidth
|
||||
float
|
||||
BFont::StringWidth(const char *string) const
|
||||
{
|
||||
int32 length=strlen(string);
|
||||
int32 length = strlen(string);
|
||||
return StringWidth(string, length);
|
||||
}
|
||||
|
||||
@ -881,7 +836,7 @@ BFont::StringWidth(const char *string) const
|
||||
float
|
||||
BFont::StringWidth(const char *string, int32 length) const
|
||||
{
|
||||
if(!string || length<1)
|
||||
if (!string || length < 1)
|
||||
return 0.0;
|
||||
|
||||
int32 code;
|
||||
@ -896,7 +851,7 @@ BFont::StringWidth(const char *string, int32 length) const
|
||||
link.Attach<uint8>(fSpacing);
|
||||
link.FlushWithReply(&code);
|
||||
|
||||
if(code!=SERVER_TRUE)
|
||||
if (code != SERVER_TRUE)
|
||||
return 0.0;
|
||||
|
||||
float width;
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <TextView.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
// TODO: remove this header
|
||||
#include <stdio.h>
|
||||
|
||||
// Private definitions not placed in public headers
|
||||
extern "C" void _init_global_fonts();
|
||||
@ -45,6 +47,10 @@ extern "C" status_t _fini_interface_kit_();
|
||||
#include <ServerProtocol.h>
|
||||
#include <WidthBuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <Font.h>
|
||||
#include "moreUTF8.h"
|
||||
#include "truncate_string.h"
|
||||
|
||||
using namespace BPrivate;
|
||||
|
||||
@ -729,5 +735,172 @@ do_minimize_team(BRect zoomRect, team_id team, bool zoom)
|
||||
// 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
|
||||
|
@ -1026,27 +1026,29 @@ void
|
||||
BWindow::SetSizeLimits(float minWidth, float maxWidth,
|
||||
float minHeight, float maxHeight)
|
||||
{
|
||||
int32 rCode;
|
||||
|
||||
if (minWidth > maxWidth
|
||||
|| minHeight > maxHeight)
|
||||
if (minWidth > maxWidth || minHeight > maxHeight)
|
||||
return;
|
||||
|
||||
Lock();
|
||||
fLink->StartMessage(AS_SET_SIZE_LIMITS);
|
||||
fLink->Attach<float>(fMinWindWidth);
|
||||
fLink->Attach<float>(fMaxWindWidth);
|
||||
fLink->Attach<float>(fMinWindHeight);
|
||||
fLink->Attach<float>(fMaxWindHeight);
|
||||
fLink->Flush();
|
||||
fLink->GetNextReply(&rCode);
|
||||
Unlock();
|
||||
if (Lock()) {
|
||||
fLink->StartMessage(AS_SET_SIZE_LIMITS);
|
||||
fLink->Attach<float>(minWidth);
|
||||
fLink->Attach<float>(maxWidth);
|
||||
fLink->Attach<float>(minHeight);
|
||||
fLink->Attach<float>(maxHeight);
|
||||
fLink->Flush();
|
||||
|
||||
if (rCode == SERVER_TRUE) {
|
||||
fMinWindHeight = minHeight;
|
||||
fMinWindWidth = minWidth;
|
||||
fMaxWindHeight = maxHeight;
|
||||
fMaxWindWidth = maxWidth;
|
||||
int32 rCode;
|
||||
fLink->GetNextReply(&rCode);
|
||||
|
||||
if (rCode == SERVER_TRUE) {
|
||||
// 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,
|
||||
float *minHeight, float *maxHeight)
|
||||
{
|
||||
*minHeight = fMinWindHeight;
|
||||
*minWidth = fMinWindWidth;
|
||||
*maxHeight = fMaxWindHeight;
|
||||
*maxWidth = fMaxWindWidth;
|
||||
// TODO: What about locking?!?
|
||||
*minHeight = fMinWindHeight;
|
||||
*minWidth = fMinWindWidth;
|
||||
*maxHeight = fMaxWindHeight;
|
||||
*maxWidth = fMaxWindWidth;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BWindow::SetZoomLimits(float maxWidth, float maxHeight)
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
if (maxWidth > fMaxWindWidth)
|
||||
maxWidth = fMaxWindWidth;
|
||||
else
|
||||
@ -1090,6 +1094,8 @@ BWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
|
||||
void
|
||||
BWindow::Zoom()
|
||||
{
|
||||
// TODO: broken.
|
||||
// TODO: What about locking?!?
|
||||
float minWidth, minHeight;
|
||||
BScreen screen;
|
||||
|
||||
@ -1142,6 +1148,7 @@ BWindow::ScreenChanged(BRect screen_size, color_space depth)
|
||||
void
|
||||
BWindow::SetPulseRate(bigtime_t rate)
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
if (rate < 0)
|
||||
return;
|
||||
|
||||
@ -1170,6 +1177,7 @@ BWindow::SetPulseRate(bigtime_t rate)
|
||||
bigtime_t
|
||||
BWindow::PulseRate() const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
return fPulseRate;
|
||||
}
|
||||
|
||||
@ -1192,6 +1200,7 @@ void
|
||||
BWindow::AddShortcut(uint32 key, uint32 modifiers, BMessage *msg, BHandler *target)
|
||||
{
|
||||
// NOTE: I'm not sure if it is OK to use 'key'
|
||||
// TODO: What about locking?!?
|
||||
|
||||
if (msg == NULL)
|
||||
return;
|
||||
@ -1224,6 +1233,7 @@ BWindow::AddShortcut(uint32 key, uint32 modifiers, BMessage *msg, BHandler *targ
|
||||
void
|
||||
BWindow::RemoveShortcut(uint32 key, uint32 modifiers)
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
int32 index = findShortcut(key, modifiers | B_COMMAND_KEY);
|
||||
if (index >=0) {
|
||||
_BCmdKey *cmdKey = (_BCmdKey *)accelList.ItemAt(index);
|
||||
@ -1239,6 +1249,7 @@ BWindow::RemoveShortcut(uint32 key, uint32 modifiers)
|
||||
BButton *
|
||||
BWindow::DefaultButton() const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
return fDefaultButton;
|
||||
}
|
||||
|
||||
@ -1246,6 +1257,7 @@ BWindow::DefaultButton() const
|
||||
void
|
||||
BWindow::SetDefaultButton(BButton *button)
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
if (fDefaultButton == button)
|
||||
return;
|
||||
|
||||
@ -1268,6 +1280,7 @@ BWindow::SetDefaultButton(BButton *button)
|
||||
bool
|
||||
BWindow::NeedsUpdate() const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
int32 rCode;
|
||||
|
||||
const_cast<BWindow *>(this)->Lock();
|
||||
@ -1283,6 +1296,7 @@ BWindow::NeedsUpdate() const
|
||||
void
|
||||
BWindow::UpdateIfNeeded()
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
// works only from this thread
|
||||
if (find_thread(NULL) != Thread())
|
||||
return;
|
||||
@ -1317,6 +1331,7 @@ BWindow::UpdateIfNeeded()
|
||||
BView *
|
||||
BWindow::FindView(const char *viewName) const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
return findView(top_view, viewName);
|
||||
}
|
||||
|
||||
@ -1324,12 +1339,14 @@ BWindow::FindView(const char *viewName) const
|
||||
BView *
|
||||
BWindow::FindView(BPoint point) const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
return findView(top_view, point);
|
||||
}
|
||||
|
||||
|
||||
BView *BWindow::CurrentFocus() const
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
return fFocus;
|
||||
}
|
||||
|
||||
@ -1337,6 +1354,7 @@ BView *BWindow::CurrentFocus() const
|
||||
void
|
||||
BWindow::Activate(bool active)
|
||||
{
|
||||
// TODO: What about locking?!?
|
||||
if (IsHidden())
|
||||
return;
|
||||
|
||||
|
@ -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
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@ -21,6 +21,7 @@
|
||||
//
|
||||
// File Name: Decorator.cpp
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Base class for window decorators
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
@ -41,36 +42,28 @@
|
||||
object.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
Decorator::~Decorator(void)
|
||||
Decorator::~Decorator()
|
||||
{
|
||||
if(_colors!=NULL)
|
||||
{
|
||||
delete _colors;
|
||||
_colors=NULL;
|
||||
}
|
||||
if(_title_string)
|
||||
delete _title_string;
|
||||
delete _colors;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Updates the decorator's color set
|
||||
\param cset The color set to update from
|
||||
*/
|
||||
void Decorator::SetColors(const ColorSet &cset)
|
||||
void
|
||||
Decorator::SetColors(const ColorSet &cset)
|
||||
{
|
||||
_colors->SetColors(cset);
|
||||
_SetColors();
|
||||
@ -103,48 +91,15 @@ void Decorator::SetColors(const ColorSet &cset)
|
||||
\brief Assigns a display driver to the decorator
|
||||
\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
|
||||
// _DoLayout() after this
|
||||
_driver=driver;
|
||||
_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;
|
||||
// _DoLayout() after we have it
|
||||
if (_driver) {
|
||||
_DoLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -154,9 +109,10 @@ void Decorator::SetZoom(bool is_down)
|
||||
While this call will not update the screen, it will affect how future
|
||||
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
|
||||
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
|
||||
\param font The new font object to copy from
|
||||
*/
|
||||
void Decorator::SetFont(ServerFont *font)
|
||||
void
|
||||
Decorator::SetFont(ServerFont *font)
|
||||
{
|
||||
if(!font)
|
||||
return;
|
||||
|
||||
_drawdata.SetFont(*font);
|
||||
if (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
|
||||
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
|
||||
\return true if down, false if up
|
||||
\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
|
||||
*/
|
||||
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
|
||||
\return true if down, false if up
|
||||
\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
|
||||
*/
|
||||
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
|
||||
\return true if down, false if up
|
||||
\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
|
||||
*/
|
||||
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
|
||||
\return the decorator's window look
|
||||
*/
|
||||
int32 Decorator::GetLook(void)
|
||||
int32
|
||||
Decorator::GetLook() const
|
||||
{
|
||||
return _look;
|
||||
}
|
||||
@ -235,7 +228,8 @@ int32 Decorator::GetLook(void)
|
||||
\brief Returns the decorator's window feel
|
||||
\return the decorator's window feel
|
||||
*/
|
||||
int32 Decorator::GetFeel(void)
|
||||
int32
|
||||
Decorator::GetFeel() const
|
||||
{
|
||||
return _feel;
|
||||
}
|
||||
@ -244,28 +238,20 @@ int32 Decorator::GetFeel(void)
|
||||
\brief Returns the decorator's window flags
|
||||
\return the decorator's window flags
|
||||
*/
|
||||
int32 Decorator::GetFlags(void)
|
||||
int32
|
||||
Decorator::GetFlags() const
|
||||
{
|
||||
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
|
||||
\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
|
||||
*/
|
||||
|
||||
BRect Decorator::GetBorderRect(void){
|
||||
BRect
|
||||
Decorator::GetBorderRect() const
|
||||
{
|
||||
return _borderrect;
|
||||
}
|
||||
|
||||
@ -282,10 +270,49 @@ BRect Decorator::GetBorderRect(void){
|
||||
\return the decorator's tab rectangle
|
||||
*/
|
||||
|
||||
BRect Decorator::GetTabRect(void){
|
||||
BRect
|
||||
Decorator::GetTabRect() const
|
||||
{
|
||||
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
|
||||
\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
|
||||
updates work.
|
||||
*/
|
||||
void Decorator::SetFocus(bool is_active)
|
||||
void
|
||||
Decorator::SetFocus(bool is_active)
|
||||
{
|
||||
_has_focus=is_active;
|
||||
fIsFocused = is_active;
|
||||
_SetFocus();
|
||||
}
|
||||
|
||||
/*!
|
||||
\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;
|
||||
// TODO: maybe it would be cleaner to handle the redraw here.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// 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
|
||||
\param region Region to be changed to represent the window's screen footprint
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
click_type Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
|
||||
click_type
|
||||
Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
|
||||
{
|
||||
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 <Region.h>
|
||||
|
||||
class DefaultDecorator: public Decorator
|
||||
{
|
||||
public:
|
||||
DefaultDecorator(BRect frame, int32 wlook, int32 wfeel, int32 wflags);
|
||||
virtual ~DefaultDecorator(void);
|
||||
class DefaultDecorator: public Decorator {
|
||||
public:
|
||||
DefaultDecorator(BRect frame,
|
||||
int32 look,
|
||||
int32 feel,
|
||||
int32 flags);
|
||||
virtual ~DefaultDecorator();
|
||||
|
||||
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 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 GetFootprint(BRegion *region);
|
||||
virtual BRect SlideTab(float dx, float dy);
|
||||
virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers);
|
||||
virtual void Draw(BRect r);
|
||||
virtual void Draw();
|
||||
|
||||
virtual void GetSizeLimits(float* minWidth, float* minHeight,
|
||||
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:
|
||||
virtual void _DrawClose(BRect r);
|
||||
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;
|
||||
virtual void _DoLayout();
|
||||
|
||||
RGBColor tab_highcol, tab_lowcol;
|
||||
RGBColor button_highcol, button_lowcol;
|
||||
RGBColor frame_highcol, frame_midcol, frame_lowcol, frame_highercol,
|
||||
frame_lowercol;
|
||||
RGBColor textcol;
|
||||
virtual void _DrawFrame(BRect r);
|
||||
virtual void _DrawTab(BRect r);
|
||||
|
||||
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
|
||||
BRect rightborder,leftborder,topborder,bottomborder;
|
||||
uint64 solidhigh, solidlow;
|
||||
|
||||
int32 borderwidth;
|
||||
// Individual rects for handling window frame
|
||||
// rendering the proper way
|
||||
BRect fRightBorder;
|
||||
BRect fLeftBorder;
|
||||
BRect fTopBorder;
|
||||
BRect fBottomBorder;
|
||||
|
||||
bool slidetab;
|
||||
int textoffset;
|
||||
float titlepixelwidth;
|
||||
int32 fBorderWidth;
|
||||
|
||||
// bool fSlidingTab;
|
||||
// uint32 fTabOffset;
|
||||
float fTextOffset;
|
||||
|
||||
float fMinTabWidth;
|
||||
float fMaxTabWidth;
|
||||
BString fTruncatedTitle;
|
||||
int32 fTruncatedTitleLength;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -70,7 +70,7 @@ FontServer::FontServer(void)
|
||||
&& init)
|
||||
init=false;
|
||||
|
||||
families=new BList(0);
|
||||
families=new BList(20);
|
||||
plain=NULL;
|
||||
bold=NULL;
|
||||
fixed=NULL;
|
||||
@ -86,9 +86,10 @@ FontServer::~FontServer(void)
|
||||
}
|
||||
|
||||
//! 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
|
||||
@ -248,15 +249,21 @@ status_t FontServer::ScanDirectory(const char *fontspath)
|
||||
|
||||
if (error!=0)
|
||||
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)
|
||||
{
|
||||
FT_Done_Face(face);
|
||||
continue;
|
||||
}
|
||||
|
||||
face->charmap=charmap;
|
||||
face->charmap=charmap;*/
|
||||
|
||||
family=GetFamily(face->family_name);
|
||||
|
||||
|
@ -847,19 +847,13 @@ Layer::Redraw(const BRegion& reg, Layer *startFrom)
|
||||
void
|
||||
Layer::Draw(const BRect &r)
|
||||
{
|
||||
// TODO/NOTE: this should be an empty method! the next lines are for testing only
|
||||
|
||||
#ifdef DEBUG_LAYER
|
||||
printf("Layer(%s)::Draw: ", GetName());
|
||||
r.PrintToStream();
|
||||
#endif
|
||||
|
||||
// TODO: don't do this if ViewColor() is B_TRANSPARENT_COLOR
|
||||
fDriver->FillRect(r, fLayerData->ViewColor());
|
||||
// RGBColor c(rand()%255,rand()%255,rand()%255);
|
||||
// fDriver->FillRect(r, c);
|
||||
|
||||
// empty HOOK function.
|
||||
if (!fLayerData->ViewColor().IsTransparentMagic())
|
||||
fDriver->FillRect(r, fLayerData->ViewColor());
|
||||
}
|
||||
|
||||
// EmptyGlobals
|
||||
|
@ -61,41 +61,68 @@
|
||||
#endif
|
||||
|
||||
static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152);
|
||||
static int32 kMaxWorkspaceCount = 32;
|
||||
|
||||
RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
Desktop *desktop, DisplayDriver *driver)
|
||||
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
|
||||
RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
Desktop *desktop, DisplayDriver *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.
|
||||
fRootLayer = this;
|
||||
fRows = 0;
|
||||
fColumns = 0;
|
||||
|
||||
// easy way to identify this class.
|
||||
fClassID = AS_ROOTLAYER_CLASS;
|
||||
fHidden = false;
|
||||
|
||||
memset(&fWorkspace[0], 0, sizeof(Workspace*)*32);
|
||||
memset(fWorkspace, 0, sizeof(Workspace*) * kMaxWorkspaceCount);
|
||||
SetWorkspaceCount(workspaceCount);
|
||||
|
||||
// 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);
|
||||
|
||||
// TODO: read these 4 from a configuration file.
|
||||
fScreenWidth = 0;
|
||||
fScreenHeight = 0;
|
||||
fColorSpace = B_RGB32;
|
||||
fFrequency = 60.f;
|
||||
// fScreenWidth = 0;
|
||||
// fScreenHeight = 0;
|
||||
// fColorSpace = B_RGB32;
|
||||
// fFrequency = 60.f;
|
||||
|
||||
// init the first, default workspace
|
||||
fActiveWksIndex = 0;
|
||||
fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00,
|
||||
kDefaultWorkspaceColor);
|
||||
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
||||
@ -121,7 +147,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
fListenPort = find_port(SERVER_INPUT_PORT);
|
||||
if (fListenPort == B_NAME_NOT_FOUND) {
|
||||
fListenPort = -1;
|
||||
return;
|
||||
}
|
||||
#if ON_SCREEN_DEBUGGING_INFO
|
||||
DebugInfoManager::Default()->SetRootLayer(this);
|
||||
@ -131,20 +156,24 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
|
||||
RootLayer::~RootLayer()
|
||||
{
|
||||
int32 exitValue;
|
||||
fQuiting = true;
|
||||
BPortLink msg(fListenPort, -1);
|
||||
fQuiting = true;
|
||||
|
||||
BPortLink msg(fListenPort, -1);
|
||||
msg.StartMessage(B_QUIT_REQUESTED);
|
||||
msg.EndMessage();
|
||||
msg.Flush();
|
||||
|
||||
wait_for_thread(fThreadID, &exitValue);
|
||||
status_t dummy;
|
||||
wait_for_thread(fThreadID, &dummy);
|
||||
|
||||
delete fDragMessage;
|
||||
|
||||
for (int32 i = 0; i < fWsCount; i++)
|
||||
delete fWorkspace[i];
|
||||
delete[] fWorkspace;
|
||||
|
||||
free(fWinBorderList2);
|
||||
free(fWinBorderList);
|
||||
// RootLayer object just uses Screen objects, it is not allowed to delete them.
|
||||
}
|
||||
|
||||
@ -303,7 +332,7 @@ int32 RootLayer::WorkingThread(void *data)
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -551,9 +580,12 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
if (index >= fWsCount || index == fActiveWksIndex || index < 0)
|
||||
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])
|
||||
{
|
||||
if (!fWorkspace[index]) {
|
||||
// TODO: we NEED datas from a file!!!
|
||||
fWorkspace[index] = new Workspace(index, 0xFF00FF00, kDefaultWorkspaceColor);
|
||||
|
||||
@ -565,10 +597,8 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
int32 ptrCount = windowList.CountItems();
|
||||
WinBorder **ptrWin = (WinBorder**)windowList.Items();
|
||||
|
||||
for (int32 i = 0; i < ptrCount; i++)
|
||||
{
|
||||
if (ptrWin[i]->Workspaces() & (0x00000001UL << index))
|
||||
{
|
||||
for (int32 i = 0; i < ptrCount; i++) {
|
||||
if (ptrWin[i]->Workspaces() & (0x00000001UL << index)) {
|
||||
fWorkspace[index]->AddWinBorder(ptrWin[i]);
|
||||
if (!ptrWin[i]->IsHidden())
|
||||
fWorkspace[index]->ShowWinBorder(ptrWin[i]);
|
||||
@ -577,6 +607,7 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
|
||||
fDesktop->Unlock();
|
||||
}
|
||||
// adjust our DrawData to workspace colors
|
||||
rgb_color bg = fWorkspace[index]->BGColor().GetColor32();
|
||||
if ((bg.red + bg.green + bg.blue) / 3 > 128)
|
||||
fLayerData->SetHighColor(RGBColor(0, 0, 0));
|
||||
@ -584,10 +615,11 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
fLayerData->SetHighColor(RGBColor(255, 255, 255));
|
||||
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.AddInt32("workspace", fActiveWksIndex);
|
||||
activatedMsg.AddBool("active", false);
|
||||
@ -596,48 +628,49 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
fWinBorderList[i]->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false);
|
||||
}
|
||||
|
||||
fActiveWksIndex = index;
|
||||
fActiveWksIndex = index;
|
||||
|
||||
if (fMovingWindow && fEventMaskLayer)
|
||||
{
|
||||
WinBorder *movingWinBorder = (WinBorder*)fEventMaskLayer;
|
||||
if (fMouseTargetWinBorder) {
|
||||
// if (fMovingWindow && 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
|
||||
//fEventMaskLayer = NULL;
|
||||
//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
|
||||
if (movingWinBorder->Feel() == B_NORMAL_WINDOW_FEEL
|
||||
&& !ActiveWorkspace()->HasWinBorder(movingWinBorder))
|
||||
{
|
||||
if (fMouseTargetWinBorder->Feel() == B_NORMAL_WINDOW_FEEL
|
||||
&& !ActiveWorkspace()->HasWinBorder(fMouseTargetWinBorder)) {
|
||||
// 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
|
||||
// change it back when adding winBorder to the current workspace.
|
||||
movingWinBorder->fHidden = true;
|
||||
fWorkspace[exIndex]->HideWinBorder(movingWinBorder);
|
||||
fWorkspace[exIndex]->RemoveWinBorder(movingWinBorder);
|
||||
fMouseTargetWinBorder->fHidden = true;
|
||||
fWorkspace[exIndex]->HideWinBorder(fMouseTargetWinBorder);
|
||||
fWorkspace[exIndex]->RemoveWinBorder(fMouseTargetWinBorder);
|
||||
|
||||
movingWinBorder->fHidden = false;
|
||||
ActiveWorkspace()->AddWinBorder(movingWinBorder);
|
||||
ActiveWorkspace()->ShowWinBorder(movingWinBorder);
|
||||
fMouseTargetWinBorder->fHidden = false;
|
||||
ActiveWorkspace()->AddWinBorder(fMouseTargetWinBorder);
|
||||
ActiveWorkspace()->ShowWinBorder(fMouseTargetWinBorder);
|
||||
|
||||
// TODO: can you call SetWinBorderWorskpaces() instead of this?
|
||||
uint32 wks = movingWinBorder->Workspaces();
|
||||
BMessage changedMsg(B_WORKSPACES_CHANGED);
|
||||
uint32 wks = fMouseTargetWinBorder->Workspaces();
|
||||
BMessage changedMsg(B_WORKSPACES_CHANGED);
|
||||
changedMsg.AddInt64("when", real_time_clock_usecs());
|
||||
changedMsg.AddInt32("old", wks);
|
||||
wks &= ~(0x00000001 << exIndex);
|
||||
wks |= (0x00000001 << fActiveWksIndex);
|
||||
wks &= ~(0x00000001 << exIndex);
|
||||
wks |= (0x00000001 << fActiveWksIndex);
|
||||
changedMsg.AddInt32("new", wks);
|
||||
movingWinBorder->QuietlySetWorkspaces(wks);
|
||||
movingWinBorder->Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false);
|
||||
fMouseTargetWinBorder->QuietlySetWorkspaces(wks);
|
||||
fMouseTargetWinBorder->Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false);
|
||||
}
|
||||
}
|
||||
else if (fEventMaskLayer)
|
||||
{
|
||||
}/* else if (fEventMaskLayer) {
|
||||
// is this a WinBorder object?
|
||||
if (!fEventMaskLayer->fOwner)
|
||||
{
|
||||
@ -648,11 +681,12 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
fEventMaskLayer = NULL;
|
||||
fMovingWindow = false;
|
||||
fResizingWindow = false;
|
||||
}
|
||||
}*/
|
||||
|
||||
fHaveWinBorderList = true;
|
||||
get_workspace_windows();
|
||||
|
||||
// send the workspace changed message for the new workspace
|
||||
{
|
||||
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
||||
activatedMsg.AddInt64("when", real_time_clock_usecs());
|
||||
@ -707,7 +741,7 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@ -716,6 +750,7 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: look into this...
|
||||
if (fEventMaskLayer)
|
||||
{
|
||||
WinBorder *wb = fEventMaskLayer->fOwner?
|
||||
@ -723,12 +758,12 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
||||
(WinBorder*)fEventMaskLayer;
|
||||
if (!fWorkspace[fActiveWksIndex]->HasWinBorder(wb))
|
||||
{
|
||||
if (wb == fEventMaskLayer)
|
||||
/* if (wb == fEventMaskLayer)
|
||||
{
|
||||
fMovingWindow = false;
|
||||
fResizingWindow = false;
|
||||
wb->MouseUp(DEC_NONE);
|
||||
}
|
||||
}*/
|
||||
fEventMaskLayer = NULL;
|
||||
}
|
||||
}
|
||||
@ -744,23 +779,20 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
|
||||
show_final_scene(exFocus, exActive);
|
||||
}
|
||||
|
||||
void RootLayer::SetWorkspaceCount(int32 wksCount)
|
||||
void
|
||||
RootLayer::SetWorkspaceCount(int32 wksCount)
|
||||
{
|
||||
if (wksCount < 1)
|
||||
wksCount = 1;
|
||||
if (wksCount > 32)
|
||||
wksCount = 32;
|
||||
if (wksCount > kMaxWorkspaceCount)
|
||||
wksCount = kMaxWorkspaceCount;
|
||||
|
||||
for (int32 i = wksCount; i < fWsCount; i++)
|
||||
{
|
||||
if (fWorkspace[i])
|
||||
{
|
||||
delete fWorkspace[i];
|
||||
fWorkspace[i] = NULL;
|
||||
}
|
||||
for (int32 i = wksCount; i < fWsCount; i++) {
|
||||
delete fWorkspace[i];
|
||||
fWorkspace[i] = NULL;
|
||||
}
|
||||
|
||||
fWsCount = wksCount;
|
||||
fWsCount = wksCount;
|
||||
}
|
||||
|
||||
void RootLayer::ReadWorkspaceData(const char *path)
|
||||
@ -946,13 +978,12 @@ RootLayer::SetScreenMode(int32 width, int32 height, uint32 colorSpace, float fre
|
||||
//---------------------------------------------------------------------------
|
||||
// Input related methods
|
||||
//---------------------------------------------------------------------------
|
||||
inline
|
||||
void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||
inline void
|
||||
RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case B_MOUSE_DOWN:
|
||||
{
|
||||
switch(code) {
|
||||
case B_MOUSE_DOWN: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_DOWN)\n");
|
||||
// Attached data:
|
||||
// 1) int64 - time 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.clicks);
|
||||
|
||||
if (fLastMousePossition != evt.where) {
|
||||
if (fLastMousePosition != evt.where) {
|
||||
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
|
||||
// correctly trigger entered/exited view transits.
|
||||
// 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");
|
||||
// update on screen mouse pos
|
||||
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) {
|
||||
CRITICAL("RootLayer: fLastMouseMoved is null!\n");
|
||||
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_DOWN) fLastMouseMoved is null!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -991,21 +1026,16 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||
|
||||
// we are clicking a WinBorder
|
||||
|
||||
click_type action;
|
||||
bool invalidate;
|
||||
bool sendMessage = true;
|
||||
WinBorder *exActive = ActiveWinBorder();
|
||||
WinBorder *exFocus = FocusWinBorder();
|
||||
WinBorder *target = fLastMouseMoved->fOwner?
|
||||
fLastMouseMoved->fOwner:
|
||||
(WinBorder*)fLastMouseMoved;
|
||||
WinBorder* exActive = ActiveWinBorder();
|
||||
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)
|
||||
invalidate = ActiveWorkspace()->MoveToBack(target);
|
||||
else
|
||||
invalidate = ActiveWorkspace()->MoveToFront(target);
|
||||
// TODO: only move to front if *not* in Focus Follows Mouse mode!
|
||||
bool invalidate = action == DEC_MOVETOBACK ? ActiveWorkspace()->MoveToBack(target)
|
||||
: ActiveWorkspace()->MoveToFront(target);
|
||||
|
||||
// Performance: MoveToFront() often returns true although it shouldn't do that.
|
||||
// This is because internaly it calls Workspace::ShowWinBorder() and this imposes
|
||||
@ -1014,55 +1044,57 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||
if (invalidate)
|
||||
show_final_scene(exFocus, exActive);
|
||||
|
||||
if (action == DEC_DRAG)
|
||||
{
|
||||
fMovingWindow = true;
|
||||
}
|
||||
else if (action == DEC_RESIZE)
|
||||
{
|
||||
fResizingWindow = true;
|
||||
}
|
||||
else if (action != DEC_NONE && action != DEC_MOVETOBACK)
|
||||
{
|
||||
target->MouseDown(action);
|
||||
}
|
||||
else if (action != DEC_MOVETOBACK)
|
||||
{
|
||||
// we are inside WinBorder
|
||||
// some of the actions are handled by the WinBorder itself,
|
||||
// others are handled by RootLayer
|
||||
fMouseTargetWinBorder = NULL;
|
||||
switch (action) {
|
||||
case DEC_MOVETOBACK:
|
||||
// TODO: handle here once we support FFM...
|
||||
// now it is handled above
|
||||
break;
|
||||
case DEC_NONE: {
|
||||
// TODO: bring to front if not in FFM...
|
||||
// now it is handled above
|
||||
bool sendMessage = true;
|
||||
// supress mouse down events if the window has no focus or
|
||||
// does not accept first clicks
|
||||
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())
|
||||
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 (fLastMouseMoved->EventMask() & B_POINTER_EVENTS) {
|
||||
fEventMaskLayer = fLastMouseMoved;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fLastMouseMoved->EventMask() & B_POINTER_EVENTS)
|
||||
{
|
||||
fEventMaskLayer = fLastMouseMoved;
|
||||
case DEC_DRAG:
|
||||
case DEC_RESIZE:
|
||||
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;
|
||||
}
|
||||
case B_MOUSE_UP:
|
||||
{
|
||||
case B_MOUSE_UP: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_UP)\n");
|
||||
// Attached data:
|
||||
// 1) int64 - time 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<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
|
||||
// correctly trigger entered/exited view transits.
|
||||
fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!",
|
||||
evt.where.x, evt.where.y, fLastMousePossition.x, fLastMousePossition.y);
|
||||
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, fLastMousePosition.x, fLastMousePosition.y);
|
||||
// update on screen mouse pos
|
||||
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
||||
fLastMousePossition = evt.where;
|
||||
fLastMousePosition = evt.where;
|
||||
}
|
||||
|
||||
// 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 (fEventMaskLayer->fOwner)
|
||||
{
|
||||
if (fEventMaskLayer->fOwner) {
|
||||
BMessage upmsg(B_MOUSE_UP);
|
||||
upmsg.AddInt64("when",evt.when);
|
||||
upmsg.AddPoint("where",evt.where);
|
||||
upmsg.AddInt32("modifiers",evt.modifiers);
|
||||
|
||||
fEventMaskLayer->Window()->SendMessageToClient(&upmsg, fEventMaskLayer->fViewToken, false);
|
||||
}
|
||||
// this surely is a WinBorder
|
||||
else
|
||||
{
|
||||
((WinBorder*)fEventMaskLayer)->MouseUp(((WinBorder*)fEventMaskLayer)->TellWhat(evt));
|
||||
} else {
|
||||
// this surely is a WinBorder
|
||||
// TODO: This code is too confusing. There should be a clear separation.
|
||||
// ((WinBorder*)fEventMaskLayer)->MouseUp(((WinBorder*)fEventMaskLayer)->TellWhat(evt));
|
||||
}
|
||||
|
||||
fEventMaskLayer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// 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
|
||||
BMessage upmsg(B_MOUSE_UP);
|
||||
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);
|
||||
|
||||
fLastMouseMoved->Window()->SendMessageToClient(&upmsg, fLastMouseMoved->fViewToken, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// WinBorders don't need _UP_ messages unless they received _DOWN_ messages,
|
||||
// and that case is threated above - WinBorders use Layer::fEventMask to
|
||||
// capture the mouse.
|
||||
}
|
||||
}
|
||||
|
||||
fMovingWindow = false;
|
||||
fResizingWindow = false;
|
||||
// fMovingWindow = false;
|
||||
// fResizingWindow = false;
|
||||
if (fMouseTargetWinBorder) {
|
||||
fMouseTargetWinBorder->MouseUp(evt);
|
||||
fMouseTargetWinBorder = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
case B_MOUSE_MOVED:
|
||||
{
|
||||
case B_MOUSE_MOVED: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_MOVED)\n");
|
||||
// Attached data:
|
||||
// 1) int64 - time 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);
|
||||
|
||||
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
|
||||
// from within RootLayer's thread!!!
|
||||
Layer *target = LayerAt(evt.where);
|
||||
if (target == NULL)
|
||||
CRITICAL("RootLayer::MouseEventHandler: 'target' can't be null.\n");
|
||||
WinBorder *winBorderUnder = NULL;
|
||||
Layer* target = LayerAt(evt.where);
|
||||
if (target == NULL) {
|
||||
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_MOVED) 'target' can't be null.\n");
|
||||
break;
|
||||
}
|
||||
WinBorder* winBorderUnder = NULL;
|
||||
|
||||
// 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.
|
||||
@ -1169,53 +1216,40 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
||||
// is very hard.
|
||||
|
||||
// fEventMaskLayer is always != this
|
||||
if (fEventMaskLayer)
|
||||
{
|
||||
if (fEventMaskLayer == target)
|
||||
{
|
||||
if (fEventMaskLayer) {
|
||||
if (fEventMaskLayer == target) {
|
||||
|
||||
if (target == fLastMouseMoved)
|
||||
{
|
||||
fViewAction = B_INSIDE_VIEW;
|
||||
}
|
||||
else
|
||||
{
|
||||
fViewAction = B_ENTERED_VIEW;
|
||||
}
|
||||
}
|
||||
else if (fEventMaskLayer == fLastMouseMoved)
|
||||
{
|
||||
|
||||
} else if (fEventMaskLayer == fLastMouseMoved) {
|
||||
|
||||
fViewAction = B_EXITED_VIEW;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
} else {
|
||||
|
||||
fViewAction = B_OUTSIDE_VIEW;
|
||||
}
|
||||
|
||||
if (fEventMaskLayer->fOwner)
|
||||
{
|
||||
if (fEventMaskLayer->fOwner) {
|
||||
// top layer does not have B_POINTER_EVENTS in its event mask
|
||||
BMessage movemsg(B_MOUSE_MOVED);
|
||||
movemsg.AddInt64("when",evt.when);
|
||||
movemsg.AddPoint("where",evt.where);
|
||||
movemsg.AddInt32("buttons",evt.buttons);
|
||||
movemsg.AddInt64("when", evt.when);
|
||||
movemsg.AddPoint("where", evt.where);
|
||||
movemsg.AddInt32("buttons", evt.buttons);
|
||||
movemsg.AddInt32("transit", fViewAction);
|
||||
|
||||
fEventMaskLayer->Window()->SendMessageToClient(&movemsg, fEventMaskLayer->fViewToken, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
winBorderUnder = (WinBorder*)fEventMaskLayer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fLastMouseMoved != target)
|
||||
{
|
||||
} else {
|
||||
if (fLastMouseMoved != target) {
|
||||
fViewAction = B_EXITED_VIEW;
|
||||
if (fLastMouseMoved->fOwner)
|
||||
{
|
||||
if (fLastMouseMoved != fLastMouseMoved->fOwner->fTopLayer)
|
||||
{
|
||||
if (fLastMouseMoved->fOwner) {
|
||||
if (fLastMouseMoved != fLastMouseMoved->fOwner->fTopLayer) {
|
||||
BMessage movemsg(B_MOUSE_MOVED);
|
||||
movemsg.AddInt64("when",evt.when);
|
||||
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);
|
||||
fLastMouseMoved->Window()->SendMessageToClient(&movemsg, fLastMouseMoved->fViewToken, false);
|
||||
}
|
||||
}
|
||||
else if (fLastMouseMoved != this)
|
||||
((WinBorder*)fLastMouseMoved)->MouseMoved(DEC_NONE);
|
||||
}// else if (fLastMouseMoved != this)
|
||||
// ((WinBorder*)fLastMouseMoved)->MouseMoved(DEC_NONE);
|
||||
|
||||
fViewAction = B_ENTERED_VIEW;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fViewAction = B_INSIDE_VIEW;
|
||||
}
|
||||
|
||||
if (target->fOwner)
|
||||
{
|
||||
if (target != target->fOwner->fTopLayer)
|
||||
{
|
||||
if (target->fOwner) {
|
||||
if (target != target->fOwner->fTopLayer) {
|
||||
BMessage movemsg(B_MOUSE_MOVED);
|
||||
movemsg.AddInt64("when",evt.when);
|
||||
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);
|
||||
target->Window()->SendMessageToClient(&movemsg, target->fViewToken, false);
|
||||
}
|
||||
}
|
||||
else if (target != this)
|
||||
{
|
||||
} else if (target != this) {
|
||||
winBorderUnder = (WinBorder*)target;
|
||||
}
|
||||
}
|
||||
|
||||
if (winBorderUnder) {
|
||||
/* if (winBorderUnder) {
|
||||
|
||||
BPoint delta = evt.where - fLastMousePossition;
|
||||
BPoint delta = evt.where - fLastMousePosition;
|
||||
|
||||
if (fMovingWindow) {
|
||||
|
||||
@ -1280,15 +1307,14 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
||||
} else {
|
||||
winBorderUnder->MouseMoved(winBorderUnder->TellWhat(evt));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
fLastMouseMoved = target;
|
||||
fLastMousePossition = evt.where;
|
||||
fLastMouseMoved = target;
|
||||
|
||||
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
|
||||
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
||||
// 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_y);
|
||||
|
||||
if (fLastMouseMoved != this)
|
||||
{
|
||||
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 && fLastMouseMoved != this) {
|
||||
if (fLastMouseMoved->fOwner) { // is a Layer object not a WinBorder one
|
||||
if (fLastMouseMoved->fOwner->fTopLayer != fLastMouseMoved) { // must not be the top_view's counterpart
|
||||
BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED);
|
||||
wheelmsg.AddInt64("when", evt.when);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// TODO: WinBorder::MouseWheel() should dissapear or get other params!
|
||||
// ((WinBorder*)fLastMouseMoved)->MouseWheel(...)
|
||||
}
|
||||
@ -1323,7 +1344,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("\nDesktop::MouseEventHandler(): WARNING: unknown message\n\n");
|
||||
printf("RootLayer::MouseEventHandler(): WARNING: unknown message\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1430,6 +1451,7 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg)
|
||||
{
|
||||
fScreenShotIndex++;
|
||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||
entry.SetTo(filename);
|
||||
}
|
||||
fScreenShotIndex++;
|
||||
GetDisplayDriver()->DumpToFile(filename);
|
||||
@ -1512,6 +1534,7 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg)
|
||||
{
|
||||
fScreenShotIndex++;
|
||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||
entry.SetTo(filename);
|
||||
}
|
||||
fScreenShotIndex++;
|
||||
|
||||
@ -1897,7 +1920,8 @@ void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
|
||||
{
|
||||
if (fEventMaskLayer)
|
||||
{
|
||||
WinBorder *wb = fEventMaskLayer->fOwner?
|
||||
// TODO: What was this supposed to do?!?
|
||||
/* WinBorder *wb = fEventMaskLayer->fOwner?
|
||||
fEventMaskLayer->fOwner:
|
||||
(WinBorder*)fEventMaskLayer;
|
||||
if (wb == fEventMaskLayer)
|
||||
@ -1905,7 +1929,7 @@ void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
|
||||
fMovingWindow = false;
|
||||
fResizingWindow = false;
|
||||
wb->MouseUp(DEC_NONE);
|
||||
}
|
||||
}*/
|
||||
fEventMaskLayer = NULL;
|
||||
}
|
||||
|
||||
@ -1970,18 +1994,17 @@ bool RootLayer::get_workspace_windows()
|
||||
return aChange;
|
||||
}
|
||||
|
||||
void RootLayer::draw_window_tab(WinBorder *exFocus)
|
||||
void
|
||||
RootLayer::draw_window_tab(WinBorder *exFocus)
|
||||
{
|
||||
WinBorder *focus = FocusWinBorder();
|
||||
if (exFocus || focus)
|
||||
{
|
||||
if (exFocus || focus) {
|
||||
if (exFocus && exFocus != focus && exFocus->fDecorator)
|
||||
exFocus->fDecorator->SetFocus(false);
|
||||
if (focus && exFocus != focus && focus->fDecorator)
|
||||
focus->fDecorator->SetFocus(true);
|
||||
|
||||
if (exFocus && focus != exFocus)
|
||||
{
|
||||
if (exFocus && focus != exFocus) {
|
||||
// TODO: this line is a hack, decorator is drawn twice.
|
||||
BRegion reg(exFocus->fVisible);
|
||||
if (focus)
|
||||
@ -1991,8 +2014,8 @@ void RootLayer::draw_window_tab(WinBorder *exFocus)
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void RootLayer::empty_visible_regions(Layer *layer)
|
||||
inline void
|
||||
RootLayer::empty_visible_regions(Layer *layer)
|
||||
{
|
||||
// TODO: optimize by avoiding recursion?
|
||||
// NOTE: first 'layer' must be a WinBorder
|
||||
@ -2002,36 +2025,32 @@ void RootLayer::empty_visible_regions(Layer *layer)
|
||||
layer->fVisible.MakeEmpty();
|
||||
|
||||
child = layer->VirtualBottomChild();
|
||||
while(child)
|
||||
{
|
||||
while(child) {
|
||||
empty_visible_regions(child);
|
||||
child = layer->VirtualUpperSibling();
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void RootLayer::winborder_activation(WinBorder* exActive)
|
||||
inline void
|
||||
RootLayer::winborder_activation(WinBorder* exActive)
|
||||
{
|
||||
if (exActive && (FocusWinBorder() != exActive || FrontWinBorder() != exActive))
|
||||
{
|
||||
BMessage msg(B_WINDOW_ACTIVATED);
|
||||
if (exActive && (FocusWinBorder() != exActive || FrontWinBorder() != exActive)) {
|
||||
BMessage msg(B_WINDOW_ACTIVATED);
|
||||
msg.AddBool("active", false);
|
||||
exActive->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||
}
|
||||
if (FocusWinBorder() == FrontWinBorder()
|
||||
&& FrontWinBorder() != NULL && FrontWinBorder() != exActive)
|
||||
{
|
||||
BMessage msg(B_WINDOW_ACTIVATED);
|
||||
&& FrontWinBorder() != NULL && FrontWinBorder() != exActive) {
|
||||
BMessage msg(B_WINDOW_ACTIVATED);
|
||||
msg.AddBool("active", true);
|
||||
FrontWinBorder()->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
||||
inline void
|
||||
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()
|
||||
fHaveWinBorderList = false;
|
||||
// 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!!!
|
||||
// INVESTIGATE, INVESTIGATE, INVESTIGATE!!!
|
||||
// NOTE: the following 3 lines are here for safety reasons!
|
||||
fLastMouseMoved = LayerAt(fLastMousePossition);
|
||||
if (fLastMouseMoved == NULL)
|
||||
CRITICAL("RootLayer::KeyboardEventHandler: 'fLastMouseMoved' can't be null.\n");
|
||||
fLastMouseMoved = LayerAt(fLastMousePosition);
|
||||
if (fLastMouseMoved == NULL) {
|
||||
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());
|
||||
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
|
||||
|
@ -164,12 +164,15 @@ friend class Desktop;
|
||||
void MouseEventHandler(int32 code, BPortLink& link);
|
||||
void KeyboardEventHandler(int32 code, BPortLink& link);
|
||||
|
||||
Desktop *fDesktop;
|
||||
BMessage *fDragMessage;
|
||||
Layer *fLastMouseMoved;
|
||||
Desktop* fDesktop;
|
||||
BMessage* fDragMessage;
|
||||
Layer* fLastMouseMoved;
|
||||
WinBorder* fMouseTargetWinBorder;
|
||||
int32 fViewAction;
|
||||
Layer *fEventMaskLayer;
|
||||
Layer* fEventMaskLayer;
|
||||
|
||||
CursorManager fCursorManager;
|
||||
|
||||
BLocker fAllRegionsLock;
|
||||
|
||||
thread_id fThreadID;
|
||||
@ -185,19 +188,20 @@ friend class Desktop;
|
||||
float fFrequency;
|
||||
|
||||
int32 fButtons;
|
||||
BPoint fLastMousePossition;
|
||||
BPoint fLastMousePosition;
|
||||
bool fMovingWindow;
|
||||
bool fResizingWindow;
|
||||
bool fHaveWinBorderList;
|
||||
|
||||
int32 fActiveWksIndex;
|
||||
int32 fWsCount;
|
||||
Workspace* fWorkspace[32];
|
||||
Workspace** fWorkspace;
|
||||
|
||||
int32 fWinBorderListLength;
|
||||
WinBorder** fWinBorderList2;
|
||||
WinBorder** fWinBorderList;
|
||||
int32 fWinBorderCount;
|
||||
mutable int32 fWinBorderIndex;
|
||||
int32 fWinBorderListLength;
|
||||
|
||||
int32 fScreenShotIndex;
|
||||
bool fQuiting;
|
||||
|
@ -1220,12 +1220,12 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
||||
replylink.Attach<float>(width);
|
||||
replylink.Flush();
|
||||
|
||||
free(string);
|
||||
} else {
|
||||
replylink.StartMessage(SERVER_FALSE);
|
||||
replylink.Flush();
|
||||
}
|
||||
|
||||
free(string);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1875,6 +1875,84 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
||||
|
||||
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:
|
||||
{
|
||||
// Attached data
|
||||
@ -1944,12 +2022,20 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
|
||||
replylink.Flush();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
STRACE(("ServerApp %s received unhandled message code offset %s\n",fSignature.String(),
|
||||
MsgCodeToBString(code).String()));
|
||||
printf("ServerApp %s received unhandled message code offset %s\n", fSignature.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;
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,13 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#include <ByteOrder.h>
|
||||
#include <Shape.h>
|
||||
#include <String.h>
|
||||
#include <UTF8.h>
|
||||
|
||||
#include "Angle.h"
|
||||
#include "FontServer.h"
|
||||
#include "moreUTF8.h"
|
||||
#include "truncate_string.h"
|
||||
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
@ -47,20 +49,22 @@
|
||||
\param flags Style flags 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,
|
||||
uint16 flags, uint8 spacing)
|
||||
ServerFont::ServerFont(FontStyle *style, float size,
|
||||
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;
|
||||
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)
|
||||
if (fStyle)
|
||||
fStyle->AddDependent();
|
||||
}
|
||||
|
||||
@ -68,18 +72,18 @@ ServerFont::ServerFont(FontStyle *style, float size, float rotation, float shear
|
||||
// constructor, that initializes without actually interfacing with
|
||||
// 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
|
||||
*/
|
||||
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;
|
||||
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)
|
||||
if (fStyle)
|
||||
fStyle->AddDependent();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Removes itself as a dependency of its owning style.
|
||||
*/
|
||||
ServerFont::~ServerFont(void)
|
||||
ServerFont::~ServerFont()
|
||||
{
|
||||
if(fStyle)
|
||||
if (fStyle)
|
||||
fStyle->RemoveDependent();
|
||||
}
|
||||
|
||||
@ -116,19 +120,21 @@ ServerFont::~ServerFont(void)
|
||||
\param The font to copy from.
|
||||
\return A copy of the specified font
|
||||
*/
|
||||
ServerFont& ServerFont::operator=(const ServerFont& font){
|
||||
fStyle = font.fStyle;
|
||||
ServerFont&
|
||||
ServerFont::operator=(const ServerFont& font)
|
||||
{
|
||||
fSize = font.fSize;
|
||||
fRotation = font.fRotation;
|
||||
fShear = font.fShear;
|
||||
fFlags = font.fFlags;
|
||||
fSpacing = font.fSpacing;
|
||||
fDirection = B_FONT_LEFT_TO_RIGHT;
|
||||
fFace = B_REGULAR_FACE;
|
||||
fEncoding = B_UNICODE_UTF8;
|
||||
fBounds.Set(0,0,0,0);
|
||||
if(fStyle)
|
||||
fStyle->AddDependent();
|
||||
fDirection = font.fDirection;
|
||||
fFace = font.fFace;
|
||||
fEncoding = font.fEncoding;
|
||||
fBounds = font.fBounds;
|
||||
|
||||
_SetStyle(font.fStyle);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -136,10 +142,11 @@ ServerFont& ServerFont::operator=(const ServerFont& font){
|
||||
\brief Returns the number of strikes in the font
|
||||
\return The number of strikes in the font
|
||||
*/
|
||||
int32 ServerFont::CountTuned(void)
|
||||
int32
|
||||
ServerFont::CountTuned()
|
||||
{
|
||||
if(fStyle)
|
||||
fStyle->TunedCount();
|
||||
if (fStyle)
|
||||
return fStyle->TunedCount();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -148,42 +155,77 @@ int32 ServerFont::CountTuned(void)
|
||||
\brief Returns the file format of the font. Currently unimplemented.
|
||||
\return B_TRUETYPE_WINDOWS
|
||||
*/
|
||||
font_file_format ServerFont::FileFormat(void)
|
||||
font_file_format
|
||||
ServerFont::FileFormat()
|
||||
{
|
||||
// TODO: implement ServerFont::FileFormat
|
||||
return B_TRUETYPE_WINDOWS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns a BRect which encloses the entire font
|
||||
\return A BRect which encloses the entire font
|
||||
const char*
|
||||
ServerFont::GetStyle() const
|
||||
{
|
||||
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
|
||||
{
|
||||
return fStyle->Name();
|
||||
}
|
||||
|
||||
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
|
||||
/*!
|
||||
\brief Sets the ServerFont instance to whatever font is specified
|
||||
\param fontID the combination of family and style ID numbers
|
||||
\return B_OK if successful, B_ERROR if not
|
||||
*/
|
||||
void ServerFont::Height(font_height *fh)
|
||||
status_t
|
||||
ServerFont::SetFamilyAndStyle(uint32 fontID)
|
||||
{
|
||||
if(!fh)
|
||||
return;
|
||||
uint16 style = fontID & 0xFFFF;
|
||||
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
||||
|
||||
if(fStyle)
|
||||
*fh=fStyle->GetHeight(fSize);
|
||||
return SetFamilyAndStyle(family, style);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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
|
||||
@ -295,7 +337,7 @@ BPoint*
|
||||
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
||||
BPoint offsetArray[]) const
|
||||
{
|
||||
if (!charArray || numChars <= 0 || !offsetArray)
|
||||
if (!fStyle || !charArray || numChars <= 0 || !offsetArray)
|
||||
return NULL;
|
||||
|
||||
FT_Face face = fStyle->GetFTFace();
|
||||
@ -349,7 +391,7 @@ inline bool
|
||||
is_white_space(uint16 glyph)
|
||||
{
|
||||
// TODO: handle them all!
|
||||
if (glyph == ' ')
|
||||
if (glyph == ' ' || glyph == B_TAB)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -359,7 +401,7 @@ bool
|
||||
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
||||
float widthArray[], escapement_delta delta) const
|
||||
{
|
||||
if (!charArray || numChars <= 0)
|
||||
if (!fStyle || !charArray || numChars <= 0)
|
||||
return false;
|
||||
|
||||
FT_Face face = fStyle->GetFTFace();
|
||||
@ -404,7 +446,7 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
||||
float
|
||||
ServerFont::StringWidth(const char* string, int32 numBytes) const
|
||||
{
|
||||
if (!string || numBytes <= 0)
|
||||
if (!fStyle || !string || numBytes <= 0)
|
||||
return 0.0;
|
||||
|
||||
FT_Face face = fStyle->GetFTFace();
|
||||
@ -439,55 +481,69 @@ ServerFont::StringWidth(const char* string, int32 numBytes) const
|
||||
return width;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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
|
||||
/*!
|
||||
\brief Returns a BRect which encloses the entire font
|
||||
\return A BRect which encloses the entire font
|
||||
*/
|
||||
status_t ServerFont::SetFamilyAndStyle(const uint16 &familyID,const uint16 &styleID)
|
||||
BRect
|
||||
ServerFont::BoundingBox()
|
||||
{
|
||||
fontserver->Lock();
|
||||
FontStyle *sty=fontserver->GetStyle(familyID,styleID);
|
||||
fontserver->Unlock();
|
||||
if(!sty)
|
||||
return B_ERROR;
|
||||
|
||||
fStyle=sty;
|
||||
return B_OK;
|
||||
// TODO: fBounds is nowhere calculated!
|
||||
return fBounds;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Sets the ServerFont instance to whatever font is specified
|
||||
\param fontID the combination of family and style ID numbers
|
||||
\return B_OK if successful, B_ERROR if not
|
||||
/*!
|
||||
\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
|
||||
*/
|
||||
status_t ServerFont::SetFamilyAndStyle(const uint32 &fontID)
|
||||
void
|
||||
ServerFont::Height(font_height *fh) const
|
||||
{
|
||||
uint16 style = fontID & 0xFFFF;
|
||||
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
||||
|
||||
fontserver->Lock();
|
||||
FontStyle *sty=fontserver->GetStyle(family,style);
|
||||
fontserver->Unlock();
|
||||
if(!sty)
|
||||
return B_ERROR;
|
||||
|
||||
fStyle=sty;
|
||||
return B_OK;
|
||||
if (fh && fStyle)
|
||||
*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
|
||||
// TruncateString
|
||||
void
|
||||
ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
||||
{
|
||||
uint32 famsty=0;
|
||||
|
||||
famsty|=FamilyID() << 16;
|
||||
famsty|=StyleID();
|
||||
|
||||
return famsty;
|
||||
if (inOut) {
|
||||
// the width of the "…" glyph
|
||||
float ellipsisWidth = StringWidth(B_UTF8_ELLIPSIS, 3);
|
||||
const char* string = inOut->String();
|
||||
int32 length = strlen(string);
|
||||
// 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
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@mymail.ro>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Shadow BWindow class
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
@ -74,7 +75,6 @@
|
||||
# define DTRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
/*!
|
||||
@ -230,7 +230,7 @@ ServerWindow::Minimize(bool status)
|
||||
|
||||
//! Sends a message to the client to perform a Zoom
|
||||
void
|
||||
ServerWindow::Zoom(void)
|
||||
ServerWindow::Zoom()
|
||||
{
|
||||
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
||||
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
|
||||
*/
|
||||
status_t
|
||||
ServerWindow::Lock(void)
|
||||
ServerWindow::Lock()
|
||||
{
|
||||
STRACE(("\nServerWindow %s: Lock\n", fName));
|
||||
|
||||
@ -268,7 +268,7 @@ ServerWindow::Lock(void)
|
||||
|
||||
//! Unlocks the window
|
||||
void
|
||||
ServerWindow::Unlock(void)
|
||||
ServerWindow::Unlock()
|
||||
{
|
||||
STRACE(("ServerWindow %s: Unlock\n\n", fName));
|
||||
|
||||
@ -280,7 +280,7 @@ ServerWindow::Unlock(void)
|
||||
\return True if locked, false if not.
|
||||
*/
|
||||
bool
|
||||
ServerWindow::IsLocked(void) const
|
||||
ServerWindow::IsLocked() const
|
||||
{
|
||||
return fLocker.IsLocked();
|
||||
}
|
||||
@ -289,8 +289,7 @@ ServerWindow::IsLocked(void) const
|
||||
\brief Sets the font state for a layer
|
||||
\param layer The layer to set the font
|
||||
*/
|
||||
inline
|
||||
void
|
||||
inline void
|
||||
ServerWindow::SetLayerFontState(Layer *layer, LinkMsgReader &link)
|
||||
{
|
||||
STRACE(("ServerWindow %s: SetLayerFontStateMessage for layer %s\n",
|
||||
@ -301,8 +300,7 @@ ServerWindow::SetLayerFontState(Layer *layer, LinkMsgReader &link)
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void
|
||||
inline void
|
||||
ServerWindow::SetLayerState(Layer *layer, LinkMsgReader &link)
|
||||
{
|
||||
STRACE(("ServerWindow %s: SetLayerState for layer %s\n",fName,
|
||||
@ -314,8 +312,7 @@ ServerWindow::SetLayerState(Layer *layer, LinkMsgReader &link)
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
Layer *
|
||||
inline Layer*
|
||||
ServerWindow::CreateLayerTree(Layer *localRoot, LinkMsgReader &link)
|
||||
{
|
||||
// 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);
|
||||
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
|
||||
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;
|
||||
}
|
||||
case AS_LAYER_INVAL_REGION:
|
||||
@ -1236,17 +1236,29 @@ ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link)
|
||||
// 3) float minimum 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>(&wmax);
|
||||
link.Read<float>(&hmin);
|
||||
link.Read<float>(&hmax);
|
||||
|
||||
fWinBorder->SetSizeLimits(wmin,wmax,hmin,hmax);
|
||||
link.Read<float>(&minWidth);
|
||||
link.Read<float>(&maxWidth);
|
||||
link.Read<float>(&minHeight);
|
||||
link.Read<float>(&maxHeight);
|
||||
|
||||
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->Attach<float>(minWidth);
|
||||
fMsgSender->Attach<float>(maxWidth);
|
||||
fMsgSender->Attach<float>(minHeight);
|
||||
fMsgSender->Attach<float>(maxHeight);
|
||||
|
||||
fMsgSender->Flush();
|
||||
|
||||
break;
|
||||
}
|
||||
case B_MINIMIZE:
|
||||
@ -2061,7 +2073,8 @@ ServerWindow::_CopyBits(RootLayer* rootLayer, Layer* layer,
|
||||
layer->GetDisplayDriver()->CopyRegion(©Region, xOffset, yOffset);
|
||||
|
||||
// trigger the redraw
|
||||
rootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
// rootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
rootLayer->RequestDraw(invalidRegion, fWinBorder);
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,27 +22,31 @@
|
||||
// File Name: WinBorder.cpp
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@cotty.iren.ro>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Layer subclass which handles window management
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
#include <Locker.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
#include <Locker.h>
|
||||
#include <View.h> // for mouse button defines
|
||||
|
||||
#include <Debug.h>
|
||||
#include "PortLink.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 "DebugInfoManager.h"
|
||||
|
||||
#include "AppServer.h" // for new_decorator()
|
||||
#include "TokenHandler.h"
|
||||
#include "Decorator.h"
|
||||
#include "Desktop.h"
|
||||
#include "Globals.h"
|
||||
#include "MessagePrivate.h"
|
||||
#include "PortLink.h"
|
||||
#include "RootLayer.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "TokenHandler.h"
|
||||
#include "Workspace.h"
|
||||
|
||||
#include "WinBorder.h"
|
||||
|
||||
// Toggle general function call output
|
||||
//#define DEBUG_WINBORDER
|
||||
|
||||
@ -71,80 +75,89 @@
|
||||
# define STRACE_CLICK(x) ;
|
||||
#endif
|
||||
|
||||
//! TokenHandler object used to provide IDs for all WinBorder objects
|
||||
TokenHandler border_token_handler;
|
||||
|
||||
bool gMouseDown = false;
|
||||
|
||||
|
||||
WinBorder::WinBorder( const BRect &r,
|
||||
const char *name,
|
||||
const uint32 wlook,
|
||||
const uint32 wfeel,
|
||||
const uint32 wflags,
|
||||
const uint32 wwksindex,
|
||||
ServerWindow *win,
|
||||
DisplayDriver *driver)
|
||||
WinBorder::WinBorder(const BRect &r,
|
||||
const char *name,
|
||||
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),
|
||||
fLook(wlook),
|
||||
fLevel(-100),
|
||||
fWindowFlags(wflags),
|
||||
fWorkspaces(wwksindex)
|
||||
fDecorator(NULL),
|
||||
fTopLayer(NULL),
|
||||
|
||||
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
|
||||
fHidden = true;
|
||||
fInUpdate = false;
|
||||
fRequestSent = false;
|
||||
fServerWin = win;
|
||||
fClassID = AS_WINBORDER_CLASS;
|
||||
cnt = 0; // for debugging
|
||||
fMouseButtons = 0;
|
||||
fKeyModifiers = 0;
|
||||
fDecorator = NULL;
|
||||
fTopLayer = NULL;
|
||||
fAdFlags = fAdFlags | B_LAYER_CHILDREN_DEPENDANT;
|
||||
fFlags = B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE;
|
||||
fEventMask = B_POINTER_EVENTS;
|
||||
|
||||
fIsClosing = false;
|
||||
fIsMinimizing = false;
|
||||
fIsZooming = false;
|
||||
|
||||
fLastMousePosition.Set(-1,-1);
|
||||
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);
|
||||
if (fDecorator)
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
||||
}
|
||||
|
||||
RebuildFullRegion();
|
||||
|
||||
gDesktop->AddWinBorder(this);
|
||||
|
||||
STRACE(("WinBorder %s:\n",GetName()));
|
||||
STRACE(("\tFrame: (%.1f,%.1f,%.1f,%.1f)\n",r.left,r.top,r.right,r.bottom));
|
||||
STRACE(("\tWindow %s\n",win?win->Title():"NULL"));
|
||||
STRACE(("WinBorder %s:\n", GetName()));
|
||||
STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", r.left, r.top, r.right, r.bottom));
|
||||
STRACE(("\tWindow %s\n",win ? win->Title() : "NULL"));
|
||||
}
|
||||
|
||||
WinBorder::~WinBorder(void)
|
||||
WinBorder::~WinBorder()
|
||||
{
|
||||
STRACE(("WinBorder(%s)::~WinBorder()\n",GetName()));
|
||||
|
||||
gDesktop->RemoveWinBorder(this);
|
||||
|
||||
if (fTopLayer){
|
||||
delete fTopLayer;
|
||||
fTopLayer = NULL;
|
||||
}
|
||||
|
||||
if (fDecorator)
|
||||
{
|
||||
delete fDecorator;
|
||||
fDecorator = NULL;
|
||||
}
|
||||
delete fTopLayer;
|
||||
delete fDecorator;
|
||||
}
|
||||
|
||||
//! 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()));
|
||||
|
||||
@ -155,16 +168,6 @@ void WinBorder::RebuildFullRegion(void)
|
||||
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
|
||||
\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
|
||||
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
|
||||
switch(action)
|
||||
{
|
||||
case DEC_CLOSE:
|
||||
{
|
||||
fIsClosing = true;
|
||||
fDecorator->SetClose(true);
|
||||
fDecorator->DrawClose();
|
||||
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
||||
break;
|
||||
}
|
||||
case DEC_ZOOM:
|
||||
{
|
||||
fIsZooming = true;
|
||||
fDecorator->SetZoom(true);
|
||||
fDecorator->DrawZoom();
|
||||
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
||||
break;
|
||||
}
|
||||
case DEC_MINIMIZE:
|
||||
{
|
||||
fIsMinimizing = true;
|
||||
fDecorator->SetMinimize(true);
|
||||
fDecorator->DrawMinimize();
|
||||
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
debugger("WinBorder::MouseDown - default case - not allowed!\n");
|
||||
break;
|
||||
click_type action = _ActionFor(event);
|
||||
|
||||
if (fDecorator) {
|
||||
// find out where user clicked in Decorator
|
||||
switch(action) {
|
||||
case DEC_CLOSE:
|
||||
fIsClosing = true;
|
||||
fDecorator->SetClose(true);
|
||||
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
||||
break;
|
||||
|
||||
case DEC_ZOOM:
|
||||
fIsZooming = true;
|
||||
fDecorator->SetZoom(true);
|
||||
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
||||
break;
|
||||
|
||||
case DEC_MINIMIZE:
|
||||
fIsMinimizing = true;
|
||||
fDecorator->SetMinimize(true);
|
||||
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
||||
break;
|
||||
|
||||
case DEC_DRAG:
|
||||
fIsDragging = true;
|
||||
fBringToFrontOnRelease = true;
|
||||
fLastMousePosition = event.where;
|
||||
STRACE_CLICK(("===> DEC_DRAG\n"));
|
||||
break;
|
||||
|
||||
case DEC_RESIZE:
|
||||
fIsResizing = true;
|
||||
fLastMousePosition = event.where;
|
||||
fResizingClickOffset = event.where - fFrame.RightBottom();
|
||||
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -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
|
||||
away to prevent the operation from occurring
|
||||
*/
|
||||
void WinBorder::MouseMoved(click_type action)
|
||||
void
|
||||
WinBorder::MouseMoved(const PointerEvent& event)
|
||||
{
|
||||
if (fIsZooming && action!=DEC_ZOOM)
|
||||
{
|
||||
fDecorator->SetZoom(false);
|
||||
fDecorator->DrawZoom();
|
||||
if (fDecorator) {
|
||||
if (fIsZooming) {
|
||||
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
|
||||
} else if (fIsClosing) {
|
||||
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
|
||||
} else if (fIsMinimizing) {
|
||||
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (fIsClosing && action!=DEC_CLOSE)
|
||||
{
|
||||
fDecorator->SetClose(false);
|
||||
fDecorator->DrawClose();
|
||||
if (fIsDragging) {
|
||||
// we will not come to front if we ever actually moved
|
||||
fBringToFrontOnRelease = false;
|
||||
|
||||
BPoint delta = event.where - fLastMousePosition;
|
||||
MoveBy(delta.x, delta.y);
|
||||
}
|
||||
else
|
||||
if(fIsMinimizing && action!=DEC_MINIMIZE)
|
||||
{
|
||||
fDecorator->SetMinimize(false);
|
||||
fDecorator->DrawMinimize();
|
||||
if (fIsResizing) {
|
||||
BRect frame(fFrame.LeftTop(), event.where - fResizingClickOffset);
|
||||
|
||||
BPoint delta = frame.RightBottom() - fFrame.RightBottom();
|
||||
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
|
||||
takes steps to close the window).
|
||||
*/
|
||||
void WinBorder::MouseUp(click_type action)
|
||||
void
|
||||
WinBorder::MouseUp(const PointerEvent& event)
|
||||
{
|
||||
if (fIsZooming)
|
||||
{
|
||||
fIsZooming = false;
|
||||
fDecorator->SetZoom(false);
|
||||
fDecorator->DrawZoom();
|
||||
if(action==DEC_ZOOM)
|
||||
Window()->Zoom();
|
||||
return;
|
||||
if (fDecorator) {
|
||||
click_type action = _ActionFor(event);
|
||||
|
||||
if (fIsZooming) {
|
||||
fIsZooming = false;
|
||||
fDecorator->SetZoom(false);
|
||||
if (action == DEC_ZOOM)
|
||||
Window()->Zoom();
|
||||
return;
|
||||
}
|
||||
if (fIsClosing) {
|
||||
fIsClosing = false;
|
||||
fDecorator->SetClose(false);
|
||||
if (action == DEC_CLOSE)
|
||||
Window()->Quit();
|
||||
return;
|
||||
}
|
||||
if (fIsMinimizing) {
|
||||
fIsMinimizing = false;
|
||||
fDecorator->SetMinimize(false);
|
||||
if (action == DEC_MINIMIZE)
|
||||
Window()->Minimize(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(fIsClosing)
|
||||
{
|
||||
fIsClosing = false;
|
||||
fDecorator->SetClose(false);
|
||||
fDecorator->DrawClose();
|
||||
if(action==DEC_CLOSE)
|
||||
Window()->Quit();
|
||||
return;
|
||||
}
|
||||
if(fIsMinimizing)
|
||||
{
|
||||
fIsMinimizing = false;
|
||||
fDecorator->SetMinimize(false);
|
||||
fDecorator->DrawMinimize();
|
||||
if(action==DEC_MINIMIZE)
|
||||
Window()->Minimize(true);
|
||||
return;
|
||||
if (fBringToFrontOnRelease) {
|
||||
// TODO: We would have dragged the window if
|
||||
// the mouse would have moved, but it didn't
|
||||
// move -> This will bring the window to the
|
||||
// front on R5 in FFM mode!
|
||||
}
|
||||
fIsDragging = false;
|
||||
fIsResizing = false;
|
||||
fBringToFrontOnRelease = false;
|
||||
}
|
||||
|
||||
//! Sets the decorator focus to active or inactive colors
|
||||
void WinBorder::HighlightDecorator(const bool &active)
|
||||
void
|
||||
WinBorder::HighlightDecorator(const bool &active)
|
||||
{
|
||||
STRACE(("Decorator->Highlight\n"));
|
||||
fDecorator->SetFocus(active);
|
||||
if (fDecorator)
|
||||
fDecorator->SetFocus(active);
|
||||
}
|
||||
|
||||
//! redraws a certain section of the window border
|
||||
void WinBorder::Draw(const BRect &r)
|
||||
void
|
||||
WinBorder::Draw(const BRect &r)
|
||||
{
|
||||
#ifdef DEBUG_WINBORDER
|
||||
printf("WinBorder(%s)::Draw() : ", GetName());
|
||||
@ -295,10 +326,9 @@ void WinBorder::Draw(const BRect &r)
|
||||
#endif
|
||||
|
||||
// if we have a visible region, it is decorator's one.
|
||||
if(fDecorator)
|
||||
{
|
||||
WinBorder *wb = GetRootLayer()->FocusWinBorder();
|
||||
if (wb && wb == this)
|
||||
if (fDecorator) {
|
||||
WinBorder* wb = GetRootLayer()->FocusWinBorder();
|
||||
if (wb == this)
|
||||
fDecorator->SetFocus(true);
|
||||
else
|
||||
fDecorator->SetFocus(false);
|
||||
@ -307,10 +337,14 @@ void WinBorder::Draw(const BRect &r)
|
||||
}
|
||||
|
||||
//! 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));
|
||||
if(fDecorator)
|
||||
if (fDecorator)
|
||||
fDecorator->MoveBy(x,y);
|
||||
|
||||
// NOTE: I moved this here from Layer::move_layer()
|
||||
@ -343,78 +377,159 @@ fUpdateReg.OffsetBy(x, y);
|
||||
} else {
|
||||
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
|
||||
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()));
|
||||
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
|
||||
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)
|
||||
minwidth=0;
|
||||
if (minWidth < 0)
|
||||
minWidth = 0;
|
||||
|
||||
if(minheight<0)
|
||||
minheight=0;
|
||||
|
||||
if(maxwidth<=minwidth)
|
||||
maxwidth=minwidth+1;
|
||||
|
||||
if(maxheight<=minheight)
|
||||
maxheight=minheight+1;
|
||||
|
||||
fMinWidth=minwidth;
|
||||
fMaxWidth=maxwidth;
|
||||
fMinHeight=minheight;
|
||||
fMaxHeight=maxheight;
|
||||
if (minHeight < 0)
|
||||
minHeight = 0;
|
||||
|
||||
fMinWidth = minWidth;
|
||||
fMaxWidth = maxWidth;
|
||||
fMinHeight = minHeight;
|
||||
fMaxHeight = maxHeight;
|
||||
|
||||
// give the Decorator a say in this too
|
||||
if (fDecorator)
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
|
||||
&fMaxWidth, &fMaxHeight);
|
||||
|
||||
if (fMaxWidth < fMinWidth)
|
||||
fMaxWidth = fMinWidth;
|
||||
|
||||
if (fMaxHeight < fMinHeight)
|
||||
fMaxHeight = fMinHeight;
|
||||
|
||||
#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
|
||||
bool WinBorder::HasPoint(const BPoint& pt) const
|
||||
bool
|
||||
WinBorder::HasPoint(const BPoint& pt) const
|
||||
{
|
||||
return fFullVisible.Contains(pt);
|
||||
}
|
||||
|
||||
// Unimplemented. Hook function for handling when system GUI colors change
|
||||
void WinBorder::UpdateColors(void)
|
||||
void
|
||||
WinBorder::UpdateColors()
|
||||
{
|
||||
STRACE(("WinBorder %s: UpdateColors unimplemented\n",GetName()));
|
||||
}
|
||||
|
||||
// Unimplemented. Hook function for handling when the system decorator changes
|
||||
void WinBorder::UpdateDecorator(void)
|
||||
void
|
||||
WinBorder::UpdateDecorator()
|
||||
{
|
||||
STRACE(("WinBorder %s: UpdateDecorator unimplemented\n",GetName()));
|
||||
}
|
||||
|
||||
// Unimplemented. Hook function for handling when a system font changes
|
||||
void WinBorder::UpdateFont(void)
|
||||
void
|
||||
WinBorder::UpdateFont()
|
||||
{
|
||||
STRACE(("WinBorder %s: UpdateFont unimplemented\n",GetName()));
|
||||
}
|
||||
|
||||
// Unimplemented. Hook function for handling when the screen resolution changes
|
||||
void WinBorder::UpdateScreen(void)
|
||||
void
|
||||
WinBorder::UpdateScreen()
|
||||
{
|
||||
STRACE(("WinBorder %s: UpdateScreen unimplemented\n",GetName()));
|
||||
}
|
||||
|
||||
void WinBorder::QuietlySetFeel(int32 feel)
|
||||
// QuietlySetFeel
|
||||
void
|
||||
WinBorder::QuietlySetFeel(int32 feel)
|
||||
{
|
||||
fFeel = feel;
|
||||
|
||||
switch(fFeel)
|
||||
{
|
||||
switch(fFeel) {
|
||||
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
||||
case B_FLOATING_APP_WINDOW_FEEL:
|
||||
fLevel = B_FLOATING_APP;
|
||||
@ -452,8 +567,7 @@ void WinBorder::QuietlySetFeel(int32 feel)
|
||||
// floating and modal windows must appear in every workspace where
|
||||
// their main window is present. Thus their wksIndex will be set to
|
||||
// '0x0' and they will be made visible when needed.
|
||||
switch (fFeel)
|
||||
{
|
||||
switch (fFeel) {
|
||||
case B_MODAL_APP_WINDOW_FEEL:
|
||||
break;
|
||||
case B_MODAL_SUBSET_WINDOW_FEEL:
|
||||
@ -470,4 +584,18 @@ void WinBorder::QuietlySetFeel(int32 feel)
|
||||
case B_NORMAL_WINDOW_FEEL:
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@ -22,6 +22,7 @@
|
||||
// File Name: WinBorder.h
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@mymail.ro>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Layer subclass which handles window management
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
@ -36,13 +37,15 @@
|
||||
|
||||
// these are used by window manager to properly place window.
|
||||
enum {
|
||||
B_SYSTEM_LAST = -10L,
|
||||
B_FLOATING_APP = 0L,
|
||||
B_MODAL_APP = 1L,
|
||||
B_NORMAL = 2L,
|
||||
B_FLOATING_ALL = 3L,
|
||||
B_MODAL_ALL = 4L,
|
||||
B_SYSTEM_FIRST = 10L,
|
||||
B_SYSTEM_LAST = -10L,
|
||||
|
||||
B_FLOATING_APP = 0L,
|
||||
B_MODAL_APP = 1L,
|
||||
B_NORMAL = 2L,
|
||||
B_FLOATING_ALL = 3L,
|
||||
B_MODAL_ALL = 4L,
|
||||
|
||||
B_SYSTEM_FIRST = 10L,
|
||||
};
|
||||
|
||||
class ServerWindow;
|
||||
@ -50,64 +53,66 @@ class Decorator;
|
||||
class DisplayDriver;
|
||||
class Desktop;
|
||||
|
||||
class PointerEvent
|
||||
{
|
||||
public:
|
||||
int32 code; //B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED
|
||||
//B_MOUSE_WHEEL_CHANGED
|
||||
bigtime_t when;
|
||||
BPoint where;
|
||||
float wheel_delta_x;
|
||||
float wheel_delta_y;
|
||||
int32 modifiers;
|
||||
int32 buttons; //B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
|
||||
//B_TERTIARY_MOUSE_BUTTON
|
||||
int32 clicks;
|
||||
class PointerEvent {
|
||||
public:
|
||||
int32 code; // B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED,
|
||||
// B_MOUSE_WHEEL_CHANGED
|
||||
bigtime_t when;
|
||||
BPoint where;
|
||||
float wheel_delta_x;
|
||||
float wheel_delta_y;
|
||||
int32 modifiers;
|
||||
int32 buttons; // B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
|
||||
// B_TERTIARY_MOUSE_BUTTON
|
||||
int32 clicks;
|
||||
};
|
||||
|
||||
class WinBorder : public Layer
|
||||
{
|
||||
public:
|
||||
WinBorder( const BRect &r,
|
||||
const char *name,
|
||||
const uint32 wlook,
|
||||
const uint32 wfeel,
|
||||
const uint32 wflags,
|
||||
const uint32 wwksindex,
|
||||
ServerWindow *win,
|
||||
DisplayDriver *driver);
|
||||
virtual ~WinBorder(void);
|
||||
class WinBorder : public Layer {
|
||||
public:
|
||||
WinBorder(const BRect &r,
|
||||
const char *name,
|
||||
const uint32 wlook,
|
||||
const uint32 wfeel,
|
||||
const uint32 wflags,
|
||||
const uint32 wwksindex,
|
||||
ServerWindow *win,
|
||||
DisplayDriver *driver);
|
||||
virtual ~WinBorder();
|
||||
|
||||
virtual void Draw(const BRect &r);
|
||||
|
||||
virtual void MoveBy(float x, float y);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
|
||||
virtual void RebuildFullRegion(void);
|
||||
virtual void RebuildFullRegion();
|
||||
|
||||
void SetSizeLimits( float minwidth,
|
||||
float maxwidth,
|
||||
float minheight,
|
||||
float maxheight);
|
||||
void SetSizeLimits(float minWidth,
|
||||
float maxWidth,
|
||||
float minHeight,
|
||||
float maxHeight);
|
||||
|
||||
click_type TellWhat(PointerEvent& evt) const;
|
||||
void MouseDown(click_type action);
|
||||
void MouseMoved(click_type action);
|
||||
void MouseUp(click_type action);
|
||||
void GetSizeLimits(float* minWidth,
|
||||
float* maxWidth,
|
||||
float* minHeight,
|
||||
float* maxHeight) const;
|
||||
|
||||
click_type MouseDown(const PointerEvent& evt);
|
||||
void MouseMoved(const PointerEvent& evt);
|
||||
void MouseUp(const PointerEvent& evt);
|
||||
|
||||
void UpdateColors(void);
|
||||
void UpdateDecorator(void);
|
||||
void UpdateFont(void);
|
||||
void UpdateScreen(void);
|
||||
void UpdateColors();
|
||||
void UpdateDecorator();
|
||||
void UpdateFont();
|
||||
void UpdateScreen();
|
||||
|
||||
virtual bool HasClient(void) { return false; }
|
||||
inline Decorator* GetDecorator(void) const { return fDecorator; }
|
||||
virtual bool HasClient() { return false; }
|
||||
inline Decorator* GetDecorator() const { return fDecorator; }
|
||||
|
||||
inline int32 Look(void) const { return fLook; }
|
||||
inline int32 Feel(void) const { return fFeel; }
|
||||
inline int32 Look() const { return fLook; }
|
||||
inline int32 Feel() const { return fFeel; }
|
||||
inline int32 Level() const { return fLevel; }
|
||||
inline uint32 WindowFlags(void) const { return fWindowFlags; }
|
||||
inline uint32 Workspaces(void) const { return fWorkspaces; }
|
||||
inline uint32 WindowFlags() const { return fWindowFlags; }
|
||||
inline uint32 Workspaces() const { return fWorkspaces; }
|
||||
|
||||
void HighlightDecorator(const bool &active);
|
||||
|
||||
@ -118,11 +123,13 @@ public:
|
||||
|
||||
FMWList fFMWList;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
friend class Layer;
|
||||
friend class ServerWindow;
|
||||
friend class RootLayer;
|
||||
|
||||
click_type _ActionFor(const PointerEvent& evt) const;
|
||||
|
||||
Decorator* fDecorator;
|
||||
Layer* fTopLayer;
|
||||
|
||||
@ -133,11 +140,17 @@ protected:
|
||||
int32 fMouseButtons;
|
||||
int32 fKeyModifiers;
|
||||
BPoint fLastMousePosition;
|
||||
BPoint fResizingClickOffset;
|
||||
|
||||
bool fIsClosing;
|
||||
bool fIsMinimizing;
|
||||
bool fIsZooming;
|
||||
|
||||
bool fIsDragging;
|
||||
bool fBringToFrontOnRelease;
|
||||
|
||||
bool fIsResizing;
|
||||
|
||||
bool fInUpdate;
|
||||
bool fRequestSent;
|
||||
|
||||
@ -147,10 +160,10 @@ protected:
|
||||
int32 fWindowFlags;
|
||||
uint32 fWorkspaces;
|
||||
|
||||
float fMinWidth,
|
||||
fMaxWidth;
|
||||
float fMinHeight,
|
||||
fMaxHeight;
|
||||
float fMinWidth;
|
||||
float fMaxWidth;
|
||||
float fMinHeight;
|
||||
float fMaxHeight;
|
||||
|
||||
int cnt; // for debugging
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user