diff --git a/docs/user/app/Message.dox b/docs/user/app/Message.dox index 6e1e28e90e..50f9e12914 100644 --- a/docs/user/app/Message.dox +++ b/docs/user/app/Message.dox @@ -1078,6 +1078,7 @@ \since BeOS R3 */ + /*! \fn status_t BMessage::AddFloat(const char* name, float aFloat) \brief Convenience method to add a \c float to the label \a name. @@ -1118,6 +1119,26 @@ */ +/*! + \fn status_t BMessage::AddColor(const char* name, rgb_color aColor) + \brief Convenience method to add a \c rgb_color to the label \a name. + + This method calls AddData() with the \c B_RGB_32_BIT_TYPE \a type. + + \param name The label to associate the data with. + \param aColor The value to store in the message. + + \returns A status code, \c B_OK on success or an error code. + + \see AddColor() for a more detailed overview of the inner workings. + \see FindColor() + \see GetColor() + \see ReplaceColor() + + \since Haiku R1 +*/ + + /*! \fn status_t BMessage::AddPointer(const char* name, const void* aPointer) \brief Convenience method to add a \c pointer to the label \a name. @@ -1807,6 +1828,48 @@ */ +/*! + \fn status_t BMessage::FindColor(const char* name, rgb_color* value) + \brief Find a color with the label \a name. + + This is an overloaded version of + FindColor(const char*, int32, rgb_color*) const + where the data is sought at \a index \c 0. + + \param name The label to which the data is associated. + \param value The object in which the data should be copied. + + \returns A status code, \c B_OK on success or an error code. + \retval B_OK The object now contains the requested data. + \retval B_NAME_NOT_FOUND There is no field with this \a name. + + \since Haiku R1 +*/ + + +/*! + \fn status_t BMessage::FindColor(const char* name, int32 index, + rgb_color* value) const + \brief Find a color at the label \a name at an \a index. + + This method looks for the data with the \c B_RGB_32_BIT_TYPE, and copies + it into a provided buffer. + + \param name The label to which the data is associated. + \param index The index from which the data should be copied. + \param value The object in which the data should be copied. + + \returns A status code, \c B_OK on success or an error code. + \retval B_OK The object now contains the requested data. + \retval B_BAD_INDEX The \a index does not exist. + \retval B_NAME_NOT_FOUND There is no field with this \a name. + + \see FindColor(const char*, rgb_color*) const + + \since BeOS R3 +*/ + + /*! \fn status_t BMessage::FindPointer(const char* name, void** pointer) const \brief Find a pointer at the label \a name. @@ -1849,7 +1912,7 @@ \retval B_BAD_INDEX The \a index does not exist. \retval B_NAME_NOT_FOUND There is no field with this \a name. - \see FindPointer(const char*, double*) const + \see FindPointer(const char*, void*) const \since BeOS R3 */ @@ -2569,6 +2632,49 @@ */ +/*! + \fn status_t BMessage::ReplaceColor(const char* name, rgb_color aColot) + \brief Replace a color at the label \a name. + + This method is an overloaded method of + ReplaceColor(const char*, int32, rgb_color). + It replaces the data at \a index \c 0. + + \param name The name associated with the data to replace. + \param aColor Where to store in the message. + + \returns A status code, \c B_OK on success or an error code. + \retval B_OK The operation succeeded. + \retval B_NAME_NOT_FOUND There is no field with this \a name. + + \since Haiku R1 +*/ + + +/*! + \fn status_t BMessage::ReplaceColor(const char* name, int32 index, + rgb_color aColor) + \brief Replace a rgb_color at the label \a name at a specified + \a index. + + The data at the specified \a name and \a index will be replaced, if it + matches the \c B_RGB_32_BIT_TYPE. + + \param name The name associated with the data to replace. + \param index The index in the array to replace. + \param aColor Where to store in the message. + + \returns A status code, \c B_OK on success or an error code. + \retval B_OK The operation succeeded. + \retval B_BAD_INDEX The index was out of range. + \retval B_NAME_NOT_FOUND There is no field with this \a name. + + \see ReplaceColor(const char*, rgb_color) + + \since Haiku R1 +*/ + + /*! \fn status_t BMessage::ReplacePointer(const char* name, const void* pointer) @@ -3513,6 +3619,38 @@ bool enabled = GetBool("enabled", false); */ +/*! + \fn rgb_color BMessage::GetColor(const char* name, rgb_color defaultValue) const + \brief Return the rgb_color value from message with \a name, or + \a defaultValue if not found. + + \param name The name of the item to retrieve. + \param defaultValue The value to use if the item specified by \a name + is not found. + + \return The item with \a name, or \a defaultValue if not found. + + \since Haiku R1 +*/ + + +/*! + \fn rgb_color BMessage::GetColor(const char* name, int32 index, + rgb_colorr defaultValue) const + \brief Return the rgb_color value from message with \a name and \a index, or + \a defaultValue if not found. + + \param name The name of the item to retrieve. + \param index The index of the item to retrieve if there is more than one. + \param defaultValue The value to use if the item specified by \a name + is not found. + + \return The item with \a name, or \a defaultValue if not found. + + \since Haiku R1 +*/ + + /*! \fn const char* BMessage::GetString(const char* name, const char* defaultValue) const diff --git a/docs/user/interface/View.dox b/docs/user/interface/View.dox index 80f776711a..6ae10e7545 100644 --- a/docs/user/interface/View.dox +++ b/docs/user/interface/View.dox @@ -1,13 +1,14 @@ /* - * Copyright 2011-2014 Haiku, Inc. All rights reserved. + * Copyright 2011-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * John Scipione, jscipione@gmail.com + * Joseph Groover, looncraz@looncraz.net * * Corresponds to: - * headers/os/interface/View.h hrev47274 - * src/kits/interface/View.cpp hrev47274 + * headers/os/interface/View.h hrev497** + * src/kits/interface/View.cpp hrev497** */ @@ -523,6 +524,15 @@ */ +/*! + \var B_FOLLOW_LEFT_TOP + \brief The margins between the left and top sides of the view and the left + and top sides of its parent remain constant. + + \since Haiku R1 +*/ + + /*! \class BView \ingroup interface @@ -596,12 +606,13 @@ if (Window()->LockLooper()) { Each view has a ViewColor() that fills the frame rectangle before the view does any drawing of its own. The default view color is white, you may - change the view color by calling SetViewColor(). A commonly used view color - is \c B_PANEL_BACKGROUND_COLOR which is a grey color used as the view color - of many Interface Kit classes. If you set the view color to - \c B_TRANSPARENT_COLOR then the Application Server won't erase the clipping - region of the view before updating, this should only be used if the view - erases itself by drawing on every pixel in the clipping region. + change the view color by calling SetViewColor() or, as of Haiku R1, + SetViewUIColor(). A commonly used view color is \c B_PANEL_BACKGROUND_COLOR + which is a user-defined color used as the view color of most applications. + If you set the view color to \c B_TRANSPARENT_COLOR then the Application Server + won't erase the clipping region of the view before updating, this should only + be used if the view erases itself by drawing on every pixel in the clipping + region. If you want to set the view color of a view to be the same as its parent you need to set it within the AttachedToWindow() method of the view like so: @@ -614,6 +625,7 @@ SetViewColor(Parent()->ViewColor()); */ + /*! \fn BView::BView(const char* name, uint32 flags, BLayout* layout) \brief Layout constructor. @@ -2057,6 +2069,59 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn bool BView::HasDefaultColors() const + \brief Tests if the view has any colors set. + + \return Boolean value, true if colors are not set. + + \since Haiku R1 +*/ + + +/*! + \fn bool BView::HasSystemColors() const + \brief Tests if the view is using system "panel" colors. + B_PANEL_BACKGROUND_COLOR for ViewUIColor() + B_PANEL_BACKGROUND_COLOR for LowUIColor() + B_PANEL_TEXT_COLOR for HighUIColor() + + \return Boolean value, true if colors are as described. + + \since Haiku R1 +*/ + + +/*! + \fn void BView::AdoptParentColors() + \brief Attempts to use the colors of any parent view. + Will adopt view, low, and high colors. + Should be called in AttachedToWindow() or AllAttached(). + + \since Haiku R1 +*/ + + +/*! + \fn void BView::AdoptSystemColors() + \brief Instructs view to use standard system "panel" colors. + B_PANEL_BACKGROUND_COLOR for ViewUIColor() + B_PANEL_BACKGROUND_COLOR for LowUIColor() + B_PANEL_TEXT_COLOR for HighUIColor() + + \since Haiku R1 +*/ + + +/*! + \fn void BView::AdoptViewColors(BView* view) + \brief Attempts to use the colors of a given view. + Will adopt view, low, and high colors. + + \since Haiku R1 +*/ + + /*! \fn void BView::SetHighColor(rgb_color color) \brief Set the high color of the view. @@ -2081,6 +2146,18 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn void BView::SetHighUIColor(color_which which, float tint) + \brief Set the high color of the view to a system constant. + The color will update live with user changes. + + \param which The color_which constant to set. + \param tint Optional tint value to use. + + \since Haiku R1 +*/ + + /*! \fn rgb_color BView::HighColor() const \brief Return the current high color. @@ -2094,6 +2171,20 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn color_which BView::HighUIColor(float* tint) const + \brief Return the current high color constant being used. + + \param tint Optional float pointer in which to store the tint + value used to modify the system color constant. + \return The current high color constant. + + \sa SetHighUIColor(color_which, float) + + \since Haiku R1 +*/ + + /*! \fn void BView::SetLowColor(rgb_color color) \brief Set the low color of the view. @@ -2117,6 +2208,18 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn void BView::SetLowUIColor(color_which which, float tint) + \brief Set the low color of the view to a system constant. + The color will update live with user changes. + + \param which The color_which constant to set. + \param tint Optional tint value to use. + + \since Haiku R1 +*/ + + /*! \fn rgb_color BView::LowColor() const \brief Return the current low color. @@ -2130,6 +2233,20 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn color_which BView::LowUIColor(float* tint) const + \brief Return the current low color constant being used. + + \param tint Optional float pointer in which to store the tint + value used to modify the system color constant. + \return The current low color constant. + + \sa SetLowUIColor(color_which, float) + + \since Haiku R1 +*/ + + /*! \fn void BView::SetViewColor(rgb_color color) \brief Set the view color of the view. @@ -2154,6 +2271,18 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn void BView::SetViewUIColor(color_which which, float tint) + \brief Set the view color of the view to a system constant. + The color will update live with user changes. + + \param which The color_which constant to set. + \param tint Optional tint value to use. + + \since Haiku R1 +*/ + + /*! \fn rgb_color BView::ViewColor() const \brief Return the current view color. @@ -2167,6 +2296,20 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn color_which BView::ViewUIColor(float* tint) const + \brief Return the current view color constant being used. + + \param tint Optional float pointer in which to store the tint + value used to modify the system color constant. + \return The current view color constant. + + \sa SetViewUIColor(color_which, float) + + \since Haiku R1 +*/ + + /*! \fn void BView::ForceFontAliasing(bool enable) \brief Turn anti-aliasing on and off when printing. @@ -3696,6 +3839,34 @@ SetViewColor(Parent()->ViewColor()); */ +/*! + \fn void BView::DelayedInvalidate(bigtime_t delay) + \brief Sends a message to App Server to redraw the entire view after + a certain, minimum, delay. Repeated calls to this method may be + merged, but the view is guaranteed to be redrawn after the delay + given in the first call of this method. + + \param delay The time, in microseconds, to wait until redrawing the view. + + \since Haiku R1 +*/ + + +/*! + \fn void BView::DelayedInvalidate(bigtime_t delay, BRect invalRect) + \brief Sends a message to App Server to redraw the portion of the view + specified by \a invalRect after a certain, minimum, delay. + Repeated calls to this method may be merged, but the invalidated + rect is guaranteed to be redrawn after the minimum delay given + by the first call of this method. + + \param delay The time, in microseconds, to wait until redrawing the view. + \param invalRect The rectangular area of the view to redraw. + + \since Haiku R1 +*/ + + /*! \fn void BView::InvertRect(BRect rect) \brief Inverts the colors within \a rect. diff --git a/docs/user/interface/Window.dox b/docs/user/interface/Window.dox index 7efc81b37a..4d7653bfbc 100644 --- a/docs/user/interface/Window.dox +++ b/docs/user/interface/Window.dox @@ -1,13 +1,14 @@ /* - * Copyright 2011-2014 Haiku, Inc. All rights reserved. + * Copyright 2011-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * John Scipione, jscipione@gmail.com + * Joseph Groover, looncraz@looncraz.net * * Corresponds to: - * headers/os/interface/Window.h hrev45799 - * src/kits/interface/Window.cpp hrev45799 + * headers/os/interface/Window.h hrev497** + * src/kits/interface/Window.cpp hrev497** */ @@ -1967,6 +1968,17 @@ */ +/*! + \fn bool BWindow::IsOffscreenWindow() const + \brief Tests if window is used for drawing into a BBitmap. + This is mostly used by the Interface Kit itself. + + \return True if the window is used for drawing into a BBitmap. + + \since Haiku R1 +*/ + + /*! \fn void BWindow::Show() \brief Shows the window on screen, places it frontmost on the screen, adds diff --git a/headers/os/app/AppDefs.h b/headers/os/app/AppDefs.h index 0a70d8b432..d48c58580a 100644 --- a/headers/os/app/AppDefs.h +++ b/headers/os/app/AppDefs.h @@ -67,10 +67,8 @@ enum { B_WORKSPACES_CHANGED = '_WCG', B_WORKSPACE_ACTIVATED = '_WAC', B_ZOOM = '_WZM', - _COLORS_UPDATED = '_CLU', - // Currently internal-use only. Later, public as B_COLORS_UPDATED - _FONTS_UPDATED = '_FNU', - // Currently internal-use only. Later, public as B_FONTS_UPDATED + B_COLORS_UPDATED = '_CLU', + B_FONTS_UPDATED = '_FNU', _APP_MENU_ = '_AMN', _BROWSER_MENUS_ = '_BRM', _MENU_EVENT_ = '_MEV', diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h index 7d7eab4977..077da8913e 100644 --- a/headers/os/app/Message.h +++ b/headers/os/app/Message.h @@ -29,6 +29,7 @@ class BHandler; class BString; class BStringList; struct entry_ref; +struct rgb_color; // Name lengths and Scripting specifiers @@ -154,6 +155,7 @@ public: status_t AddBool(const char* name, bool value); status_t AddFloat(const char* name, float value); status_t AddDouble(const char* name, double value); + status_t AddColor(const char* name, rgb_color value); status_t AddPointer(const char* name, const void* pointer); status_t AddMessenger(const char* name, @@ -241,6 +243,10 @@ public: double* value) const; status_t FindDouble(const char* name, int32 index, double* value) const; + status_t FindColor(const char* name, + rgb_color* value) const; + status_t FindColor(const char* name, int32 index, + rgb_color* value) const; status_t FindPointer(const char* name, void** pointer) const; status_t FindPointer(const char* name, int32 index, @@ -324,6 +330,10 @@ public: status_t ReplaceDouble(const char* name, double value); status_t ReplaceDouble(const char* name, int32 index, double value); + status_t ReplaceColor(const char* name, + rgb_color value); + status_t ReplaceColor(const char* name, int32 index, + rgb_color value); status_t ReplacePointer(const char* name, const void* pointer); status_t ReplacePointer(const char* name, int32 index, @@ -379,6 +389,7 @@ public: bool HasBool(const char* name, int32 n = 0) const; bool HasFloat(const char* name, int32 n = 0) const; bool HasDouble(const char* name, int32 n = 0) const; + bool HasColor(const char* name, int32 n = 0) const; bool HasPointer(const char* name, int32 n = 0) const; bool HasMessenger(const char* name, int32 n = 0) const; @@ -446,6 +457,10 @@ public: double defaultValue) const; double GetDouble(const char* name, int32 index, double defaultValue) const; + rgb_color GetColor(const char* name, + rgb_color defaultValue) const; + rgb_color GetColor(const char* name, int32 index, + rgb_color defaultValue) const; const char* GetString(const char* name, const char* defaultValue = NULL) const; const char* GetString(const char* name, int32 index, @@ -477,6 +492,7 @@ public: status_t SetUInt32(const char* name, uint32 value); status_t SetInt64(const char* name, int64 value); status_t SetUInt64(const char* name, uint64 value); + status_t SetColor(const char* name, rgb_color value); status_t SetPointer(const char* name, const void* value); status_t SetString(const char* name, const char* string); status_t SetString(const char* name, diff --git a/headers/os/interface/Box.h b/headers/os/interface/Box.h index 37bdf88d90..a3020d3602 100644 --- a/headers/os/interface/Box.h +++ b/headers/os/interface/Box.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2013 Haiku, Inc. All Rights Reserved. + * Copyright 2005-2015 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _BOX_H @@ -12,8 +12,7 @@ class BBox : public BView { public: BBox(BRect frame, const char* name = NULL, - uint32 resizingMode = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP, border_style border = B_FANCY_BORDER); diff --git a/headers/os/interface/Button.h b/headers/os/interface/Button.h index 703bb09e8c..71dfac5255 100644 --- a/headers/os/interface/Button.h +++ b/headers/os/interface/Button.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2014 Haiku, Inc. All rights reserved. + * Copyright 2001-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _BUTTON_H @@ -20,8 +20,7 @@ public: public: BButton(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE); BButton(const char* name, const char* label, diff --git a/headers/os/interface/ChannelControl.h b/headers/os/interface/ChannelControl.h index 3f9e5c8877..7df9cd9592 100644 --- a/headers/os/interface/ChannelControl.h +++ b/headers/os/interface/ChannelControl.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Haiku, Inc. All rights reserved. + * Copyright 2008-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CHANNEL_CONTROL_H @@ -18,8 +18,7 @@ public: BChannelControl(BRect frame, const char* name, const char* label, BMessage* model, int32 channelCount = 1, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BChannelControl(const char* name, const char* label, BMessage* model, diff --git a/headers/os/interface/ChannelSlider.h b/headers/os/interface/ChannelSlider.h index 8c3961ba55..5151ef14b1 100644 --- a/headers/os/interface/ChannelSlider.h +++ b/headers/os/interface/ChannelSlider.h @@ -1,5 +1,5 @@ /* - * Copyright 2009, Haiku, Inc. All rights reserved. + * Copyright 2009-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CHANNEL_SLIDER_H @@ -14,15 +14,13 @@ public: BChannelSlider(BRect area, const char* name, const char* label, BMessage* message, int32 channels = 1, - uint32 resizeMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizeMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BChannelSlider(BRect area, const char* name, const char* label, BMessage* message, orientation orientation, int32 channels = 1, - uint32 resizeMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizeMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BChannelSlider(const char* name, const char* label, BMessage* message, diff --git a/headers/os/interface/CheckBox.h b/headers/os/interface/CheckBox.h index 674a701555..056f034548 100644 --- a/headers/os/interface/CheckBox.h +++ b/headers/os/interface/CheckBox.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2014 Haiku, Inc. All rights reserved. + * Copyright 2001-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CHECK_BOX_H @@ -13,8 +13,7 @@ class BCheckBox : public BControl { public: BCheckBox(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BCheckBox(const char* name, const char* label, BMessage* message, uint32 flags diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index 6de91e289d..445f40bf8e 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2012, Haiku, Inc. All rights reserved. + * Copyright 2009-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CONTROL_LOOK_H @@ -85,6 +85,7 @@ public: B_PARTIALLY_ACTIVATED = 1 << 7, // like B_ACTIVATED, but for tri-state B_FLAT = 1 << 8, // flat look (e.g. button background) B_INVALID = 1 << 9, // invalid value, use B_FAILURE_COLOR + B_IS_CONTROL = 1 << 10, // use control colors B_BLEND_FRAME = 1 << 16, }; @@ -328,27 +329,32 @@ public: /*virtual*/ void DrawLabel(BView* view, const char* label, BRect rect, const BRect& updateRect, - const rgb_color& base, uint32 flags); + const rgb_color& base, uint32 flags, + const rgb_color* textColor = NULL); virtual void DrawLabel(BView* view, const char* label, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - const BAlignment& alignment); + const BAlignment& alignment, + const rgb_color* textColor = NULL); // TODO: Would be nice to have a (non-virtual) version of this method // which takes an array of labels and locations. That would save some // setup with the view graphics state. /*virtual*/ void DrawLabel(BView* view, const char* label, const rgb_color& base, uint32 flags, - const BPoint& where); + const BPoint& where, + const rgb_color* textColor = NULL); void DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, const BRect& updateRect, - const rgb_color& base, uint32 flags); + const rgb_color& base, uint32 flags, + const rgb_color* textColor = NULL); virtual void DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - const BAlignment& alignment); + const BAlignment& alignment, + const rgb_color* textColor = NULL); virtual void GetFrameInsets(frame_type frameType, uint32 flags, float& _left, float& _top, diff --git a/headers/os/interface/GraphicsDefs.h b/headers/os/interface/GraphicsDefs.h index 5e970c0a5b..e98d6deba0 100644 --- a/headers/os/interface/GraphicsDefs.h +++ b/headers/os/interface/GraphicsDefs.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 Haiku, Inc. All rights reserved. + * Copyright 2008-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _GRAPHICS_DEFS_H @@ -57,6 +57,8 @@ typedef struct rgb_color { return *this; } + int32 Brightness() const; + inline bool operator==(const rgb_color& other) const { @@ -88,6 +90,11 @@ make_color(uint8 red, uint8 green, uint8 blue, uint8 alpha = 255) #endif +rgb_color mix_color(rgb_color color1, rgb_color color2, uint8 amount); +rgb_color blend_color(rgb_color color1, rgb_color color2, uint8 amount); +rgb_color disable_color(rgb_color color, rgb_color background); + + extern const rgb_color B_TRANSPARENT_COLOR; extern const uint8 B_TRANSPARENT_MAGIC_CMAP8; extern const uint16 B_TRANSPARENT_MAGIC_RGBA15; diff --git a/headers/os/interface/InterfaceDefs.h b/headers/os/interface/InterfaceDefs.h index edfe7fdd23..ed550fb5a8 100644 --- a/headers/os/interface/InterfaceDefs.h +++ b/headers/os/interface/InterfaceDefs.h @@ -11,6 +11,7 @@ class BBitmap; +class BMessage; class BPoint; class BRect; @@ -296,6 +297,7 @@ enum bitmap_drawing_options { // Default UI Colors enum color_which { + B_NO_COLOR = 0, B_PANEL_BACKGROUND_COLOR = 1, B_PANEL_TEXT_COLOR = 10, B_DOCUMENT_BACKGROUND_COLOR = 11, @@ -310,6 +312,11 @@ enum color_which { B_SHINE_COLOR = 18, B_SHADOW_COLOR = 19, + B_LINK_TEXT_COLOR = 33, + B_LINK_HOVER_COLOR = 34, + B_LINK_VISITED_COLOR = 35, + B_LINK_ACTIVE_COLOR = 36, + B_MENU_BACKGROUND_COLOR = 2, B_MENU_SELECTED_BACKGROUND_COLOR = 6, B_MENU_ITEM_TEXT_COLOR = 7, @@ -463,7 +470,10 @@ void set_accept_first_click(bool acceptFirstClick); bool accept_first_click(); rgb_color ui_color(color_which which); +const char* ui_color_name(color_which which); +color_which which_ui_color(const char* name); void set_ui_color(const color_which& which, const rgb_color& color); +void set_ui_colors(const BMessage* colors); rgb_color tint_color(rgb_color color, float tint); extern "C" status_t _init_interface_kit_(); diff --git a/headers/os/interface/LayoutBuilder.h b/headers/os/interface/LayoutBuilder.h index 1c54716748..4ba372c9d3 100644 --- a/headers/os/interface/LayoutBuilder.h +++ b/headers/os/interface/LayoutBuilder.h @@ -457,9 +457,7 @@ Group::Group(BWindow* window, orientation orientation, fLayout(new BGroupLayout(orientation, spacing)) { window->SetLayout(fLayout); - - fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - // TODO: we get a white background if we don't do this + fLayout->Owner()->AdoptSystemColors(); } @@ -469,9 +467,11 @@ Group::Group(BView* view, orientation orientation, : fLayout(new BGroupLayout(orientation, spacing)) { + + if (view->HasDefaultColors()) + view->AdoptSystemColors(); + view->SetLayout(fLayout); - view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - // TODO: we get a white background if we don't do this } @@ -796,9 +796,7 @@ Grid::Grid(BWindow* window, float horizontalSpacing, fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) { window->SetLayout(fLayout); - - fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - // TODO: we get a white background if we don't do this + fLayout->Owner()->AdoptSystemColors(); } @@ -808,9 +806,10 @@ Grid::Grid(BView* view, float horizontalSpacing, : fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) { + if (view->HasDefaultColors()) + view->AdoptSystemColors(); + view->SetLayout(fLayout); - view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - // TODO: we get a white background if we don't do this } diff --git a/headers/os/interface/ListView.h b/headers/os/interface/ListView.h index 311fa77dd5..fe8a9afec9 100644 --- a/headers/os/interface/ListView.h +++ b/headers/os/interface/ListView.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 Haiku, Inc. All rights reserved. + * Copyright 2002-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LIST_VIEW_H @@ -26,8 +26,7 @@ public: BListView(BRect frame, const char* name, list_view_type type = B_SINGLE_SELECTION_LIST, - uint32 resizeMask = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizeMask = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); BListView(const char* name, diff --git a/headers/os/interface/MenuField.h b/headers/os/interface/MenuField.h index bbc95abf2a..d605419af0 100644 --- a/headers/os/interface/MenuField.h +++ b/headers/os/interface/MenuField.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013, Haiku, Inc. All rights reserved. + * Copyright 2006-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _MENU_FIELD_H @@ -17,14 +17,12 @@ class BMenuField : public BView { public: BMenuField(BRect frame, const char* name, const char* label, BMenu* menu, - uint32 resizingMode = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BMenuField(BRect frame, const char* name, const char* label, BMenu* menu, bool fixed_size, - uint32 resizingMode = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BMenuField(const char* name, const char* label, BMenu* menu, diff --git a/headers/os/interface/MultiChannelControl.h b/headers/os/interface/MultiChannelControl.h index 49733d654e..4f4aff03f9 100644 --- a/headers/os/interface/MultiChannelControl.h +++ b/headers/os/interface/MultiChannelControl.h @@ -1,5 +1,5 @@ /* - * Copyright 2009, Haiku, Inc. All rights reserved. + * Copyright 2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _MULTI_CHANNEL_CONTROL_H @@ -14,8 +14,7 @@ public: BMultiChannelControl(BRect frame, const char* name, const char* label, BMessage* message, int32 channelCount = 1, - uint32 resize = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resize = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BMultiChannelControl(BMessage* archive); virtual ~BMultiChannelControl(); diff --git a/headers/os/interface/OptionControl.h b/headers/os/interface/OptionControl.h index d038f5fc45..d5f28f373f 100644 --- a/headers/os/interface/OptionControl.h +++ b/headers/os/interface/OptionControl.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku, Inc. All rights reserved. + * Copyright 2001-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _OPTION_CONTROL_H @@ -18,8 +18,7 @@ class BOptionControl : public BControl { public: BOptionControl(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizeMask = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizeMask = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BOptionControl(const char* name, const char* label, BMessage* message, diff --git a/headers/os/interface/OptionPopUp.h b/headers/os/interface/OptionPopUp.h index 12110a7f24..2c6cc3dcfa 100644 --- a/headers/os/interface/OptionPopUp.h +++ b/headers/os/interface/OptionPopUp.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku, Inc. All rights reserved. + * Copyright 2001-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _OPTION_POP_UP_H @@ -16,13 +16,12 @@ class BOptionPopUp : public BOptionControl { public: BOptionPopUp(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizeMask = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizeMask = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BOptionPopUp(BRect frame, const char* name, const char* label, BMessage* message, bool fixed, uint32 resizeMask - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BOptionPopUp(const char* name, const char* label, BMessage* message, diff --git a/headers/os/interface/OutlineListView.h b/headers/os/interface/OutlineListView.h index 2dc58ce3f5..2d519da82b 100644 --- a/headers/os/interface/OutlineListView.h +++ b/headers/os/interface/OutlineListView.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013, Haiku, Inc. All rights reserved. + * Copyright 2006-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _OUTLINE_LIST_VIEW_H @@ -14,8 +14,7 @@ public: BOutlineListView(BRect frame, const char* name, list_view_type type = B_SINGLE_SELECTION_LIST, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); BOutlineListView(const char* name, diff --git a/headers/os/interface/PictureButton.h b/headers/os/interface/PictureButton.h index 904ff467bb..0a21ea94d2 100644 --- a/headers/os/interface/PictureButton.h +++ b/headers/os/interface/PictureButton.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Haiku, Inc. All rights reserved. + * Copyright 2001-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _PICTURE_BUTTON_H @@ -22,8 +22,7 @@ public: BPicture* off, BPicture* on, BMessage* message, uint32 behavior = B_ONE_STATE_BUTTON, - uint32 resizingMode = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flgs = B_WILL_DRAW | B_NAVIGABLE); BPictureButton(BMessage* archive); diff --git a/headers/os/interface/RadioButton.h b/headers/os/interface/RadioButton.h index 6a218db1d9..a1cd200cdb 100644 --- a/headers/os/interface/RadioButton.h +++ b/headers/os/interface/RadioButton.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Haiku, Inc. All rights reserved. + * Copyright 2001-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _RADIO_BUTTON_H @@ -14,8 +14,7 @@ class BRadioButton : public BControl { public: BRadioButton(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BRadioButton(const char* name, const char* label, BMessage* message, diff --git a/headers/os/interface/ScrollView.h b/headers/os/interface/ScrollView.h index 7abec2d5f4..d90c758762 100644 --- a/headers/os/interface/ScrollView.h +++ b/headers/os/interface/ScrollView.h @@ -15,8 +15,7 @@ class BScrollView : public BView { public: BScrollView(const char* name, BView* target, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = 0, bool horizontal = false, bool vertical = false, border_style border = B_FANCY_BORDER); diff --git a/headers/os/interface/Slider.h b/headers/os/interface/Slider.h index 42e81487c9..888bb8f205 100644 --- a/headers/os/interface/Slider.h +++ b/headers/os/interface/Slider.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013, Haiku, Inc. All rights reserved. + * Copyright 2001-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _SLIDER_H @@ -30,8 +30,7 @@ public: const char* label, BMessage* message, int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS); @@ -40,8 +39,7 @@ public: int32 minValue, int32 maxValue, orientation posture, thumb_style thumbType = B_BLOCK_THUMB, - uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS); diff --git a/headers/os/interface/SplitView.h b/headers/os/interface/SplitView.h index c4d3dd5f19..efa8a47f05 100644 --- a/headers/os/interface/SplitView.h +++ b/headers/os/interface/SplitView.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010, Haiku, Inc. All rights reserved. + * Copyright 2006-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _SPLIT_VIEW_H @@ -61,6 +61,7 @@ public: bool AddChild(int32 index, BLayoutItem* child, float weight); + virtual void AttachedToWindow(); virtual void Draw(BRect updateRect); virtual void DrawAfterChildren(BRect updateRect); virtual void MouseDown(BPoint where); diff --git a/headers/os/interface/StatusBar.h b/headers/os/interface/StatusBar.h index 789f3a9309..9f17da6c4a 100644 --- a/headers/os/interface/StatusBar.h +++ b/headers/os/interface/StatusBar.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2009, Haiku, Inc. All rights reserved. + * Copyright 2006-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _STATUS_BAR_H @@ -110,8 +110,9 @@ private: float fTextDivider; rgb_color fBarColor; bool fCustomBarHeight; + uint32 fInternalFlags; - uint32 _reserved[5]; + uint32 _reserved[4]; }; #endif // _STATUS_BAR_H diff --git a/headers/os/interface/StringView.h b/headers/os/interface/StringView.h index 820b41a7da..d75dfc2987 100644 --- a/headers/os/interface/StringView.h +++ b/headers/os/interface/StringView.h @@ -13,7 +13,7 @@ class BStringView : public BView { public: BStringView(BRect frame, const char* name, const char* text, uint32 resizingMode - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW); BStringView(const char* name, const char* text, uint32 flags = B_WILL_DRAW); diff --git a/headers/os/interface/TextControl.h b/headers/os/interface/TextControl.h index 49fd7b5321..3c8792bc71 100644 --- a/headers/os/interface/TextControl.h +++ b/headers/os/interface/TextControl.h @@ -21,8 +21,7 @@ public: BTextControl(BRect frame, const char* name, const char* label, const char* initialText, BMessage* message, - uint32 resizeMask - = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizeMask = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BTextControl(const char* name, const char* label, const char* initialText, diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index 84079e1cb1..ddec3dfba8 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -107,6 +107,7 @@ inline uint32 _rule_(uint32 r1, uint32 r2, uint32 r3, uint32 r4) #define B_FOLLOW_TOP_BOTTOM _rule_(_VIEW_TOP_, 0, _VIEW_BOTTOM_, 0) #define B_FOLLOW_V_CENTER _rule_(_VIEW_CENTER_, 0, _VIEW_CENTER_, 0) +#define B_FOLLOW_LEFT_TOP B_FOLLOW_TOP | B_FOLLOW_LEFT class BBitmap; class BCursor; @@ -242,32 +243,38 @@ public: void SetViewCursor(const BCursor* cursor, bool sync = true); + bool HasDefaultColors() const; + bool HasSystemColors() const; + void AdoptParentColors(); + void AdoptSystemColors(); + void AdoptViewColors(BView* view); + virtual void SetViewColor(rgb_color color); void SetViewColor(uchar red, uchar green, uchar blue, uchar alpha = 255); rgb_color ViewColor() const; + void SetViewUIColor(color_which which, + float tint = B_NO_TINT); + color_which ViewUIColor(float* tint = NULL) const; + void SetViewBitmap(const BBitmap* bitmap, BRect srcRect, BRect dstRect, - uint32 followFlags - = B_FOLLOW_TOP | B_FOLLOW_LEFT, + uint32 followFlags = B_FOLLOW_LEFT_TOP, uint32 options = B_TILE_BITMAP); void SetViewBitmap(const BBitmap* bitmap, - uint32 followFlags - = B_FOLLOW_TOP | B_FOLLOW_LEFT, + uint32 followFlags = B_FOLLOW_LEFT_TOP, uint32 options = B_TILE_BITMAP); void ClearViewBitmap(); status_t SetViewOverlay(const BBitmap* overlay, BRect srcRect, BRect dstRect, rgb_color* colorKey, - uint32 followFlags - = B_FOLLOW_TOP | B_FOLLOW_LEFT, + uint32 followFlags = B_FOLLOW_LEFT_TOP, uint32 options = 0); status_t SetViewOverlay(const BBitmap* overlay, rgb_color* colorKey, - uint32 followFlags - = B_FOLLOW_TOP | B_FOLLOW_LEFT, + uint32 followFlags = B_FOLLOW_LEFT_TOP, uint32 options = 0); void ClearViewOverlay(); @@ -276,11 +283,19 @@ public: uchar alpha = 255); rgb_color HighColor() const; + void SetHighUIColor(color_which which, + float tint = B_NO_TINT); + color_which HighUIColor(float* tint = NULL) const; + virtual void SetLowColor(rgb_color color); void SetLowColor(uchar red, uchar green, uchar blue, uchar alpha = 255); rgb_color LowColor() const; + void SetLowUIColor(color_which which, + float tint = B_NO_TINT); + color_which LowUIColor(float* tint = NULL) const; + void SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit = B_DEFAULT_MITER_LIMIT); @@ -495,6 +510,9 @@ public: void Invalidate(BRect invalRect); void Invalidate(const BRegion* invalRegion); void Invalidate(); + void DelayedInvalidate(bigtime_t delay); + void DelayedInvalidate(bigtime_t delay, + BRect invalRect); void SetDiskMode(char* filename, long offset); @@ -691,9 +709,11 @@ private: void _Activate(bool state); void _Attach(); + void _ColorsUpdated(BMessage* message); void _Detach(); void _Draw(BRect screenUpdateRect); void _DrawAfterChildren(BRect screenUpdateRect); + void _FontsUpdated(BMessage*); void _Pulse(); void _UpdateStateForRemove(); diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 586bfb7f06..c59a5494b2 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -272,7 +272,7 @@ public: void InvalidateLayout(bool descendants = false); void Layout(bool force); - + bool IsOffscreenWindow() const; private: // FBC padding and forbidden methods virtual void _ReservedWindow2(); diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index d5f42f0907..73b0a7cfac 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -293,11 +293,18 @@ enum { AS_VIEW_SET_PEN_SIZE, AS_VIEW_GET_PEN_SIZE, AS_VIEW_SET_HIGH_COLOR, + AS_VIEW_SET_HIGH_UI_COLOR, AS_VIEW_SET_LOW_COLOR, + AS_VIEW_SET_LOW_UI_COLOR, AS_VIEW_SET_VIEW_COLOR, + AS_VIEW_SET_VIEW_UI_COLOR, AS_VIEW_GET_HIGH_COLOR, + AS_VIEW_GET_HIGH_UI_COLOR, AS_VIEW_GET_LOW_COLOR, + AS_VIEW_GET_LOW_UI_COLOR, AS_VIEW_GET_VIEW_COLOR, + AS_VIEW_GET_VIEW_UI_COLOR, + AS_VIEW_PRINT_ALIASING, AS_VIEW_CLIP_TO_PICTURE, AS_VIEW_GET_CLIP_REGION, @@ -314,6 +321,7 @@ enum { AS_VIEW_COPY_BITS, AS_VIEW_DRAW_PICTURE, AS_VIEW_INVALIDATE_RECT, + AS_VIEW_DELAYED_INVALIDATE_RECT, AS_VIEW_INVALIDATE_REGION, AS_VIEW_INVERT_RECT, AS_VIEW_MOVE_TO, @@ -355,6 +363,9 @@ enum { AS_VIEW_CLIP_TO_RECT, AS_VIEW_CLIP_TO_SHAPE, + // Internal messages + AS_COLOR_MAP_UPDATED, + AS_LAST_CODE }; diff --git a/headers/private/app/ServerProtocolStructs.h b/headers/private/app/ServerProtocolStructs.h index 8eec0aa9c1..ff986366e1 100644 --- a/headers/private/app/ServerProtocolStructs.h +++ b/headers/private/app/ServerProtocolStructs.h @@ -18,6 +18,10 @@ struct ViewSetStateInfo { float penSize; rgb_color highColor; rgb_color lowColor; + color_which whichHighColor; + color_which whichLowColor; + float whichHighColorTint; + float whichLowColorTint; ::pattern pattern; drawing_mode drawingMode; BPoint origin; diff --git a/headers/private/app/ServerReadOnlyMemory.h b/headers/private/app/ServerReadOnlyMemory.h index 238498111b..f62e3c0236 100644 --- a/headers/private/app/ServerReadOnlyMemory.h +++ b/headers/private/app/ServerReadOnlyMemory.h @@ -13,11 +13,11 @@ #include -// Update this constant with the largest color constant excluding -// B_SUCCESS_COLOR and B_FAILURE_COLOR. -// If you add a constant with index greater than 100 you'll have to add -// to the second operand. -static const int32 kColorWhichCount = B_SCROLL_BAR_THUMB_COLOR + 3; +// Update kColorWhichLastContinuous with the largest color constant which +// leaves no gaps in the color_which integer values. +static const int32 kColorWhichLastContinuous = B_LINK_ACTIVE_COLOR; +static const int32 kColorWhichCount = kColorWhichLastContinuous + 3; + // + 1 for index-offset, + 2 for B_SUCCESS_COLOR, B_FAILURE_COLOR struct server_read_only_memory { diff --git a/headers/private/interface/AbstractSpinner.h b/headers/private/interface/AbstractSpinner.h index 9d961b1260..e822299d37 100644 --- a/headers/private/interface/AbstractSpinner.h +++ b/headers/private/interface/AbstractSpinner.h @@ -39,7 +39,7 @@ class BAbstractSpinner : public BControl { public: BAbstractSpinner(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BAbstractSpinner(const char* name, const char* label, BMessage* message, diff --git a/headers/private/interface/ColorTools.h b/headers/private/interface/ColorTools.h deleted file mode 100644 index 8f7e78e66e..0000000000 --- a/headers/private/interface/ColorTools.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -/******************************************************************************* -/ -/ File: ColorTools.h -/ -/ Description: Additional experimental color manipulation functions. -/ -/ Copyright 2000, Be Incorporated, All Rights Reserved -/ -*******************************************************************************/ - - -#ifndef _COLOR_TOOLS_H -#define _COLOR_TOOLS_H - -#include - -#if B_BEOS_VERSION <= B_BEOS_VERSION_5 - -namespace BExperimental { - -// Mix two colors together, ignoring their relative alpha channels. -// If amount is 0, the result is color1; if 255, the result is color2; -// if another value, it is somewhere in-between. The resulting alpha -// channel is mixed exactly like the other color channels. -rgb_color mix_color(rgb_color color1, rgb_color color2, uint8 amount); - -// Blend two colors together, weighting by their relative alpha channels. -// The resulting color is the same as mix_color(), except that the amount -// used from color1 and color2's color channels is dependent on that color's -// alpha channel. For example, if color1.alpha is 0 and color2.alpha is -// 255, the resulting red, green, and blue values will be the same as those -// in color2, regardless of 'amount'. -rgb_color blend_color(rgb_color color1, rgb_color color2, uint8 amount); - -// Return a color that is the disabled representation of 'color' when drawn -// on a solid color 'background'. -rgb_color disable_color(rgb_color color, rgb_color background); - -} // namespace BExperimental - -using namespace BExperimental; - -#endif - -#endif diff --git a/headers/private/interface/ColumnListView.h b/headers/private/interface/ColumnListView.h index 76fd0bc916..5cfdf13a76 100644 --- a/headers/private/interface/ColumnListView.h +++ b/headers/private/interface/ColumnListView.h @@ -63,10 +63,10 @@ class RecursiveOutlineIterator; } // ns BPrivate -class BField; -class BRow; class BColumn; class BColumnListView; +class BField; +class BRow; enum LatchType { B_NO_LATCH = 0, @@ -353,6 +353,7 @@ public: // Appearance (NEW STYLE) void SetColor(ColumnListViewColor colorIndex, rgb_color color); + void ResetColors(); void SetFont(ColumnListViewFont fontIndex, const BFont* font, uint32 mask = B_FONT_ALL); @@ -396,12 +397,14 @@ protected: private: void _Init(); + void _UpdateColors(); void _GetChildViewRects(const BRect& bounds, BRect& titleRect, BRect& outlineRect, BRect& vScrollBarRect, BRect& hScrollBarRect); rgb_color fColorList[B_COLOR_TOTAL]; + bool fCustomColors; BPrivate::TitleView* fTitleView; BPrivate::OutlineView* fOutlineView; BList fColumns; diff --git a/headers/private/interface/DecimalSpinner.h b/headers/private/interface/DecimalSpinner.h index 46161c70bd..9c97367550 100644 --- a/headers/private/interface/DecimalSpinner.h +++ b/headers/private/interface/DecimalSpinner.h @@ -16,7 +16,7 @@ class BDecimalSpinner : public BAbstractSpinner { public: BDecimalSpinner(BRect frame, const char* name, const char* label, BMessage* message, - uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 resizingMode = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BDecimalSpinner(const char* name, const char* label, BMessage* message, diff --git a/headers/private/interface/ViewPrivate.h b/headers/private/interface/ViewPrivate.h index 7d642d7836..676454a03a 100644 --- a/headers/private/interface/ViewPrivate.h +++ b/headers/private/interface/ViewPrivate.h @@ -42,8 +42,11 @@ enum { B_VIEW_PATTERN_BIT = 0x00020000, B_VIEW_TRANSFORM_BIT = 0x00040000, B_VIEW_FILL_RULE_BIT = 0x00080000, + B_VIEW_WHICH_VIEW_COLOR_BIT = 0x00100000, + B_VIEW_WHICH_LOW_COLOR_BIT = 0x00200000, + B_VIEW_WHICH_HIGH_COLOR_BIT = 0x00400000, - B_VIEW_ALL_BITS = 0x000fffff, + B_VIEW_ALL_BITS = 0x00ffffff, // these used for archiving only B_VIEW_RESIZE_BIT = 0x00001000, @@ -107,6 +110,15 @@ class ViewState { // This one is not affected by pop state/push state rgb_color view_color; + color_which which_view_color; + float which_view_color_tint; + + // these are cached values + color_which which_low_color; + float which_low_color_tint; + + color_which which_high_color; + float which_high_color_tint; ::pattern pattern; diff --git a/headers/private/shared/CalendarView.h b/headers/private/shared/CalendarView.h index b7f0dcee66..d48c9915df 100644 --- a/headers/private/shared/CalendarView.h +++ b/headers/private/shared/CalendarView.h @@ -26,8 +26,7 @@ namespace BPrivate { class BCalendarView : public BView, public BInvoker { public: BCalendarView(BRect frame, const char* name, - uint32 resizeMask = B_FOLLOW_LEFT - | B_FOLLOW_TOP, + uint32 resizeMask = B_FOLLOW_LEFT_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index c1c3f33b62..4de804b6c6 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -1044,6 +1044,8 @@ BApplication::DispatchMessage(BMessage* message, BHandler* handler) return; } + message->PrintToStream(); + switch (message->what) { case B_ARGV_RECEIVED: _ArgvReceived(message); @@ -1102,6 +1104,23 @@ BApplication::DispatchMessage(BMessage* message, BHandler* handler) break; } + case B_COLORS_UPDATED: + { + AutoLocker listLock(gLooperList); + if (!listLock.IsLocked()) + break; + + BWindow* window = NULL; + uint32 count = gLooperList.CountLoopers(); + for (uint32 index = 0; index < count; ++index) { + window = dynamic_cast(gLooperList.LooperAt(index)); + if (window == NULL || (window != NULL && window->fOffscreen)) + continue; + window->PostMessage(message); + } + break; + } + case _SHOW_DRAG_HANDLES_: { bool show; diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index d1824937e7..eac16f4b33 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -735,6 +736,14 @@ BMessage::_PrintToStream(const char* indent) const break; } + case B_RGB_32_BIT_TYPE: + { + rgb_color* color = (rgb_color*)pointer; + printf("rgb_color(%u, %u, %u, %u)\n", color->red, + color->green, color->blue, color->alpha); + break; + } + default: { printf("(type = '%.4s')(size = %ld)\n", (char*)&value, @@ -2494,6 +2503,7 @@ DEFINE_FUNCTIONS(uint64, UInt64, B_UINT64_TYPE); DEFINE_FUNCTIONS(bool, Bool, B_BOOL_TYPE); DEFINE_FUNCTIONS(float, Float, B_FLOAT_TYPE); DEFINE_FUNCTIONS(double, Double, B_DOUBLE_TYPE); +DEFINE_FUNCTIONS(rgb_color, Color, B_RGB_32_BIT_TYPE); #undef DEFINE_FUNCTIONS @@ -2577,6 +2587,7 @@ DEFINE_SET_GET_FUNCTIONS(uint64, UInt64, B_UINT64_TYPE); DEFINE_SET_GET_FUNCTIONS(bool, Bool, B_BOOL_TYPE); DEFINE_SET_GET_FUNCTIONS(float, Float, B_FLOAT_TYPE); DEFINE_SET_GET_FUNCTIONS(double, Double, B_DOUBLE_TYPE); +DEFINE_SET_GET_FUNCTIONS(rgb_color, Color, B_RGB_32_BIT_TYPE); #undef DEFINE_SET_GET_FUNCTION diff --git a/src/kits/interface/ColorTools.cpp b/src/kits/interface/ColorTools.cpp deleted file mode 100644 index e4aea31624..0000000000 --- a/src/kits/interface/ColorTools.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -/******************************************************************************* -/ -/ File: ColorTools.cpp -/ -/ Description: Additional experimental color manipulation functions. -/ -/ Copyright 2000, Be Incorporated, All Rights Reserved -/ -*******************************************************************************/ - -#include "ColorTools.h" - -#if B_BEOS_VERSION <= B_BEOS_VERSION_MAUI - -namespace BExperimental { - -#if DEBUG -#define DB_INLINE -#else -#define DB_INLINE inline -#endif - -static DB_INLINE void mix_color_func(rgb_color* target, const rgb_color other, uint8 amount) -{ - target->red = (uint8)( ((int16(other.red)-int16(target->red))*amount)/255 - + target->red ); - target->green = (uint8)( ((int16(other.green)-int16(target->green))*amount)/255 - + target->green ); - target->blue = (uint8)( ((int16(other.blue)-int16(target->blue))*amount)/255 - + target->blue ); - target->alpha = (uint8)( ((int16(other.alpha)-int16(target->alpha))*amount)/255 - + target->alpha ); -} - -static DB_INLINE void blend_color_func(rgb_color* target, const rgb_color other, uint8 amount) -{ - const uint8 alphaMix = (uint8)( ((int16(other.alpha)-int16(255-target->alpha))*amount)/255 - + (255-target->alpha) ); - target->red = (uint8)( ((int16(other.red)-int16(target->red))*alphaMix)/255 - + target->red ); - target->green = (uint8)( ((int16(other.green)-int16(target->green))*alphaMix)/255 - + target->green ); - target->blue = (uint8)( ((int16(other.blue)-int16(target->blue))*alphaMix)/255 - + target->blue ); - target->alpha = (uint8)( ((int16(other.alpha)-int16(target->alpha))*amount)/255 - + target->alpha ); -} - -static DB_INLINE void disable_color_func(rgb_color* target, const rgb_color background) -{ - blend_color_func(target, background, 255-70); -} - -// -------------------------------------------------------------------------- - -rgb_color mix_color(rgb_color color1, rgb_color color2, uint8 amount) -{ - mix_color_func(&color1, color2, amount); - return color1; -} - -rgb_color blend_color(rgb_color color1, rgb_color color2, uint8 amount) -{ - blend_color_func(&color1, color2, amount); - return color1; -} - -rgb_color disable_color(rgb_color color, rgb_color background) -{ - disable_color_func(&color, background); - return color; -} - -} - -#endif diff --git a/src/kits/interface/GraphicsDefs.cpp b/src/kits/interface/GraphicsDefs.cpp index db59bd596f..b40e395b7d 100644 --- a/src/kits/interface/GraphicsDefs.cpp +++ b/src/kits/interface/GraphicsDefs.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -36,6 +36,58 @@ const uint32 B_TRANSPARENT_MAGIC_RGBA32_BIG = 0x77747700; const struct screen_id B_MAIN_SCREEN_ID = {0}; +// rgb_color +int32 +rgb_color::Brightness() const +{ + return ((int32)red * 41 + (int32)green * 187 + (int32)blue * 28) >> 8; +} + + +// Mix two colors without respect for their alpha values +rgb_color +mix_color(rgb_color color1, rgb_color color2, uint8 amount) +{ + color1.red = (uint8)(((int16(color2.red) - int16(color1.red)) * amount) + / 255 + color1.red); + color1.green = (uint8)(((int16(color2.green) - int16(color1.green)) + * amount) / 255 + color1.green); + color1.blue = (uint8)(((int16(color2.blue) - int16(color1.blue)) * amount) + / 255 + color1.blue ); + color1.alpha = (uint8)(((int16(color2.alpha) - int16(color1.alpha)) + * amount) / 255 + color1.alpha ); + + return color1; +} + + +// Mix two colors, respecting their alpha values. +rgb_color +blend_color(rgb_color color1, rgb_color color2, uint8 amount) +{ + const uint8 alphaMix = (uint8)(((int16(color2.alpha) - int16(255 + - color1.alpha)) * amount) / 255 + (255 - color1.alpha)); + + color1.red = (uint8)(((int16(color2.red) - int16(color1.red)) * alphaMix) + / 255 + color1.red ); + color1.green = (uint8)(((int16(color2.green) - int16(color1.green)) + * alphaMix) / 255 + color1.green); + color1.blue = (uint8)(((int16(color2.blue) - int16(color1.blue)) + * alphaMix) / 255 + color1.blue); + color1.alpha = (uint8)(((int16(color2.alpha) - int16(color1.alpha)) + * amount) / 255 + color1.alpha); + + return color1; +} + + +rgb_color +disable_color(rgb_color color, rgb_color background) +{ + return mix_color(color, background, 185); +} + + status_t get_pixel_size_for(color_space space, size_t *pixelChunk, size_t *rowAlignment, size_t *pixelsPerChunk) diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index 880f786858..97017b31e4 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -8,6 +8,7 @@ * Axel Dörfler, axeld@pinc-software.de * Michael Lotz * Wim van der Meer + * Joseph Groover */ @@ -39,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +104,10 @@ static const rgb_color _kDefaultColors[kColorWhichCount] = { {0, 0, 0, 255}, // B_LIST_ITEM_TEXT_COLOR {0, 0, 0, 255}, // B_LIST_SELECTED_ITEM_TEXT_COLOR {216, 216, 216, 255}, // B_SCROLL_BAR_THUMB_COLOR + {51, 102, 187, 255}, // B_LINK_TEXT_COLOR + {102, 152, 203, 255}, // B_LINK_HOVER_COLOR + {145, 112, 155, 255}, // B_LINK_VISITED_COLOR + {121, 142, 203, 255}, // B_LINK_ACTIVE_COLOR // 100... {46, 204, 64, 255}, // B_SUCCESS_COLOR {255, 65, 54, 255}, // B_FAILURE_COLOR @@ -110,6 +116,50 @@ static const rgb_color _kDefaultColors[kColorWhichCount] = { const rgb_color* BPrivate::kDefaultColors = &_kDefaultColors[0]; +static const char* kColorNames[kColorWhichCount] = { + "B_PANEL_BACKGROUND_COLOR", + "B_MENU_BACKGROUND_COLOR", + "B_WINDOW_TAB_COLOR", + "B_KEYBOARD_NAVIGATION_COLOR", + "B_DESKTOP_COLOR", + "B_MENU_SELECTED_BACKGROUND_COLOR", + "B_MENU_ITEM_TEXT_COLOR", + "B_MENU_SELECTED_ITEM_TEXT_COLOR", + "B_MENU_SELECTED_BORDER_COLOR", + "B_PANEL_TEXT_COLOR", + "B_DOCUMENT_BACKGROUND_COLOR", + "B_DOCUMENT_TEXT_COLOR", + "B_CONTROL_BACKGROUND_COLOR", + "B_CONTROL_TEXT_COLOR", + "B_CONTROL_BORDER_COLOR", + "B_CONTROL_HIGHLIGHT_COLOR", + "B_NAVIGATION_PULSE_COLOR", + "B_SHINE_COLOR", + "B_SHADOW_COLOR", + "B_TOOLTIP_BACKGROUND_COLOR", + "B_TOOLTIP_TEXT_COLOR", + "B_WINDOW_TEXT_COLOR", + "B_WINDOW_INACTIVE_TAB_COLOR", + "B_WINDOW_INACTIVE_TEXT_COLOR", + "B_WINDOW_BORDER_COLOR", + "B_WINDOW_INACTIVE_BORDER_COLOR", + "B_CONTROL_MARK_COLOR", + "B_LIST_BACKGROUND_COLOR", + "B_LIST_SELECTED_BACKGROUND_COLOR", + "B_LIST_ITEM_TEXT_COLOR", + "B_LIST_SELECTED_ITEM_TEXT_COLOR", + "B_SCROLL_BAR_THUMB_COLOR", + "B_LINK_TEXT_COLOR", + "B_LINK_HOVER_COLOR", + "B_LINK_VISITED_COLOR", + "B_LINK_ACTIVE_COLOR", + // 100... + "B_SUCCESS_COLOR", + "B_FAILURE_COLOR", + NULL +}; + + namespace BPrivate { @@ -1079,14 +1129,51 @@ ui_color(color_which which) if (be_app != NULL) { server_read_only_memory* shared = BApplication::Private::ServerReadOnlyMemory(); - if (shared != NULL) + if (shared != NULL) { + // check for unset colors + if (shared->colors[index] == B_TRANSPARENT_COLOR) + shared->colors[index] = kDefaultColors[index]; + return shared->colors[index]; + } } return kDefaultColors[index]; } +const char* +ui_color_name(color_which which) +{ + // Suppress warnings for B_NO_COLOR. + if (which == B_NO_COLOR) + return NULL; + + int32 index = color_which_to_index(which); + if (index < 0 || index >= kColorWhichCount) { + fprintf(stderr, "ui_color_name(): unknown color_which %d\n", which); + return NULL; + } + + return kColorNames[index]; +} + + +color_which +which_ui_color(const char* name) +{ + if (name == NULL) + return B_NO_COLOR; + + for (int32 index = 0; index < kColorWhichCount; ++index) { + if (!strcmp(kColorNames[index], name)) + return index_to_color_which(index); + } + + return B_NO_COLOR; +} + + void set_ui_color(const color_which &which, const rgb_color &color) { @@ -1096,7 +1183,10 @@ set_ui_color(const color_which &which, const rgb_color &color) return; } - BPrivate::AppServerLink link; + if (ui_color(which) == color) + return; + + BPrivate::DesktopLink link; link.StartMessage(AS_SET_UI_COLOR); link.Attach(which); link.Attach(color); @@ -1104,6 +1194,48 @@ set_ui_color(const color_which &which, const rgb_color &color) } +void +set_ui_colors(const BMessage* colors) +{ + if (colors == NULL) + return; + + int32 count = 0; + int32 index = 0; + char* name = NULL; + type_code type; + rgb_color color; + color_which which = B_NO_COLOR; + + BPrivate::DesktopLink desktop; + if (desktop.InitCheck() != B_OK) + return; + + desktop.StartMessage(AS_SET_UI_COLORS); + desktop.Attach(false); + + // Only colors with names that map to system colors will get through. + while (colors->GetInfo(B_RGB_32_BIT_TYPE, index, &name, &type) == B_OK) { + + which = which_ui_color(name); + ++index; + + if (which == B_NO_COLOR || colors->FindColor(name, &color) != B_OK) + continue; + + desktop.Attach(which); + desktop.Attach(color); + ++count; + } + + if (count == 0) + return; + + desktop.Attach(B_NO_COLOR); + desktop.Flush(); +} + + rgb_color tint_color(rgb_color color, float tint) { diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index c02b07b8d2..561005e328 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -57,7 +57,6 @@ for architectureObject in [ MultiArchSubDirSetup ] { CheckBox.cpp ColorConversion.cpp ColorControl.cpp - ColorTools.cpp Control.cpp ControlLook.cpp DecorInfo.cpp diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 0a0f2b4e98..21b563f1c0 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -8,6 +8,7 @@ * Adrian Oanca, adioanca@cotty.iren.ro * Ingo Weinhold. ingo_weinhold@gmx.de * Julian Harnath, julian.harnath@rwth-aachen.de + * Joseph Groover, looncraz@looncraz.net */ @@ -141,6 +142,14 @@ ViewState::ViewState() high_color = (rgb_color){ 0, 0, 0, 255 }; low_color = (rgb_color){ 255, 255, 255, 255 }; view_color = low_color; + which_view_color = B_NO_COLOR; + which_view_color_tint = B_NO_TINT; + + which_high_color = B_NO_COLOR; + which_high_color_tint = B_NO_TINT; + + which_low_color = B_NO_COLOR; + which_low_color_tint = B_NO_TINT; pattern = B_SOLID_HIGH; drawing_mode = B_OP_COPY; @@ -220,6 +229,10 @@ ViewState::UpdateServerState(BPrivate::PortLink &link) info.penSize = pen_size; info.highColor = high_color; info.lowColor = low_color; + info.whichHighColor = which_high_color; + info.whichLowColor = which_low_color; + info.whichHighColorTint = which_high_color_tint; + info.whichLowColorTint = which_low_color_tint; info.pattern = pattern; info.drawingMode = drawing_mode; info.origin = origin; @@ -456,7 +469,7 @@ BView::BView(BMessage* archive) | B_FONT_SHEAR | B_FONT_ROTATION); } - int32 color; + int32 color = 0; if (archive->FindInt32("_color", 0, &color) == B_OK) SetHighColor(get_rgb_color(color)); if (archive->FindInt32("_color", 1, &color) == B_OK) @@ -464,6 +477,29 @@ BView::BView(BMessage* archive) if (archive->FindInt32("_color", 2, &color) == B_OK) SetViewColor(get_rgb_color(color)); + float tint = B_NO_TINT; + if (archive->FindInt32("_uicolor", 0, &color) == B_OK + && color != B_NO_COLOR) { + if (archive->FindFloat("_uitint", 0, &tint) != B_OK) + tint = B_NO_TINT; + + SetHighUIColor((color_which)color, tint); + } + if (archive->FindInt32("_uicolor", 1, &color) == B_OK + && color != B_NO_COLOR) { + if (archive->FindFloat("_uitint", 1, &tint) != B_OK) + tint = B_NO_TINT; + + SetLowUIColor((color_which)color, tint); + } + if (archive->FindInt32("_uicolor", 2, &color) == B_OK + && color != B_NO_COLOR) { + if (archive->FindFloat("_uitint", 2, &tint) != B_OK) + tint = B_NO_TINT; + + SetViewUIColor((color_which)color, tint); + } + uint32 evMask; uint32 options; if (archive->FindInt32("_evmask", 0, (int32*)&evMask) == B_OK @@ -595,6 +631,20 @@ BView::Archive(BMessage* data, bool deep) const if (ret == B_OK) ret = data->AddInt32("_color", get_uint32_color(ViewColor())); + if (ret == B_OK) + ret = data->AddInt32("_uicolor", (int32)HighUIColor()); + if (ret == B_OK) + ret = data->AddInt32("_uicolor", (int32)LowUIColor()); + if (ret == B_OK) + ret = data->AddInt32("_uicolor", (int32)ViewUIColor()); + + if (ret == B_OK) + ret = data->AddFloat("_uitint", fState->which_high_color_tint); + if (ret == B_OK) + ret = data->AddFloat("_uitint", fState->which_low_color_tint); + if (ret == B_OK) + ret = data->AddFloat("_uitint", fState->which_view_color_tint); + // NOTE: we do not use this flag any more // if ( 1 ){ // ret = data->AddInt32("_dbuf", 1); @@ -2304,6 +2354,8 @@ BView::PenSize() const void BView::SetHighColor(rgb_color color) { + SetHighUIColor(B_NO_COLOR); + // are we up-to-date already? if (fState->IsValid(B_VIEW_HIGH_COLOR_BIT) && fState->high_color == color) @@ -2345,9 +2397,73 @@ BView::HighColor() const } +void +BView::SetHighUIColor(color_which which, float tint) +{ + if (fState->IsValid(B_VIEW_WHICH_HIGH_COLOR_BIT) + && fState->which_high_color == which + && fState->which_high_color_tint == tint) + return; + + if (fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_SET_HIGH_UI_COLOR); + fOwner->fLink->Attach(which); + fOwner->fLink->Attach(tint); + + fState->valid_flags |= B_VIEW_WHICH_HIGH_COLOR_BIT; + } + + fState->which_high_color = which; + fState->which_high_color_tint = tint; + + if (which != B_NO_COLOR) { + fState->archiving_flags |= B_VIEW_WHICH_HIGH_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_HIGH_COLOR_BIT; + fState->valid_flags |= B_VIEW_HIGH_COLOR_BIT; + + fState->high_color = tint_color(ui_color(which), tint); + } else { + fState->valid_flags &= ~B_VIEW_HIGH_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_WHICH_HIGH_COLOR_BIT; + } +} + + +color_which +BView::HighUIColor(float* tint) const +{ + if (!fState->IsValid(B_VIEW_WHICH_HIGH_COLOR_BIT) + && fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_GET_HIGH_UI_COLOR); + + int32 code; + if (fOwner->fLink->FlushWithReply(code) == B_OK + && code == B_OK) { + fOwner->fLink->Read(&fState->which_high_color); + fOwner->fLink->Read(&fState->which_high_color_tint); + fOwner->fLink->Read(&fState->high_color); + + fState->valid_flags |= B_VIEW_WHICH_HIGH_COLOR_BIT; + fState->valid_flags |= B_VIEW_HIGH_COLOR_BIT; + } + } + + if (tint != NULL) + *tint = fState->which_high_color_tint; + + return fState->which_high_color; +} + + void BView::SetLowColor(rgb_color color) { + SetLowUIColor(B_NO_COLOR); + if (fState->IsValid(B_VIEW_LOW_COLOR_BIT) && fState->low_color == color) return; @@ -2388,10 +2504,151 @@ BView::LowColor() const } +void +BView::SetLowUIColor(color_which which, float tint) +{ + if (fState->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT) + && fState->which_low_color == which + && fState->which_low_color_tint == tint) + return; + + if (fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_SET_LOW_UI_COLOR); + fOwner->fLink->Attach(which); + fOwner->fLink->Attach(tint); + + fState->valid_flags |= B_VIEW_WHICH_LOW_COLOR_BIT; + } + + fState->which_low_color = which; + fState->which_low_color_tint = tint; + + if (which != B_NO_COLOR) { + fState->archiving_flags |= B_VIEW_WHICH_LOW_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_LOW_COLOR_BIT; + fState->valid_flags |= B_VIEW_LOW_COLOR_BIT; + + fState->low_color = tint_color(ui_color(which), tint); + } else { + fState->valid_flags &= ~B_VIEW_LOW_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_WHICH_LOW_COLOR_BIT; + } +} + + +color_which +BView::LowUIColor(float* tint) const +{ + if (!fState->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT) + && fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_GET_LOW_UI_COLOR); + + int32 code; + if (fOwner->fLink->FlushWithReply(code) == B_OK + && code == B_OK) { + fOwner->fLink->Read(&fState->which_low_color); + fOwner->fLink->Read(&fState->which_low_color_tint); + fOwner->fLink->Read(&fState->low_color); + + fState->valid_flags |= B_VIEW_WHICH_LOW_COLOR_BIT; + fState->valid_flags |= B_VIEW_LOW_COLOR_BIT; + } + } + + if (tint != NULL) + *tint = fState->which_low_color_tint; + + return fState->which_low_color; +} + + +bool +BView::HasDefaultColors() const +{ + // If we don't have any of these flags, then we have default colors + uint32 testMask = B_VIEW_VIEW_COLOR_BIT | B_VIEW_HIGH_COLOR_BIT + | B_VIEW_LOW_COLOR_BIT | B_VIEW_WHICH_VIEW_COLOR_BIT + | B_VIEW_WHICH_HIGH_COLOR_BIT | B_VIEW_WHICH_LOW_COLOR_BIT; + + return (fState->archiving_flags & testMask) == 0; +} + + +bool +BView::HasSystemColors() const +{ + return fState->which_view_color == B_PANEL_BACKGROUND_COLOR + && fState->which_high_color == B_PANEL_TEXT_COLOR + && fState->which_low_color == B_PANEL_BACKGROUND_COLOR + && fState->which_view_color_tint == B_NO_TINT + && fState->which_high_color_tint == B_NO_TINT + && fState->which_low_color_tint == B_NO_TINT; +} + + +void +BView::AdoptParentColors() +{ + AdoptViewColors(Parent()); +} + + +void +BView::AdoptSystemColors() +{ + SetViewUIColor(B_PANEL_BACKGROUND_COLOR); + SetLowUIColor(B_PANEL_BACKGROUND_COLOR); + SetHighUIColor(B_PANEL_TEXT_COLOR); +} + + +void +BView::AdoptViewColors(BView* view) +{ + if (view == NULL || !view->LockLooper()) + return; + + float tint = B_NO_TINT; + float viewTint = tint; + color_which viewWhich = view->ViewUIColor(&viewTint); + + // View color + if (viewWhich != B_NO_COLOR) + SetViewUIColor(viewWhich, viewTint); + else + SetViewColor(view->ViewColor()); + + // Low color + color_which which = view->LowUIColor(&tint); + if (which != B_NO_COLOR) + SetLowUIColor(which, tint); + else if (viewWhich != B_NO_COLOR) + SetLowUIColor(viewWhich, viewTint); + else + SetLowColor(view->LowColor()); + + // High color + which = view->HighUIColor(&tint); + if (which != B_NO_COLOR) + SetHighUIColor(which, tint); + else + SetHighColor(view->HighColor()); + + view->UnlockLooper(); +} + + void BView::SetViewColor(rgb_color color) { - if (fState->IsValid(B_VIEW_VIEW_COLOR_BIT) && fState->view_color == color) + SetViewUIColor(B_NO_COLOR); + + if (fState->IsValid(B_VIEW_VIEW_COLOR_BIT) + && fState->view_color == color) return; if (fOwner) { @@ -2431,6 +2688,71 @@ BView::ViewColor() const } +void +BView::SetViewUIColor(color_which which, float tint) +{ + if (fState->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT) + && fState->which_view_color == which + && fState->which_view_color_tint == tint) + return; + + if (fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_SET_VIEW_UI_COLOR); + fOwner->fLink->Attach(which); + fOwner->fLink->Attach(tint); + + fState->valid_flags |= B_VIEW_WHICH_VIEW_COLOR_BIT; + } + + fState->which_view_color = which; + fState->which_view_color_tint = tint; + + if (which != B_NO_COLOR) { + fState->archiving_flags |= B_VIEW_WHICH_VIEW_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_VIEW_COLOR_BIT; + fState->valid_flags |= B_VIEW_VIEW_COLOR_BIT; + + fState->view_color = tint_color(ui_color(which), tint); + } else { + fState->valid_flags &= ~B_VIEW_VIEW_COLOR_BIT; + fState->archiving_flags &= ~B_VIEW_WHICH_VIEW_COLOR_BIT; + } + + if (!fState->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT)) + SetLowUIColor(which, tint); +} + + +color_which +BView::ViewUIColor(float* tint) const +{ + if (!fState->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT) + && fOwner != NULL) { + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_GET_VIEW_UI_COLOR); + + int32 code; + if (fOwner->fLink->FlushWithReply(code) == B_OK + && code == B_OK) { + fOwner->fLink->Read(&fState->which_view_color); + fOwner->fLink->Read(&fState->which_view_color_tint); + fOwner->fLink->Read(&fState->view_color); + + fState->valid_flags |= B_VIEW_WHICH_VIEW_COLOR_BIT; + fState->valid_flags |= B_VIEW_VIEW_COLOR_BIT; + } + } + + if (tint != NULL) + *tint = fState->which_view_color_tint; + + return fState->which_view_color; +} + + void BView::ForceFontAliasing(bool enable) { @@ -4099,6 +4421,35 @@ BView::Invalidate() } +void +BView::DelayedInvalidate(bigtime_t delay) +{ + DelayedInvalidate(delay, Bounds()); +} + + +void +BView::DelayedInvalidate(bigtime_t delay, BRect invalRect) +{ + if (fOwner == NULL) + return; + + invalRect.left = (int)invalRect.left; + invalRect.top = (int)invalRect.top; + invalRect.right = (int)invalRect.right; + invalRect.bottom = (int)invalRect.bottom; + if (!invalRect.IsValid()) + return; + + _CheckLockAndSwitchCurrent(); + + fOwner->fLink->StartMessage(AS_VIEW_DELAYED_INVALIDATE_RECT); + fOwner->fLink->Attach(system_time() + delay); + fOwner->fLink->Attach(invalRect); + fOwner->fLink->Flush(); +} + + void BView::InvertRect(BRect rect) { @@ -4598,6 +4949,11 @@ BView::MessageReceived(BMessage* message) break; } + // prevent message repeats + case B_COLORS_UPDATED: + case B_FONTS_UPDATED: + break; + default: BHandler::MessageReceived(message); break; @@ -4940,7 +5296,6 @@ BView::InvalidateLayout(bool descendants) || fLayoutData->fLayoutInvalidationDisabled > 0) { return; } - fLayoutData->fLayoutValid = false; fLayoutData->fMinMaxValid = false; LayoutInvalidated(descendants); @@ -4957,7 +5312,8 @@ BView::InvalidateLayout(bool descendants) else _InvalidateParentLayout(); - if (fTopLevelView && fOwner) + if (fTopLevelView + && fOwner != NULL) fOwner->PostMessage(B_LAYOUT_WINDOW); } @@ -5266,6 +5622,12 @@ BView::_InitData(BRect frame, const char* name, uint32 resizingMode, fLayoutData = new LayoutData; fToolTip = NULL; + + if ((flags & B_SUPPORTS_LAYOUT) != 0) { + SetViewUIColor(B_PANEL_BACKGROUND_COLOR); + SetLowUIColor(ViewUIColor()); + SetHighUIColor(B_PANEL_TEXT_COLOR); + } } @@ -5545,7 +5907,7 @@ BView::_ResizeBy(int32 deltaWidth, int32 deltaHeight) } // layout the children - if (fFlags & B_SUPPORTS_LAYOUT) { + if ((fFlags & B_SUPPORTS_LAYOUT) != 0) { Relayout(); } else { for (BView* child = fFirstChild; child; child = child->fNextSibling) @@ -5624,7 +5986,26 @@ BView::_Activate(bool active) void BView::_Attach() { + if (fOwner != NULL) { + // unmask state flags to force [re]syncing with the app_server + fState->valid_flags &= ~(B_VIEW_WHICH_VIEW_COLOR_BIT + | B_VIEW_WHICH_LOW_COLOR_BIT | B_VIEW_WHICH_HIGH_COLOR_BIT); + + if (fState->which_view_color != B_NO_COLOR) + SetViewUIColor(fState->which_view_color, + fState->which_view_color_tint); + + if (fState->which_high_color != B_NO_COLOR) + SetHighUIColor(fState->which_high_color, + fState->which_high_color_tint); + + if (fState->which_low_color != B_NO_COLOR) + SetLowUIColor(fState->which_low_color, + fState->which_low_color_tint); + } + AttachedToWindow(); + fAttached = true; // after giving the view a chance to do this itself, @@ -5653,6 +6034,46 @@ BView::_Attach() } +void +BView::_ColorsUpdated(BMessage* message) +{ + if (fTopLevelView + && fLayoutData->fLayout != NULL + && !fState->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT)) { + SetViewUIColor(B_PANEL_BACKGROUND_COLOR); + SetHighUIColor(B_PANEL_TEXT_COLOR); + } + + rgb_color color; + + const char* colorName = ui_color_name(fState->which_view_color); + if (colorName != NULL && message->FindColor(colorName, &color) == B_OK) { + fState->view_color = tint_color(color, fState->which_view_color_tint); + fState->valid_flags |= B_VIEW_VIEW_COLOR_BIT; + } + + colorName = ui_color_name(fState->which_low_color); + if (colorName != NULL && message->FindColor(colorName, &color) == B_OK) { + fState->low_color = tint_color(color, fState->which_low_color_tint); + fState->valid_flags |= B_VIEW_LOW_COLOR_BIT; + } + + colorName = ui_color_name(fState->which_high_color); + if (colorName != NULL && message->FindColor(colorName, &color) == B_OK) { + fState->high_color = tint_color(color, fState->which_high_color_tint); + fState->valid_flags |= B_VIEW_HIGH_COLOR_BIT; + } + + MessageReceived(message); + + for (BView* child = fFirstChild; child != NULL; + child = child->fNextSibling) + child->_ColorsUpdated(message); + + Invalidate(); +} + + void BView::_Detach() { @@ -5744,6 +6165,18 @@ BView::_DrawAfterChildren(BRect updateRect) } +void +BView::_FontsUpdated(BMessage* message) +{ + MessageReceived(message); + + for (BView* child = fFirstChild; child != NULL; + child = child->fNextSibling) { + child->_FontsUpdated(message); + } +} + + void BView::_Pulse() { diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 694be5fa3c..3f71c54422 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -733,7 +734,7 @@ BWindow::MessageReceived(BMessage* message) // we're talking to the server application using our own // communication channel (fLink) - we better make sure no one // interferes by locking that channel (which AppServerLink does - // implicetly) + // implicitly) fLink->StartMessage(AS_CREATE_WINDOW); @@ -1439,6 +1440,20 @@ FrameMoved(origin); break; } + case B_COLORS_UPDATED: + { + fTopView->_ColorsUpdated(message); + target->MessageReceived(message); + break; + } + + case B_FONTS_UPDATED: + { + fTopView->_FontsUpdated(message); + target->MessageReceived(message); + break; + } + default: BLooper::DispatchMessage(message, target); break; @@ -2699,6 +2714,10 @@ BWindow::Run() void BWindow::SetLayout(BLayout* layout) { + // Adopt layout's colors for fTopView + if (layout != NULL) + fTopView->AdoptViewColors(layout->View()); + fTopView->SetLayout(layout); } @@ -2727,6 +2746,13 @@ BWindow::Layout(bool force) } +bool +BWindow::IsOffscreenWindow() const +{ + return fOffscreen; +} + + status_t BWindow::GetSupportedSuites(BMessage* data) { @@ -3205,8 +3231,7 @@ BWindow::_CreateTopView() BRect frame = fFrame.OffsetToCopy(B_ORIGIN); // TODO: what to do here about std::nothrow? - fTopView = new BView(frame, "fTopView", - B_FOLLOW_ALL, B_WILL_DRAW); + fTopView = new BView(frame, "fTopView", B_FOLLOW_ALL, B_WILL_DRAW); fTopView->fTopLevelView = true; //inhibit check_lock() @@ -3222,7 +3247,6 @@ BWindow::_CreateTopView() // we can't use AddChild() because this is the top view fTopView->_CreateSelf(); - STRACE(("BuildTopView ended\n")); } diff --git a/src/servers/app/DelayedMessage.cpp b/src/servers/app/DelayedMessage.cpp new file mode 100644 index 0000000000..dd8139d812 --- /dev/null +++ b/src/servers/app/DelayedMessage.cpp @@ -0,0 +1,871 @@ +/* + * Copyright 2015, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Joseph Groover +*/ + + +#include "DelayedMessage.h" + +#include +#include +#include + +#include +#include + +#include +#include + + +// DelayedMessageSender constants +static const int32 kWakeupMessage = AS_LAST_CODE + 2048; +static const int32 kExitMessage = kWakeupMessage + 1; + +static const char* kName = "DMT is here for you, eventually..."; +static int32 kPriority = B_URGENT_DISPLAY_PRIORITY; +static int32 kPortCapacity = 10; + + +//! Data attachment structure. +struct Attachment { + Attachment(const void* data, size_t size); + ~Attachment(); + + const void* constData; + void* data; + size_t size; +}; + + +typedef BObjectList AttachmentList; + + +/*! \class ScheduledMessage + \brief Responsible for sending of delayed message. +*/ +class ScheduledMessage { +public: + ScheduledMessage(DelayedMessage& message); + ~ScheduledMessage(); + + int32 CountTargets() const; + + void Finalize(); + bigtime_t ScheduledTime() const; + int32 SendMessage(); + bool IsValid() const; + bool Merge(DelayedMessage& message); + + status_t SendMessageToPort(port_id port); + bool operator<(const ScheduledMessage& other) const; + + DelayedMessageData* fData; +}; + + +/*! \class DelayedMessageSender DelayedMessageSender.h + \brief Responsible for scheduling and sending of delayed messages +*/ +class DelayedMessageSender { +public: + explicit DelayedMessageSender(); + ~DelayedMessageSender(); + + status_t ScheduleMessage (DelayedMessage& message); + + int32 CountDelayedMessages() const; + int64 CountSentMessages() const; + +private: + void _MessageLoop(); + int32 _SendDelayedMessages(); + static int32 _thread_func(void* sender); + void _Wakeup(bigtime_t whatTime); + +private: + typedef BObjectList ScheduledList; + + mutable BLocker fLock; + ScheduledList fMessages; + + bigtime_t fScheduledWakeup; + + int32 fWakeupRetry; + thread_id fThread; + port_id fPort; + + mutable int64 fSentCount; +}; + + +DelayedMessageSender gDelayedMessageSender; + + +/*! \class DelayedMessageData DelayedMessageSender.h + \brief Owns DelayedMessage data, allocates memory and copies data only + when needed, +*/ +class DelayedMessageData { + typedef BObjectList PortList; + typedef void(*FailureCallback)(int32 code, port_id port, void* data); +public: + DelayedMessageData(int32 code, bigtime_t delay, + bool isSpecificTime); + ~DelayedMessageData(); + + bool AddTarget(port_id port); + void RemoveTarget(port_id port); + int32 CountTargets() const; + + void MergeTargets(DelayedMessageData* other); + + bool CopyData(); + bool MergeData(DelayedMessageData* other); + + bool IsValid() const; + // Only valid after a successful CopyData(). + + status_t Attach(const void* data, size_t size); + + bool Compare(Attachment* one, Attachment* two, + int32 index); + + void SetMerge(DMMergeMode mode, uint32 mask); + void SendFailed(port_id port); + + void SetFailureCallback(FailureCallback callback, + void* data); + + // Accessors. + int32& Code() {return fCode;} + const int32& Code() const {return fCode;} + + bigtime_t& ScheduledTime() {return fScheduledTime;} + const bigtime_t& ScheduledTime() const {return fScheduledTime;} + + AttachmentList& Attachments() {return fAttachments;} + const AttachmentList& Attachments() const {return fAttachments;} + + PortList& Targets() {return fTargets;} + const PortList& Targets() const {return fTargets;} + +private: + // Data members. + + int32 fCode; + bigtime_t fScheduledTime; + bool fValid; + + AttachmentList fAttachments; + PortList fTargets; + + DMMergeMode fMergeMode; + uint32 fMergeMask; + + FailureCallback fFailureCallback; + void* fFailureData; +}; + + +// #pragma mark - + + + +DelayedMessage::DelayedMessage(int32 code, bigtime_t delay, + bool isSpecificTime) + : + fData(new(std::nothrow) DelayedMessageData(code, delay < DM_MINIMUM_DELAY + ? DM_MINIMUM_DELAY : delay, isSpecificTime)), + fHandedOff(false) +{ +} + + +DelayedMessage::~DelayedMessage() +{ + // Message is canceled without a handoff. + if (!fHandedOff) + delete fData; +} + + +bool +DelayedMessage::AddTarget(port_id port) +{ + if (fData == NULL || fHandedOff) + return false; + + return fData->AddTarget(port); +} + + +void +DelayedMessage::SetMerge(DMMergeMode mode, uint32 match) +{ + if (fData == NULL || fHandedOff) + return; + + fData->SetMerge(mode, match); +} + + +void +DelayedMessage::SetFailureCallback(void (*callback)(int32, port_id, void*), + void* data) +{ + if (fData == NULL || fHandedOff) + return; + + fData->SetFailureCallback(callback, data); +} + + +//! Attach data to message. Memory is not allocated nor copied until handoff. +status_t +DelayedMessage::Attach(const void* data, size_t size) +{ + if (fData == NULL) + return B_NO_MEMORY; + + if (fHandedOff) + return B_ERROR; + + if (data == NULL || size == 0) + return B_BAD_VALUE; + + return fData->Attach(data, size); +} + + +status_t +DelayedMessage::Flush() +{ + if (fData == NULL) + return B_NO_MEMORY; + + if (fHandedOff) + return B_ERROR; + + if (fData->CountTargets() == 0) + return B_BAD_VALUE; + + return gDelayedMessageSender.ScheduleMessage(*this); +} + + +/*! The data handoff occurs upon scheduling and reduces copies to only + when a message is actually scheduled. Canceled messages have low cost. +*/ +DelayedMessageData* +DelayedMessage::HandOff() +{ + if (fData == NULL || fHandedOff) + return NULL; + + if (fData->CopyData()) { + fHandedOff = true; + return fData; + } + + return NULL; +} + + +// #pragma mark - + + +Attachment::Attachment(const void* _data, size_t _size) + : + constData(_data), + data(NULL), + size(_size) +{ +} + + +Attachment::~Attachment() +{ + free(data); +} + + +// #pragma mark - + + +DelayedMessageData::DelayedMessageData(int32 code, bigtime_t delay, + bool isSpecificTime) + : + fCode(code), + fScheduledTime(delay + isSpecificTime ? 0 : system_time()), + fValid(false), + + fAttachments(3, true), + fTargets(4, true), + + fMergeMode(DM_NO_MERGE), + fMergeMask(DM_DATA_DEFAULT), + + fFailureCallback(NULL), + fFailureData(NULL) +{ +} + + +DelayedMessageData::~DelayedMessageData() +{ +} + + +bool +DelayedMessageData::AddTarget(port_id port) +{ + if (port <= 0) + return false; + + // check for duplicates: + for (int32 index = 0; index < fTargets.CountItems(); ++index) { + if (port == *fTargets.ItemAt(index)) + return false; + } + + return fTargets.AddItem(new(std::nothrow) port_id(port)); +} + + +void +DelayedMessageData::RemoveTarget(port_id port) +{ + if (port == B_BAD_PORT_ID) + return; + + // Search for a match by value. + for (int32 index = 0; index < fTargets.CountItems(); ++index) { + port_id* target = fTargets.ItemAt(index); + if (port == *target) { + fTargets.RemoveItem(target, true); + return; + } + } +} + + +int32 +DelayedMessageData::CountTargets() const +{ + return fTargets.CountItems(); +} + + +void +DelayedMessageData::MergeTargets(DelayedMessageData* other) +{ + // Failure to add one target does not abort the loop! + // It could just mean we already have the target. + for (int32 index = 0; index < other->fTargets.CountItems(); ++index) + AddTarget(*(other->fTargets.ItemAt(index))); +} + + +//! Copy data from original location - merging failed +bool +DelayedMessageData::CopyData() +{ + Attachment* attached = NULL; + + for (int32 index = 0; index < fAttachments.CountItems(); ++index) { + attached = fAttachments.ItemAt(index); + + if (attached == NULL || attached->data != NULL) + return false; + + attached->data = malloc(attached->size); + if (attached->data == NULL) + return false; + + memcpy(attached->data, attached->constData, attached->size); + } + + fValid = true; + return true; +} + + +bool +DelayedMessageData::MergeData(DelayedMessageData* other) +{ + if (!fValid + || other == NULL + || other->fCode != fCode + || fMergeMode == DM_NO_MERGE + || other->fMergeMode == DM_NO_MERGE + || other->fMergeMode != fMergeMode + || other->fAttachments.CountItems() != fAttachments.CountItems()) + return false; + + if (other->fMergeMode == DM_MERGE_CANCEL) { + MergeTargets(other); + return true; + } + + // Compare data + Attachment* attached = NULL; + Attachment* otherAttached = NULL; + + for (int32 index = 0; index < fAttachments.CountItems(); ++index) { + attached = fAttachments.ItemAt(index); + otherAttached = other->fAttachments.ItemAt(index); + + if (attached == NULL + || otherAttached == NULL + || attached->data == NULL + || otherAttached->constData == NULL + || attached->size != otherAttached->size) + return false; + + // Compares depending upon mode & flags + if (!Compare(attached, otherAttached, index)) + return false; + } + + // add any targets not included in the existing message! + MergeTargets(other); + + // since these are duplicates, we need not copy anything... + if (fMergeMode == DM_MERGE_DUPLICATES) + return true; + + // DM_MERGE_REPLACE: + + // Import the new data! + for (int32 index = 0; index < fAttachments.CountItems(); ++index) { + attached = fAttachments.ItemAt(index); + otherAttached = other->fAttachments.ItemAt(index); + + // We already have allocated our memory, but the other data + // has not. So this reduces memory allocations. + memcpy(attached->data, otherAttached->constData, attached->size); + } + + return true; +} + + +bool +DelayedMessageData::IsValid() const +{ + return fValid; +} + + +status_t +DelayedMessageData::Attach(const void* data, size_t size) +{ + // Sanity checking already performed + Attachment* attach = new(std::nothrow) Attachment(data, size); + + if (attach == NULL) + return B_NO_MEMORY; + + if (fAttachments.AddItem(attach) == false) { + delete attach; + return B_ERROR; + } + + return B_OK; +} + + +bool +DelayedMessageData::Compare(Attachment* one, Attachment* two, int32 index) +{ + if (fMergeMode == DM_MERGE_DUPLICATES) { + + // Default-policy: all data must match + if (fMergeMask == DM_DATA_DEFAULT || (fMergeMask & 1 << index) != 0) + return memcmp(one->data, two->constData, one->size) == 0; + + } else if (fMergeMode == DM_MERGE_REPLACE) { + + // Default Policy: no data needs to match + if (fMergeMask != DM_DATA_DEFAULT && (fMergeMask & 1 << index) != 0) + return memcmp(one->data, two->constData, one->size) == 0; + } + + return true; +} + + +void +DelayedMessageData::SetMerge(DMMergeMode mode, uint32 mask) +{ + fMergeMode = mode; + fMergeMask = mask; +} + + +void +DelayedMessageData::SendFailed(port_id port) +{ + if (fFailureCallback != NULL) + fFailureCallback(fCode, port, fFailureData); +} + + +void +DelayedMessageData::SetFailureCallback(FailureCallback callback, void* data) +{ + fFailureCallback = callback; + fFailureData = data; +} + + +// #pragma mark - + + +ScheduledMessage::ScheduledMessage(DelayedMessage& message) + : + fData(message.HandOff()) +{ +} + + +ScheduledMessage::~ScheduledMessage() +{ + delete fData; +} + + +int32 +ScheduledMessage::CountTargets() const +{ + if (fData == NULL) + return 0; + + return fData->CountTargets(); +} + + +bigtime_t +ScheduledMessage::ScheduledTime() const +{ + if (fData == NULL) + return 0; + + return fData->ScheduledTime(); +} + + +//! Send our message and data to their intended target(s) +int32 +ScheduledMessage::SendMessage() +{ + if (fData == NULL || !fData->IsValid()) + return 0; + + int32 sent = 0; + for (int32 index = 0; index < fData->Targets().CountItems(); ++index) { + port_id port = *(fData->Targets().ItemAt(index)); + status_t error = SendMessageToPort(port); + + if (error == B_OK) { + ++sent; + continue; + } + + if (error != B_TIMED_OUT) + fData->SendFailed(port); + } + + return sent; +} + + +status_t +ScheduledMessage::SendMessageToPort(port_id port) +{ + if (fData == NULL || !fData->IsValid()) + return B_BAD_DATA; + + if (port == B_BAD_PORT_ID) + return B_BAD_VALUE; + + BPrivate::LinkSender sender(port); + if (sender.StartMessage(fData->Code()) != B_OK) + return B_ERROR; + + AttachmentList& list = fData->Attachments(); + Attachment* attached = NULL; + status_t error = B_OK; + + // The data has been checked already, so we assume it is all good + for (int32 index = 0; index < list.CountItems(); ++index) { + attached = list.ItemAt(index); + + error = sender.Attach(attached->data, attached->size); + if (error != B_OK) { + sender.CancelMessage(); + return error; + } + } + + // We do not want to ever hold up the sender thread for too long, we + // set a 1 second sending delay, which should be more than enough for + // 99.992% of all cases. Approximately. + error = sender.Flush(1000000); + + if (error == B_OK || error == B_BAD_PORT_ID) + fData->RemoveTarget(port); + + return error; +} + + +bool +ScheduledMessage::IsValid() const +{ + return fData != NULL && fData->IsValid(); +} + + +bool +ScheduledMessage::Merge(DelayedMessage& other) +{ + if (!IsValid()) + return false; + + return fData->MergeData(other.Data()); +} + + +bool +ScheduledMessage::operator<(const ScheduledMessage& other) const +{ + if (!IsValid() || !other.IsValid()) + return false; + + return fData->ScheduledTime() < other.fData->ScheduledTime(); +} + + +int +CompareMessages(const ScheduledMessage* one, const ScheduledMessage* two) +{ + return *one < *two; +} + + +// #pragma mark - + + +DelayedMessageSender::DelayedMessageSender() + : + fLock("DelayedMessageSender"), + fMessages(20, true), + fScheduledWakeup(B_INFINITE_TIMEOUT), + fWakeupRetry(0), + fThread(spawn_thread(&_thread_func, kName, kPriority, this)), + fPort(create_port(kPortCapacity, "DelayedMessageSender")), + fSentCount(0) +{ + resume_thread(fThread); +} + + +DelayedMessageSender::~DelayedMessageSender() +{ + // write the exit message to our port + write_port(fPort, kExitMessage, NULL, 0); + + status_t status = B_OK; + while (wait_for_thread(fThread, &status) == B_OK); + + // We now know the thread has exited, it is safe to cleanup + delete_port(fPort); +} + + +status_t +DelayedMessageSender::ScheduleMessage(DelayedMessage& message) +{ + BAutolock _(fLock); + + // Can we merge with a pending message? + ScheduledMessage* pending = NULL; + for (int32 index = 0; index < fMessages.CountItems(); ++index) { + pending = fMessages.ItemAt(index); + if (pending->Merge(message)) + return B_OK; + } + + // Guess not, add it to our list! + ScheduledMessage* scheduled = new(std::nothrow) ScheduledMessage(message); + + if (scheduled == NULL) + return B_NO_MEMORY; + + if (!scheduled->IsValid()) + return B_BAD_DATA; + + if (fMessages.AddItem(scheduled)) { + fMessages.SortItems(&CompareMessages); + _Wakeup(scheduled->ScheduledTime()); + return B_OK; + } + + return B_ERROR; +} + + +int32 +DelayedMessageSender::CountDelayedMessages() const +{ + BAutolock _(fLock); + return fMessages.CountItems(); +} + + +int64 +DelayedMessageSender::CountSentMessages() const +{ + return atomic_get64(&fSentCount); +} + + +void +DelayedMessageSender::_MessageLoop() +{ + int32 code = -1; + status_t status = B_TIMED_OUT; + bigtime_t timeout = B_INFINITE_TIMEOUT; + + while (true) { + timeout = atomic_get64(&fScheduledWakeup) - (system_time() + + (DM_MINIMUM_DELAY / 2)); + + if (timeout > DM_MINIMUM_DELAY / 4) { + status = read_port_etc(fPort, &code, NULL, 0, B_RELATIVE_TIMEOUT, + timeout); + } else + status = B_TIMED_OUT; + + if (status == B_INTERRUPTED) + continue; + + if (status == B_TIMED_OUT) { + _SendDelayedMessages(); + continue; + } + + if (status == B_OK) { + switch (code) { + case kWakeupMessage: + continue; + + case kExitMessage: + return; + + // TODO: trace unhandled messages + default: + continue; + } + } + + // port deleted? + if (status < B_OK) + break; + } +} + + +int32 +DelayedMessageSender::_thread_func(void* sender) +{ + (static_cast(sender))->_MessageLoop(); + return 0; +} + + +//! Sends pending messages, call ONLY from sender thread! +int32 +DelayedMessageSender::_SendDelayedMessages() +{ + // avoid sending messages during times of contention + if (fLock.LockWithTimeout(30000) != B_OK) { + atomic_add64(&fScheduledWakeup, DM_MINIMUM_DELAY); + return 0; + } + + atomic_set64(&fScheduledWakeup, B_INFINITE_TIMEOUT); + + if (fMessages.CountItems() == 0) { + fLock.Unlock(); + return 0; + } + + int32 sent = 0; + + bigtime_t time = system_time() + DM_MINIMUM_DELAY / 2; + // capture any that may be on the verge of being sent. + + BObjectList remove; + + ScheduledMessage* message = NULL; + for (int32 index = 0; index < fMessages.CountItems(); ++index) { + message = fMessages.ItemAt(index); + + if (message->ScheduledTime() > time) { + atomic_set64(&fScheduledWakeup, message->ScheduledTime()); + break; + } + + int32 sendCount = message->SendMessage(); + if (sendCount > 0) + sent += sendCount; + + if (message->CountTargets() == 0) + remove.AddItem(message); + } + + // remove serviced messages + for (int32 index = 0; index < remove.CountItems(); ++index) + fMessages.RemoveItem(remove.ItemAt(index)); + + atomic_add64(&fSentCount, sent); + + // catch any partly-failed messages (possibly late): + if (fMessages.CountItems() > 0 + && atomic_get64(&fScheduledWakeup) == B_INFINITE_TIMEOUT) { + + fMessages.SortItems(&CompareMessages); + message = fMessages.ItemAt(0); + bigtime_t timeout = message->ScheduledTime() - time; + + if (timeout < 0) + timeout = DM_MINIMUM_DELAY; + + atomic_set64(&fScheduledWakeup, timeout); + } + + fLock.Unlock(); + return sent; +} + + +void +DelayedMessageSender::_Wakeup(bigtime_t when) +{ + if (atomic_get64(&fScheduledWakeup) < when + && atomic_get(&fWakeupRetry) == 0) + return; + + atomic_set64(&fScheduledWakeup, when); + + BPrivate::LinkSender sender(fPort); + sender.StartMessage(kWakeupMessage); + status_t error = sender.Flush(30000); + atomic_set(&fWakeupRetry, (int32)error == B_TIMED_OUT); +} + diff --git a/src/servers/app/DelayedMessage.h b/src/servers/app/DelayedMessage.h new file mode 100644 index 0000000000..1faf355e34 --- /dev/null +++ b/src/servers/app/DelayedMessage.h @@ -0,0 +1,178 @@ +/* + * Copyright 2015, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Joseph Groover +*/ +#ifndef AS_DELAYED_MESSAGE_H +#define AS_DELAYED_MESSAGE_H + + +#include +#include + + +//! Method by which to merge DelayedMessages with the same code. +enum DMMergeMode { + DM_NO_MERGE = 0, // Will send this message, and the other(s) + DM_MERGE_REPLACE = 1, // Replace older data with newer data + DM_MERGE_CANCEL = 2, // keeps older data, cancels this message + DM_MERGE_DUPLICATES = 3 // If data is the same, cancel new message +}; + + +//! Merge-mode data-matching, set which data must match to merge messages. +enum { + DM_DATA_DEFAULT = 0, // Match all for DUPLICATES & none for REPLACE modes. + DM_DATA_1 = 1 << 0, + DM_DATA_2 = 1 << 1, + DM_DATA_3 = 1 << 2, + DM_DATA_4 = 1 << 3, + DM_DATA_5 = 1 << 4, + DM_DATA_6 = 1 << 5 +}; + + +//! Convenient delay definitions. +enum { + DM_MINIMUM_DELAY = 500ULL, + DM_SHORT_DELAY = 1000ULL, + DM_120HZ_DELAY = 8888ULL, + DM_60HZ_DELAY = 16666ULL, + DM_MEDIUM_DELAY = 15000ULL, + DM_30HZ_DELAY = 33332ULL, + DM_15HZ_DELAY = 66664ULL, + DM_LONG_DELAY = 100000ULL, + DM_QUARTER_SECOND_DELAY = 250000ULL, + DM_HALF_SECOND_DELAY = 500000ULL, + DM_ONE_SECOND_DELAY = 1000000ULL, + DM_ONE_MINUTE_DELAY = DM_ONE_SECOND_DELAY * 60, + DM_ONE_HOUR_DELAY = DM_ONE_MINUTE_DELAY * 60 +}; + + +class DelayedMessageData; + + +/*! \class DelayedMessage + \brief Friendly API for creating messages to be sent at a future time. + + Messages can be sent with a relative delay, or at a set time. Messages with + the same code can be merged according to various rules. Each message can + have any number of target recipients. + + DelayedMessage is a throw-away object, it is to be created on the stack, + Flush()'d, then left to be destructed when out of scope. +*/ +class DelayedMessage { + typedef void(*FailureCallback)(int32 code, port_id port, void* data); +public: + DelayedMessage(int32 code, bigtime_t delay, + bool isSpecificTime = false); + + ~DelayedMessage(); + + // At least one target port is required. + bool AddTarget(port_id port); + + // Merge messages with the same code according to the following + // rules and data matching mask. + void SetMerge(DMMergeMode mode, uint32 match = 0); + + // Called for each port on which the message was failed to be sent. + void SetFailureCallback(FailureCallback callback, + void* data = NULL); + + template + status_t Attach(const Type& data); + status_t Attach(const void* data, size_t size); + + template + status_t AttachList(const BObjectList& list); + + template + status_t AttachList(const BObjectList& list, + bool* whichArray); + + status_t Flush(); + + // Private + DelayedMessageData* HandOff(); + DelayedMessageData* Data() {return fData;} + +private: + // Forbidden methods - these are one time-use objects. + void* operator new(size_t); + void* operator new[](size_t); + + DelayedMessageData* fData; + bool fHandedOff; +}; + + +// #pragma mark Implementation + + +template +status_t +DelayedMessage::Attach(const Type& data) +{ + return Attach(&data, sizeof(Type)); +} + + +template +status_t +DelayedMessage::AttachList(const BObjectList& list) +{ + if (list.CountItems() == 0) + return B_BAD_VALUE; + + status_t error = Attach(list.CountItems()); + + for (int32 index = 0; index < list.CountItems(); ++index) { + if (error != B_OK) + break; + + error = Attach(*(list.ItemAt(index))); + } + + return error; +} + + +template +status_t +DelayedMessage::AttachList(const BObjectList& list, bool* which) +{ + if (list.CountItems() == 0) + return B_BAD_VALUE; + + if (which == NULL) + return AttachList(list); + + int32 count = 0; + for (int32 index = 0; index < list.CountItems(); ++index) { + if (which[index]) + ++count; + } + + if (count == 0) + return B_BAD_VALUE; + + status_t error = Attach(count); + + for (int32 index = 0; index < list.CountItems(); ++index) { + if (error != B_OK) + break; + + if (which[index]) + error = Attach(*list.ItemAt(index)); + } + + return error; +} + + +#endif // AS_DELAYED_MESSAGE_H diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 5e45bc975e..a5644d7f54 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -10,6 +10,7 @@ * Brecht Machiels * Clemens Zeidler * Ingo Weinhold + * Joseph Groover */ @@ -575,7 +576,7 @@ Desktop::BroadcastToAllApps(int32 code) void Desktop::BroadcastToAllWindows(int32 code) { - AutoWriteLocker _(fWindowLock); + AutoReadLocker _(fWindowLock); for (Window* window = fAllWindows.FirstWindow(); window != NULL; window = window->NextWindow(kAllWindowList)) { @@ -584,6 +585,34 @@ Desktop::BroadcastToAllWindows(int32 code) } +int32 +Desktop::GetAllWindowTargets(DelayedMessage& message) +{ + AutoReadLocker _(fWindowLock); + int32 count = 0; + + for (Window* window = fAllWindows.FirstWindow(); window != NULL; + window = window->NextWindow(kAllWindowList)) { + message.AddTarget(window->ServerWindow()->MessagePort()); + ++count; + } + + return count; +} + + +int32 +Desktop::GetAllAppTargets(DelayedMessage& message) +{ + BAutolock _(fApplicationsLock); + + for (int32 index = 0; index < fApplications.CountItems(); ++index) + message.AddTarget(fApplications.ItemAt(index)->MessagePort()); + + return fApplications.CountItems(); +} + + filter_result Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers) { @@ -1648,6 +1677,31 @@ Desktop::FontsChanged(Window* window) } +void +Desktop::ColorUpdated(Window* window, color_which which, rgb_color color) +{ + AutoWriteLocker _(fWindowLock); + + window->TopView()->ColorUpdated(which, color); + + switch (which) { + case B_WINDOW_TAB_COLOR: + case B_WINDOW_TEXT_COLOR: + case B_WINDOW_INACTIVE_TAB_COLOR: + case B_WINDOW_INACTIVE_TEXT_COLOR: + case B_WINDOW_BORDER_COLOR: + case B_WINDOW_INACTIVE_BORDER_COLOR: + break; + default: + return; + } + + BRegion dirty; + window->ColorsChanged(&dirty); + RebuildAndRedrawAfterWindowChange(window, dirty); +} + + void Desktop::SetWindowLook(Window* window, window_look newLook) { @@ -2655,6 +2709,56 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } + case AS_SET_UI_COLOR: + { + color_which which; + rgb_color color; + + if (link.Read(&which) == B_OK + && link.Read(&color) == B_OK) { + + const char* colorName = ui_color_name(which); + fPendingColors.SetColor(colorName, color); + + DelayedMessage delayed(AS_SET_UI_COLORS, DM_60HZ_DELAY); + delayed.AddTarget(MessagePort()); + delayed.SetMerge(DM_MERGE_CANCEL); + + delayed.Attach(true); + delayed.Flush(); + } + + break; + } + + case AS_SET_UI_COLORS: + { + bool flushPendingOnly = false; + + if (link.Read(&flushPendingOnly) != B_OK + || (flushPendingOnly && + fPendingColors.CountNames(B_RGB_32_BIT_TYPE) == 0)) { + break; + } + + if (!flushPendingOnly) { + // Client wants to set a color map + color_which which = B_NO_COLOR; + rgb_color color; + + do { + if (link.Read(&which) != B_OK + || link.Read(&color) != B_OK) + break; + + fPendingColors.SetColor(ui_color_name(which), color); + } while (which != B_NO_COLOR); + } + + _FlushPendingColors(); + break; + } + // ToDo: Remove this again. It is a message sent by the // invalidate_on_exit kernel debugger add-on to trigger a redraw // after exiting a kernel debugger session. @@ -2716,6 +2820,54 @@ Desktop::_Windows(int32 index) } +void +Desktop::_FlushPendingColors() +{ + // Update all windows while we are holding the write lock. + + int32 count = fPendingColors.CountNames(B_RGB_32_BIT_TYPE); + if (count == 0) + return; + + bool changed[count]; + LockedDesktopSettings settings(this); + settings.SetUIColors(fPendingColors, &changed[0]); + + int32 index = 0; + char* name = NULL; + type_code type = B_RGB_32_BIT_TYPE; + rgb_color color; + color_which which = B_NO_COLOR; + BMessage clientMessage(B_COLORS_UPDATED); + + while (fPendingColors.GetInfo(type, index, &name, &type) == B_OK) { + which = which_ui_color(name); + if (which == B_NO_COLOR || fPendingColors.FindColor(name, + &color) != B_OK || !changed[index]) { + ++index; + continue; + } + + for (Window* window = fAllWindows.FirstWindow(); window != NULL; + window = window->NextWindow(kAllWindowList)) { + ColorUpdated(window, which, color); + } + + // Ensure client only gets list of changed colors + clientMessage.AddColor(name, color); + ++index; + } + + // Notify client applications + BAutolock appListLock(fApplicationsLock); + for (int32 index = 0; index < fApplications.CountItems(); ++index) { + fApplications.ItemAt(index)->SendMessageToClient(&clientMessage); + } + + fPendingColors.MakeEmpty(); +} + + void Desktop::_UpdateFloating(int32 previousWorkspace, int32 nextWorkspace, Window* mouseEventWindow) diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index c9b8e61959..6872f354c5 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -9,9 +9,11 @@ * Andrej Spielmann, * Brecht Machiels * Clemens Zeidler + * Joseph Groover */ #ifndef DESKTOP_H #define DESKTOP_H +#include "RapidDebug.h" #include @@ -22,7 +24,10 @@ #include #include +#include + #include "CursorManager.h" +#include "DelayedMessage.h" #include "DesktopListener.h" #include "DesktopSettings.h" #include "EventDispatcher.h" @@ -56,7 +61,8 @@ namespace BPrivate { class Desktop : public DesktopObservable, public MessageLooper, public ScreenOwner { public: - Desktop(uid_t userID, const char* targetScreen); + Desktop(uid_t userID, + const char* targetScreen); virtual ~Desktop(); void RegisterListener(DesktopListener* listener); @@ -74,6 +80,9 @@ public: void BroadcastToAllApps(int32 code); void BroadcastToAllWindows(int32 code); + int32 GetAllWindowTargets(DelayedMessage& message); + int32 GetAllAppTargets(DelayedMessage& message); + filter_result KeyEvent(uint32 what, int32 key, int32 modifiers); // Locking @@ -191,6 +200,8 @@ public: Window* window); void FontsChanged(Window* window); + void ColorUpdated(Window* window, color_which which, + rgb_color color); void SetWindowLook(Window* window, window_look look); void SetWindowFeel(Window* window, window_feel feel); @@ -253,6 +264,8 @@ public: private: WindowList& _Windows(int32 index); + void _FlushPendingColors(); + void _LaunchInputServer(); void _GetLooperName(char* name, size_t size); void _PrepareQuit(); @@ -359,6 +372,8 @@ private: Window* fBack; StackAndTile fStackAndTile; + + BMessage fPendingColors; }; #endif // DESKTOP_H diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index d6895b4657..ae261b9a88 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2005-2013, Haiku. + * Copyright 2005-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus * Axel Dörfler, axeld@pinc-software.de * Andrej Spielmann, + * Joseph Groover */ @@ -297,7 +298,10 @@ DesktopSettingsPrivate::_Load() snprintf(colorName, sizeof(colorName), "color%" B_PRId32, (int32)index_to_color_which(i)); - settings.FindInt32(colorName, (int32*)&fShared.colors[i]); + if (settings.FindInt32(colorName, (int32*)&fShared.colors[i]) != B_OK) { + // Set obviously bad value so the Appearance app can detect it + fShared.colors[i] = B_TRANSPARENT_COLOR; + } } } } @@ -647,12 +651,16 @@ DesktopSettingsPrivate::WorkspacesMessage(int32 index) const void -DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color) +DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color, + bool* changed) { int32 index = color_which_to_index(which); if (index < 0 || index >= kColorWhichCount) return; + if (changed != NULL) + *changed = fShared.colors[index] != color; + fShared.colors[index] = color; // TODO: deprecate the background_color member of the menu_info struct, // otherwise we have to keep this duplication... @@ -663,6 +671,47 @@ DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color) } +void +DesktopSettingsPrivate::SetUIColors(const BMessage& colors, bool* changed) +{ + int32 count = colors.CountNames(B_RGB_32_BIT_TYPE); + if (count <= 0) + return; + + int32 index = 0; + int32 colorIndex = 0; + char* name = NULL; + type_code type; + rgb_color color; + color_which which = B_NO_COLOR; + + while (colors.GetInfo(B_RGB_32_BIT_TYPE, index, &name, &type) == B_OK) { + which = which_ui_color(name); + colorIndex = color_which_to_index(which); + if (colorIndex < 0 || colorIndex >= kColorWhichCount + || colors.FindColor(name, &color) != B_OK) { + if (changed != NULL) + changed[index] = false; + + ++index; + continue; + } + + if (changed != NULL) + changed[index] = fShared.colors[colorIndex] != color; + + fShared.colors[colorIndex] = color; + + if (which == (int32)B_MENU_BACKGROUND_COLOR) + fMenuInfo.background_color = color; + + ++index; + } + + Save(kAppearanceSettings); +} + + rgb_color DesktopSettingsPrivate::UIColor(color_which which) const { @@ -977,9 +1026,9 @@ LockedDesktopSettings::SetShowAllDraggers(bool show) void -LockedDesktopSettings::SetUIColor(color_which which, const rgb_color color) +LockedDesktopSettings::SetUIColors(const BMessage& colors, bool* changed) { - fSettings->SetUIColor(which, color); + fSettings->SetUIColors(colors, &changed[0]); } diff --git a/src/servers/app/DesktopSettings.h b/src/servers/app/DesktopSettings.h index 77d16569c3..48677fb227 100644 --- a/src/servers/app/DesktopSettings.h +++ b/src/servers/app/DesktopSettings.h @@ -1,10 +1,11 @@ /* - * Copyright 2001-2013, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de * Andrej Spielmann, + * Joseph Groover */ #ifndef DESKTOP_SETTINGS_H #define DESKTOP_SETTINGS_H @@ -14,6 +15,8 @@ #include #include +#include + class Desktop; class DesktopSettingsPrivate; @@ -97,8 +100,8 @@ public: void SetShowAllDraggers(bool show); - void SetUIColor(color_which which, - const rgb_color color); + void SetUIColors(const BMessage& colors, + bool* changed = NULL); void SetSubpixelAntialiasing(bool subpix); void SetHinting(uint8 hinting); diff --git a/src/servers/app/DesktopSettingsPrivate.h b/src/servers/app/DesktopSettingsPrivate.h index 71b7519adb..9983e3a77d 100644 --- a/src/servers/app/DesktopSettingsPrivate.h +++ b/src/servers/app/DesktopSettingsPrivate.h @@ -1,10 +1,11 @@ /* - * Copyright 2005-2013, Haiku. + * Copyright 2005-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de * Andrej Spielmann, + * Joseph Groover */ #ifndef DESKTOP_SETTINGS_PRIVATE_H #define DESKTOP_SETTINGS_PRIVATE_H @@ -72,7 +73,13 @@ public: const BMessage* WorkspacesMessage(int32 index) const; void SetUIColor(color_which which, - const rgb_color color); + const rgb_color color, + bool* changed = NULL); + void SetUIColors(const BMessage& colors, + bool* changed = NULL); + // changed must be boolean array equal in + // size to colors' size + rgb_color UIColor(color_which which) const; void SetSubpixelAntialiasing(bool subpix); diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index c0f6c8427a..fb20f52438 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -9,6 +9,7 @@ * Axel Dörfler, axeld@pinc-software.de * Michael Pfeiffer * Julian Harnath + * Joseph Groover */ //! Data classes for working with BView states and draw parameters @@ -43,6 +44,10 @@ DrawState::DrawState() fHighColor((rgb_color){ 0, 0, 0, 255 }), fLowColor((rgb_color){ 255, 255, 255, 255 }), + fWhichHighColor(B_NO_COLOR), + fWhichLowColor(B_NO_COLOR), + fWhichHighColorTint(B_NO_TINT), + fWhichLowColorTint(B_NO_TINT), fPattern(kSolidHigh), fDrawingMode(B_OP_COPY), @@ -78,6 +83,10 @@ DrawState::DrawState(const DrawState& other) fHighColor(other.fHighColor), fLowColor(other.fLowColor), + fWhichHighColor(other.fWhichHighColor), + fWhichLowColor(other.fWhichLowColor), + fWhichHighColorTint(other.fWhichHighColorTint), + fWhichLowColorTint(other.fWhichLowColorTint), fPattern(other.fPattern), fDrawingMode(other.fDrawingMode), @@ -218,6 +227,10 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link) fPenSize = info.penSize; fHighColor = info.highColor; fLowColor = info.lowColor; + fWhichHighColor = info.whichHighColor; + fWhichLowColor = info.whichLowColor; + fWhichHighColorTint = info.whichHighColorTint; + fWhichLowColorTint = info.whichLowColorTint; fPattern = info.pattern; fDrawingMode = info.drawingMode; fOrigin = info.origin; @@ -283,6 +296,10 @@ DrawState::WriteToLink(BPrivate::LinkSender& link) const info.viewStateInfo.penSize = fPenSize; info.viewStateInfo.highColor = fHighColor; info.viewStateInfo.lowColor = fLowColor; + info.viewStateInfo.whichHighColor = fWhichHighColor; + info.viewStateInfo.whichLowColor = fWhichLowColor; + info.viewStateInfo.whichHighColorTint = fWhichHighColorTint; + info.viewStateInfo.whichLowColorTint = fWhichLowColorTint; info.viewStateInfo.pattern = (::pattern)fPattern.GetPattern(); info.viewStateInfo.drawingMode = fDrawingMode; info.viewStateInfo.origin = fOrigin; @@ -577,6 +594,42 @@ DrawState::SetLowColor(rgb_color color) } +void +DrawState::SetHighUIColor(color_which which, float tint) +{ + fWhichHighColor = which; + fWhichHighColorTint = tint; +} + + +color_which +DrawState::HighUIColor(float* tint) const +{ + if (tint != NULL) + *tint = fWhichHighColorTint; + + return fWhichHighColor; +} + + +void +DrawState::SetLowUIColor(color_which which, float tint) +{ + fWhichLowColor = which; + fWhichLowColorTint = tint; +} + + +color_which +DrawState::LowUIColor(float* tint) const +{ + if (tint != NULL) + *tint = fWhichLowColorTint; + + return fWhichLowColor; +} + + void DrawState::SetPattern(const Pattern& pattern) { @@ -760,6 +813,10 @@ DrawState::PrintToStream() const fHighColor.red, fHighColor.green, fHighColor.blue, fHighColor.alpha); printf("\t LowColor: r=%d g=%d b=%d a=%d\n", fLowColor.red, fLowColor.green, fLowColor.blue, fLowColor.alpha); + printf("\t WhichHighColor: %i\n", fWhichHighColor); + printf("\t WhichLowColor: %i\n", fWhichLowColor); + printf("\t WhichHighColorTint: %.3f\n", fWhichHighColorTint); + printf("\t WhichLowColorTint: %.3f\n", fWhichLowColorTint); printf("\t Pattern: %" B_PRIu64 "\n", fPattern.GetInt64()); printf("\t DrawMode: %" B_PRIu32 "\n", (uint32)fDrawingMode); diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 5c3535776c..8e664b8e8a 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -8,6 +8,7 @@ * Stephan Aßmus * Axel Dörfler, axeld@pinc-software.de * Julian Harnath + * Joseph Groover */ #ifndef _DRAW_STATE_H_ #define _DRAW_STATE_H_ @@ -100,6 +101,12 @@ public: rgb_color LowColor() const { return fLowColor; } + void SetHighUIColor(color_which which, float tint); + color_which HighUIColor(float* tint) const; + + void SetLowUIColor(color_which which, float tint); + color_which LowUIColor(float* tint) const; + void SetPattern(const Pattern& pattern); const Pattern& GetPattern() const { return fPattern; } @@ -175,6 +182,11 @@ protected: rgb_color fHighColor; rgb_color fLowColor; + + color_which fWhichHighColor; + color_which fWhichLowColor; + float fWhichHighColorTint; + float fWhichLowColorTint; Pattern fPattern; drawing_mode fDrawingMode; diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 3d23fdeceb..aaef69de94 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -56,6 +56,7 @@ Server app_server : CursorData.cpp CursorManager.cpp CursorSet.cpp + DelayedMessage.cpp Desktop.cpp DesktopListener.cpp DesktopSettings.cpp diff --git a/src/servers/app/MessageLooper.h b/src/servers/app/MessageLooper.h index 9cacd304fb..d9c027175c 100644 --- a/src/servers/app/MessageLooper.h +++ b/src/servers/app/MessageLooper.h @@ -22,7 +22,9 @@ class MessageLooper : public BLocker { virtual bool Run(); virtual void Quit(); - status_t PostMessage(int32 code, bigtime_t timeout = B_INFINITE_TIMEOUT); + status_t PostMessage(int32 code, + bigtime_t timeout = B_INFINITE_TIMEOUT); + thread_id Thread() const { return fThread; } bool IsQuitting() const { return fQuitting; } sem_id DeathSemaphore() const { return fDeathSemaphore; } diff --git a/src/servers/app/ProfileMessageSupport.cpp b/src/servers/app/ProfileMessageSupport.cpp index 1dbb357d74..f48f3bdfea 100644 --- a/src/servers/app/ProfileMessageSupport.cpp +++ b/src/servers/app/ProfileMessageSupport.cpp @@ -271,11 +271,17 @@ string_for_message_code(uint32 code, BString& string) CODE(AS_VIEW_SET_PEN_SIZE); CODE(AS_VIEW_GET_PEN_SIZE); CODE(AS_VIEW_SET_HIGH_COLOR); + CODE(AS_VIEW_SET_HIGH_UI_COLOR); CODE(AS_VIEW_SET_LOW_COLOR); + CODE(AS_VIEW_SET_LOW_UI_COLOR); CODE(AS_VIEW_SET_VIEW_COLOR); + CODE(AS_VIEW_SET_VIEW_UI_COLOR); CODE(AS_VIEW_GET_HIGH_COLOR); + CODE(AS_VIEW_GET_HIGH_UI_COLOR); CODE(AS_VIEW_GET_LOW_COLOR); + CODE(AS_VIEW_GET_LOW_UI_COLOR); CODE(AS_VIEW_GET_VIEW_COLOR); + CODE(AS_VIEW_GET_VIEW_UI_COLOR); CODE(AS_VIEW_PRINT_ALIASING); CODE(AS_VIEW_CLIP_TO_PICTURE); CODE(AS_VIEW_GET_CLIP_REGION); @@ -292,6 +298,7 @@ string_for_message_code(uint32 code, BString& string) CODE(AS_VIEW_COPY_BITS); CODE(AS_VIEW_DRAW_PICTURE); CODE(AS_VIEW_INVALIDATE_RECT); + CODE(AS_VIEW_DELAYED_INVALIDATE_RECT); CODE(AS_VIEW_INVALIDATE_REGION); CODE(AS_VIEW_INVERT_RECT); CODE(AS_VIEW_MOVE_TO); @@ -307,6 +314,9 @@ string_for_message_code(uint32 code, BString& string) CODE(AS_DIRECT_WINDOW_GET_SYNC_DATA); CODE(AS_DIRECT_WINDOW_SET_FULLSCREEN); + // Internal messages + CODE(AS_COLOR_MAP_UPDATED); + default: string << "unkown code: " << code; break; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 678ab3e8bf..ec6432ab6a 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -12,6 +12,7 @@ * Andrej Spielmann, * Philippe Saint-Pierre, stpere@gmail.com * Wim van der Meer, + * Joseph Groover */ @@ -2813,25 +2814,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } - case AS_SET_UI_COLOR: - { - STRACE(("ServerApp %s: Set UI Color\n", Signature())); - - // Attached Data: - // 1) color_which which - // 2) rgb_color color - - color_which which; - rgb_color color; - - link.Read(&which); - if (link.Read(&color) == B_OK) { - LockedDesktopSettings settings(fDesktop); - settings.SetUIColor(which, color); - } - break; - } - case AS_GET_ACCELERANT_INFO: { STRACE(("ServerApp %s: get accelerant info\n", Signature())); @@ -3204,7 +3186,7 @@ ServerApp::_MessageLooper() STRACE(("info: ServerApp::_MessageLooper() listening on port %" B_PRId32 ".\n", fMessagePort)); - err = receiver.GetNextMessage(code, B_INFINITE_TIMEOUT); + err = receiver.GetNextMessage(code); if (err != B_OK || code == B_QUIT_REQUESTED) { STRACE(("ServerApp: application seems to be gone...\n")); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 6f813551d6..6d4a880c67 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -12,6 +12,7 @@ * Philippe Saint-Pierre * Brecht Machiels * Julian Harnath + * Joseph Groover */ @@ -1015,7 +1016,15 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { // Has the all-window look fDesktop->FontsChanged(fWindow); - // TODO: tell client about this, too, and relayout... + break; + } + + // Forward to client + case B_FONTS_UPDATED: + { + // TODO: would knowing which font was changed be useful? + BMessage message(code); + SendMessageToClient(&message); break; } @@ -1770,6 +1779,116 @@ fDesktop->LockSingleWindow(); fWindow->GetDrawingEngine()->SetHighColor(color); break; } + + case AS_VIEW_SET_HIGH_UI_COLOR: + { + color_which which = B_NO_COLOR; + float tint = B_NO_TINT; + + if (link.Read(&which) != B_OK + || link.Read(&tint) != B_OK ) + break; + + fCurrentView->CurrentState()->SetHighUIColor(which, tint); + + // TODO: should we do more color_which validity checking? + if (which != B_NO_COLOR) { + DesktopSettings settings(fDesktop); + rgb_color color = tint_color(settings.UIColor(which), tint); + + fCurrentView->CurrentState()->SetHighColor(color); + fWindow->GetDrawingEngine()->SetHighColor(color); + } + break; + } + case AS_VIEW_SET_LOW_UI_COLOR: + { + color_which which = B_NO_COLOR; + float tint = B_NO_TINT; + + if (link.Read(&which) != B_OK + || link.Read(&tint) != B_OK ) + break; + + fCurrentView->CurrentState()->SetLowUIColor(which, tint); + + // TODO: should we do more color_which validity checking? + if (which != B_NO_COLOR) { + DesktopSettings settings(fDesktop); + rgb_color color = tint_color(settings.UIColor(which), tint); + + fCurrentView->CurrentState()->SetLowColor(color); + fWindow->GetDrawingEngine()->SetLowColor(color); + } + break; + } + case AS_VIEW_SET_VIEW_UI_COLOR: + { + color_which which = B_NO_COLOR; + float tint = B_NO_TINT; + + if (link.Read(&which) != B_OK + || link.Read(&tint) != B_OK ) + break; + + // TODO: should we do more color_which validity checking? + fCurrentView->SetViewUIColor(which, tint); + break; + } + case AS_VIEW_GET_HIGH_UI_COLOR: + { + float tint; + color_which which = fCurrentView->CurrentState()->HighUIColor(&tint); + rgb_color color = fCurrentView->CurrentState()->HighColor(); + + DTRACE(("ServerWindow %s: Message AS_VIEW_GET_HIGH_UI_COLOR: " + "View: %s -> color_which(%i) tint(%.3f) - rgb_color(%i, %i," + " %i, %i)\n", Title(), fCurrentView->Name(), which, tint, + color.red, color.green, color.blue, color.alpha)); + + fLink.StartMessage(B_OK); + fLink.Attach(which); + fLink.Attach(tint); + fLink.Attach(color); + fLink.Flush(); + break; + } + case AS_VIEW_GET_LOW_UI_COLOR: + { + float tint; + color_which which = fCurrentView->CurrentState()->LowUIColor(&tint); + rgb_color color = fCurrentView->CurrentState()->LowColor(); + + DTRACE(("ServerWindow %s: Message AS_VIEW_GET_LOW_UI_COLOR: " + "View: %s -> color_which(%i) tint(%.3f) - rgb_color(%i, %i," + " %i, %i)\n", Title(), fCurrentView->Name(), which, tint, + color.red, color.green, color.blue, color.alpha)); + + fLink.StartMessage(B_OK); + fLink.Attach(which); + fLink.Attach(tint); + fLink.Attach(color); + fLink.Flush(); + break; + } + case AS_VIEW_GET_VIEW_UI_COLOR: + { + float tint; + color_which which = fCurrentView->ViewUIColor(&tint); + rgb_color color = fCurrentView->ViewColor(); + + DTRACE(("ServerWindow %s: Message AS_VIEW_GET_VIEW_UI_COLOR: " + "View: %s -> color_which(%i) tint(%.3f) - rgb_color(%i, %i," + " %i, %i)\n", Title(), fCurrentView->Name(), which, tint, + color.red, color.green, color.blue, color.alpha)); + + fLink.StartMessage(B_OK); + fLink.Attach(which); + fLink.Attach(tint); + fLink.Attach(color); + fLink.Flush(); + break; + } case AS_VIEW_GET_HIGH_COLOR: { rgb_color color = fCurrentView->CurrentState()->HighColor(); @@ -2112,11 +2231,45 @@ fDesktop->LockSingleWindow(); fCurrentView->Name(), invalidRect.left, invalidRect.top, invalidRect.right, invalidRect.bottom)); + View* view = NULL; + if (link.Read(&view) != B_OK) + view = fCurrentView; + + // make sure the view is still available! + if (view != fCurrentView + && !fWindow->TopView()->HasView(view)) + break; + BRegion dirty(invalidRect); - fWindow->InvalidateView(fCurrentView, dirty); + fWindow->InvalidateView(view, dirty); } break; } + + case AS_VIEW_DELAYED_INVALIDATE_RECT: + { + bigtime_t time = 0; + BRect invalidRect; + if (link.Read(&time) == B_OK + && link.Read(&invalidRect) == B_OK) { + DTRACE(("ServerWindow %s: Message " + "AS_VIEW_DELAYED_INVALIDATE_RECT: " + "View: %s -> BRect(%.1f, %.1f, %.1f, %.1f) at time %llu\n", + Title(), fCurrentView->Name(), invalidRect.left, + invalidRect.top, invalidRect.right, invalidRect.bottom, + time)); + + DelayedMessage delayed(AS_VIEW_INVALIDATE_RECT, time, true); + delayed.AddTarget(MessagePort()); + delayed.SetMerge(DM_MERGE_DUPLICATES); + + if (delayed.Attach(invalidRect) == B_OK + && delayed.Attach(fCurrentView) == B_OK) + delayed.Flush(); + } + break; + } + case AS_VIEW_INVALIDATE_REGION: { // NOTE: looks like this call is NOT affected by origin and scale diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 660902e5c0..554308d475 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -10,6 +10,7 @@ * Marcus Overhagen * Adrien Destugues + * Joseph Groover */ #include "View.h" @@ -90,6 +91,8 @@ View::View(IntRect frame, IntPoint scrollingOffset, const char* name, fScrollingOffset(scrollingOffset), fViewColor((rgb_color){ 255, 255, 255, 255 }), + fWhichViewColor(B_NO_COLOR), + fWhichViewColorTint(B_NO_TINT), fViewBitmap(NULL), fBitmapResizingMode(0), fBitmapOptions(0), @@ -436,6 +439,21 @@ View::FindViews(uint32 flags, BObjectList& list, int32& left) } +bool +View::HasView(View* view) +{ + if (view == this) + return true; + + for (View* child = FirstChild(); child; child = child->NextSibling()) { + if (child->HasView(view)) + return true; + } + + return false; +} + + View* View::ViewAt(const BPoint& where) { @@ -907,6 +925,54 @@ View::CopyBits(IntRect src, IntRect dst, BRegion& windowContentClipping) // #pragma mark - +void +View::ColorUpdated(color_which which, rgb_color color) +{ + float tint = B_NO_TINT; + + if (fWhichViewColor == which) + SetViewColor(tint_color(color, fWhichViewColorTint)); + + if (CurrentState()->HighUIColor(&tint) == which) + CurrentState()->SetHighColor(tint_color(color, tint)); + + if (CurrentState()->LowUIColor(&tint) == which) + CurrentState()->SetLowColor(tint_color(color, tint)); + + for (View* child = FirstChild(); child != NULL; + child = child->NextSibling()) { + + child->ColorUpdated(which, color); + } +} + + +void +View::SetViewUIColor(color_which which, float tint) +{ + if (which != B_NO_COLOR) { + DesktopSettings settings(fWindow->Desktop()); + SetViewColor(tint_color(settings.UIColor(which), tint)); + } + + fWhichViewColor = which; + fWhichViewColorTint = tint; +} + + +color_which +View::ViewUIColor(float* tint) +{ + if (tint != NULL) + *tint = fWhichViewColorTint; + + return fWhichViewColor; +} + + +// #pragma mark - + + void View::PushState() { diff --git a/src/servers/app/View.h b/src/servers/app/View.h index cf19fa762e..84e2b3cf16 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -10,6 +10,7 @@ * Marcus Overhagen * Adrien Destugues * Julian Harnath + * Joseph Groover */ #ifndef VIEW_H #define VIEW_H @@ -19,6 +20,7 @@ #include "IntRect.h" #include +#include #include #include #include @@ -110,6 +112,7 @@ public: void FindViews(uint32 flags, BObjectList& list, int32& left); + bool HasView(View* view); View* ViewAt(const BPoint& where); public: @@ -135,6 +138,10 @@ public: void SetViewColor(const rgb_color& color) { fViewColor = color; } + void ColorUpdated(color_which which, rgb_color color); + void SetViewUIColor(color_which which, float tint); + color_which ViewUIColor(float* tint); + ServerBitmap* ViewBitmap() const { return fViewBitmap; } void SetViewBitmap(ServerBitmap* bitmap, @@ -234,6 +241,8 @@ protected: IntPoint fScrollingOffset; rgb_color fViewColor; + color_which fWhichViewColor; + float fWhichViewColorTint; ServerBitmap* fViewBitmap; IntRect fBitmapSource; IntRect fBitmapDestination; diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 8af42bd2bd..40e95b1896 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -1242,6 +1242,17 @@ Window::FontsChanged(BRegion* updateRegion) } +void +Window::ColorsChanged(BRegion* updateRegion) +{ + ::Decorator* decorator = Decorator(); + if (decorator != NULL) { + DesktopSettings settings(fDesktop); + decorator->ColorsChanged(settings, updateRegion); + } +} + + void Window::SetLook(window_look look, BRegion* updateRegion) { diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h index 6817df2bd3..1de625c249 100644 --- a/src/servers/app/Window.h +++ b/src/servers/app/Window.h @@ -243,6 +243,7 @@ public: void HighlightDecorator(bool active); void FontsChanged(BRegion* updateRegion); + void ColorsChanged(BRegion* updateRegion); void SetLook(window_look look, BRegion* updateRegion); diff --git a/src/servers/app/decorator/DecorManager.cpp b/src/servers/app/decorator/DecorManager.cpp index 59e6f539a8..b09830ebef 100644 --- a/src/servers/app/decorator/DecorManager.cpp +++ b/src/servers/app/decorator/DecorManager.cpp @@ -63,11 +63,13 @@ DecorAddOn::AllocateDecorator(Desktop* desktop, DrawingEngine* engine, DesktopSettings settings(desktop); Decorator* decorator; - decorator = _AllocateDecorator(settings, rect); + decorator = _AllocateDecorator(settings, rect, desktop); desktop->UnlockSingleWindow(); if (!decorator) return NULL; + decorator->UpdateColors(settings); + if (decorator->AddTab(settings, title, look, flags) == false) { delete decorator; return NULL; @@ -94,9 +96,10 @@ DecorAddOn::GetDesktopListeners() Decorator* -DecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect) +DecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect, + Desktop* desktop) { - return new (std::nothrow)SATDecorator(settings, rect); + return new (std::nothrow)SATDecorator(settings, rect, desktop); } diff --git a/src/servers/app/decorator/DecorManager.h b/src/servers/app/decorator/DecorManager.h index d5826c22f2..eeb8864b54 100644 --- a/src/servers/app/decorator/DecorManager.h +++ b/src/servers/app/decorator/DecorManager.h @@ -53,7 +53,7 @@ public: protected: virtual Decorator* _AllocateDecorator(DesktopSettings& settings, - BRect rect); + BRect rect, Desktop* desktop); DesktopListenerList fDesktopListeners; diff --git a/src/servers/app/decorator/Decorator.cpp b/src/servers/app/decorator/Decorator.cpp index 0823257026..d35c49edf9 100644 --- a/src/servers/app/decorator/Decorator.cpp +++ b/src/servers/app/decorator/Decorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -8,6 +8,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ @@ -20,6 +21,8 @@ #include +#include "Desktop.h" +#include "DesktopSettings.h" #include "DrawingEngine.h" @@ -68,7 +71,8 @@ Decorator::Tab::Tab() \param settings DesktopSettings pointer. \param frame Decorator frame rectangle */ -Decorator::Decorator(DesktopSettings& settings, BRect frame) +Decorator::Decorator(DesktopSettings& settings, BRect frame, + Desktop* desktop) : fDrawingEngine(NULL), fDrawState(), @@ -87,6 +91,7 @@ Decorator::Decorator(DesktopSettings& settings, BRect frame) fTopTab(NULL), + fDesktop(desktop), fFootprintValid(false) { memset(&fRegionHighlights, HIGHLIGHT_NONE, sizeof(fRegionHighlights)); @@ -234,11 +239,26 @@ Decorator::SetFlags(int32 tab, uint32 flags, BRegion* updateRegion) void Decorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion) { + _FontsChanged(settings, updateRegion); _InvalidateFootprint(); } +/*! \brief Called when a system colors change. +*/ +void +Decorator::ColorsChanged(DesktopSettings& settings, BRegion* updateRegion) +{ + UpdateColors(settings); + + if (updateRegion != NULL) + updateRegion->Include(&GetFootprint()); + + _InvalidateBitmaps(); +} + + /*! \brief Sets the decorator's window look \param look New value for the look */ @@ -249,6 +269,7 @@ Decorator::SetLook(int32 tab, DesktopSettings& settings, window_look look, Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; + _SetLook(decoratorTab, settings, look, updateRect); _InvalidateFootprint(); // the border very likely changed @@ -496,6 +517,15 @@ Decorator::GetFootprint() } +/*! \brief Returns our Desktop object pointer +*/ +::Desktop* +Decorator::GetDesktop() +{ + return fDesktop; +} + + /*! \brief Performs hit-testing for the decorator. The base class provides a basic implementation, recognizing only button and @@ -821,9 +851,8 @@ Decorator::DrawZoom(int32 tab) rgb_color Decorator::UIColor(color_which which) { - // TODO: for now - calling ui_color() from within the app_server - // will always return the default colors (as there is no be_app) - return ui_color(which); + DesktopSettings settings(fDesktop); + return settings.UIColor(which); } diff --git a/src/servers/app/decorator/Decorator.h b/src/servers/app/decorator/Decorator.h index 186bd69169..44440a83ca 100644 --- a/src/servers/app/decorator/Decorator.h +++ b/src/servers/app/decorator/Decorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -8,6 +8,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ #ifndef DECORATOR_H #define DECORATOR_H @@ -20,6 +21,7 @@ #include "DrawState.h" +class Desktop; class DesktopSettings; class DrawingEngine; class ServerBitmap; @@ -98,7 +100,8 @@ public: }; Decorator(DesktopSettings& settings, - BRect frame); + BRect frame, + Desktop* desktop); virtual ~Decorator(); virtual Decorator::Tab* AddTab(DesktopSettings& settings, @@ -123,6 +126,11 @@ public: void FontsChanged(DesktopSettings& settings, BRegion* updateRegion = NULL); + void ColorsChanged(DesktopSettings& settings, + BRegion* updateRegion = NULL); + + virtual void UpdateColors(DesktopSettings& settings) = 0; + void SetLook(int32 tab, DesktopSettings& settings, window_look look, BRegion* updateRegion = NULL); @@ -160,6 +168,7 @@ public: virtual Region RegionAt(BPoint where, int32& tab) const; const BRegion& GetFootprint(); + ::Desktop* GetDesktop(); void MoveBy(float x, float y); void MoveBy(BPoint offset); @@ -281,6 +290,7 @@ protected: BObjectList fTabList; private: + Desktop* fDesktop; BRegion fFootprint; bool fFootprintValid : 1; diff --git a/src/servers/app/decorator/DefaultDecorator.cpp b/src/servers/app/decorator/DefaultDecorator.cpp index c12853ea11..51ad0c063b 100644 --- a/src/servers/app/decorator/DefaultDecorator.cpp +++ b/src/servers/app/decorator/DefaultDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ @@ -72,9 +73,10 @@ blend_color_value(uint8 a, uint8 b, float position) // TODO: get rid of DesktopSettings here, and introduce private accessor // methods to the Decorator base class -DefaultDecorator::DefaultDecorator(DesktopSettings& settings, BRect rect) +DefaultDecorator::DefaultDecorator(DesktopSettings& settings, BRect rect, + Desktop* desktop) : - TabDecorator(settings, rect) + TabDecorator(settings, rect, desktop) { // TODO: If the decorator was created with a frame too small, it should // resize itself! @@ -112,35 +114,35 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight, case COMPONENT_TAB: if (tab && tab->buttonFocus) { _colors[COLOR_TAB_FRAME_LIGHT] - = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); + = tint_color(fFocusFrameColor, B_DARKEN_2_TINT); _colors[COLOR_TAB_FRAME_DARK] - = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); - _colors[COLOR_TAB] = kFocusTabColor; - _colors[COLOR_TAB_LIGHT] = kFocusTabColorLight; - _colors[COLOR_TAB_BEVEL] = kFocusTabColorBevel; - _colors[COLOR_TAB_SHADOW] = kFocusTabColorShadow; - _colors[COLOR_TAB_TEXT] = kFocusTextColor; + = tint_color(fFocusFrameColor, B_DARKEN_3_TINT); + _colors[COLOR_TAB] = fFocusTabColor; + _colors[COLOR_TAB_LIGHT] = fFocusTabColorLight; + _colors[COLOR_TAB_BEVEL] = fFocusTabColorBevel; + _colors[COLOR_TAB_SHADOW] = fFocusTabColorShadow; + _colors[COLOR_TAB_TEXT] = fFocusTextColor; } else { _colors[COLOR_TAB_FRAME_LIGHT] - = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); + = tint_color(fNonFocusFrameColor, B_DARKEN_2_TINT); _colors[COLOR_TAB_FRAME_DARK] - = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); - _colors[COLOR_TAB] = kNonFocusTabColor; - _colors[COLOR_TAB_LIGHT] = kNonFocusTabColorLight; - _colors[COLOR_TAB_BEVEL] = kNonFocusTabColorBevel; - _colors[COLOR_TAB_SHADOW] = kNonFocusTabColorShadow; - _colors[COLOR_TAB_TEXT] = kNonFocusTextColor; + = tint_color(fNonFocusFrameColor, B_DARKEN_3_TINT); + _colors[COLOR_TAB] = fNonFocusTabColor; + _colors[COLOR_TAB_LIGHT] = fNonFocusTabColorLight; + _colors[COLOR_TAB_BEVEL] = fNonFocusTabColorBevel; + _colors[COLOR_TAB_SHADOW] = fNonFocusTabColorShadow; + _colors[COLOR_TAB_TEXT] = fNonFocusTextColor; } break; case COMPONENT_CLOSE_BUTTON: case COMPONENT_ZOOM_BUTTON: if (tab && tab->buttonFocus) { - _colors[COLOR_BUTTON] = kFocusTabColor; - _colors[COLOR_BUTTON_LIGHT] = kFocusTabColorLight; + _colors[COLOR_BUTTON] = fFocusTabColor; + _colors[COLOR_BUTTON_LIGHT] = fFocusTabColorLight; } else { - _colors[COLOR_BUTTON] = kNonFocusTabColor; - _colors[COLOR_BUTTON_LIGHT] = kNonFocusTabColorLight; + _colors[COLOR_BUTTON] = fNonFocusTabColor; + _colors[COLOR_BUTTON_LIGHT] = fNonFocusTabColorLight; } break; @@ -151,21 +153,21 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight, case COMPONENT_RESIZE_CORNER: default: if (tab && tab->buttonFocus) { - _colors[0] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[1] = tint_color(kFocusFrameColor, B_LIGHTEN_2_TINT); - _colors[2] = kFocusFrameColor; - _colors[3] = tint_color(kFocusFrameColor, + _colors[0] = tint_color(fFocusFrameColor, B_DARKEN_2_TINT); + _colors[1] = tint_color(fFocusFrameColor, B_LIGHTEN_2_TINT); + _colors[2] = fFocusFrameColor; + _colors[3] = tint_color(fFocusFrameColor, (B_DARKEN_1_TINT + B_NO_TINT) / 2); - _colors[4] = tint_color(kFocusFrameColor, B_DARKEN_2_TINT); - _colors[5] = tint_color(kFocusFrameColor, B_DARKEN_3_TINT); + _colors[4] = tint_color(fFocusFrameColor, B_DARKEN_2_TINT); + _colors[5] = tint_color(fFocusFrameColor, B_DARKEN_3_TINT); } else { - _colors[0] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); - _colors[1] = tint_color(kNonFocusFrameColor, B_LIGHTEN_2_TINT); - _colors[2] = kNonFocusFrameColor; - _colors[3] = tint_color(kNonFocusFrameColor, + _colors[0] = tint_color(fNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[1] = tint_color(fNonFocusFrameColor, B_LIGHTEN_2_TINT); + _colors[2] = fNonFocusFrameColor; + _colors[3] = tint_color(fNonFocusFrameColor, (B_DARKEN_1_TINT + B_NO_TINT) / 2); - _colors[4] = tint_color(kNonFocusFrameColor, B_DARKEN_2_TINT); - _colors[5] = tint_color(kNonFocusFrameColor, B_DARKEN_3_TINT); + _colors[4] = tint_color(fNonFocusFrameColor, B_DARKEN_2_TINT); + _colors[5] = tint_color(fNonFocusFrameColor, B_DARKEN_3_TINT); } // for the resize-border highlight dye everything bluish. @@ -181,6 +183,13 @@ DefaultDecorator::GetComponentColors(Component component, uint8 highlight, } +void +DefaultDecorator::UpdateColors(DesktopSettings& settings) +{ + TabDecorator::UpdateColors(settings); +} + + // #pragma mark - Protected methods diff --git a/src/servers/app/decorator/DefaultDecorator.h b/src/servers/app/decorator/DefaultDecorator.h index e8ae5d5d3e..5d9448f83b 100644 --- a/src/servers/app/decorator/DefaultDecorator.h +++ b/src/servers/app/decorator/DefaultDecorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ #ifndef DEFAULT_DECORATOR_H #define DEFAULT_DECORATOR_H @@ -25,13 +26,15 @@ class ServerBitmap; class DefaultDecorator: public TabDecorator { public: DefaultDecorator(DesktopSettings& settings, - BRect frame); + BRect frame, Desktop* desktop); virtual ~DefaultDecorator(); virtual void GetComponentColors(Component component, uint8 highlight, ComponentColors _colors, Decorator::Tab* tab = NULL); + virtual void UpdateColors(DesktopSettings& settings); + protected: virtual void _DrawFrame(BRect rect); diff --git a/src/servers/app/decorator/TabDecorator.cpp b/src/servers/app/decorator/TabDecorator.cpp index 44352063fb..a5953f2ea6 100644 --- a/src/servers/app/decorator/TabDecorator.cpp +++ b/src/servers/app/decorator/TabDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ @@ -63,28 +64,11 @@ static const float kResizeKnobSize = 18.0; // TODO: get rid of DesktopSettings here, and introduce private accessor // methods to the Decorator base class -TabDecorator::TabDecorator(DesktopSettings& settings, BRect frame) +TabDecorator::TabDecorator(DesktopSettings& settings, BRect frame, + Desktop* desktop) : - Decorator(settings, frame), - fOldMovingTab(0, 0, -1, -1), - // focus color constants - kFocusFrameColor(settings.UIColor(B_WINDOW_BORDER_COLOR)), - kFocusTabColor(settings.UIColor(B_WINDOW_TAB_COLOR)), - kFocusTabColorLight(tint_color(kFocusTabColor, - (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2)), - kFocusTabColorBevel(tint_color(kFocusTabColor, B_LIGHTEN_2_TINT)), - kFocusTabColorShadow(tint_color(kFocusTabColor, - (B_DARKEN_1_TINT + B_NO_TINT) / 2)), - kFocusTextColor(settings.UIColor(B_WINDOW_TEXT_COLOR)), - // non-focus color constants - kNonFocusFrameColor(settings.UIColor(B_WINDOW_INACTIVE_BORDER_COLOR)), - kNonFocusTabColor(settings.UIColor(B_WINDOW_INACTIVE_TAB_COLOR)), - kNonFocusTabColorLight(tint_color(kNonFocusTabColor, - (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2)), - kNonFocusTabColorBevel(tint_color(kNonFocusTabColor, B_LIGHTEN_2_TINT)), - kNonFocusTabColorShadow(tint_color(kNonFocusTabColor, - (B_DARKEN_1_TINT + B_NO_TINT) / 2)), - kNonFocusTextColor(settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR)) + Decorator(settings, frame, desktop), + fOldMovingTab(0, 0, -1, -1) { STRACE(("TabDecorator:\n")); STRACE(("\tFrame (%.1f,%.1f,%.1f,%.1f)\n", @@ -209,6 +193,30 @@ TabDecorator::SetRegionHighlight(Region region, uint8 highlight, } +void +TabDecorator::UpdateColors(DesktopSettings& settings) +{ + // Desktop is write locked, so be quick about it. + fFocusFrameColor = settings.UIColor(B_WINDOW_BORDER_COLOR); + fFocusTabColor = settings.UIColor(B_WINDOW_TAB_COLOR); + fFocusTabColorLight = tint_color(fFocusTabColor, + (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2); + fFocusTabColorBevel = tint_color(fFocusTabColor, B_LIGHTEN_2_TINT); + fFocusTabColorShadow = tint_color(fFocusTabColor, + (B_DARKEN_1_TINT + B_NO_TINT) / 2); + fFocusTextColor = settings.UIColor(B_WINDOW_TEXT_COLOR); + + fNonFocusFrameColor = settings.UIColor(B_WINDOW_INACTIVE_BORDER_COLOR); + fNonFocusTabColor = settings.UIColor(B_WINDOW_INACTIVE_TAB_COLOR); + fNonFocusTabColorLight = tint_color(fNonFocusTabColor, + (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2); + fNonFocusTabColorBevel = tint_color(fNonFocusTabColor, B_LIGHTEN_2_TINT); + fNonFocusTabColorShadow = tint_color(fNonFocusTabColor, + (B_DARKEN_1_TINT + B_NO_TINT) / 2); + fNonFocusTextColor = settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR); +} + + void TabDecorator::_DoLayout() { diff --git a/src/servers/app/decorator/TabDecorator.h b/src/servers/app/decorator/TabDecorator.h index 17fb59f2b5..781d33a92b 100644 --- a/src/servers/app/decorator/TabDecorator.h +++ b/src/servers/app/decorator/TabDecorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013 Haiku, Inc. + * Copyright 2001-2015 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ * John Scipione, jscipione@gmail.com * Ingo Weinhold, ingo_weinhold@gmx.de * Clemens Zeidler, haiku@clemens-zeidler.de + * Joseph Groover */ #ifndef TAB_DECORATOR_H #define TAB_DECORATOR_H @@ -26,7 +27,7 @@ class Desktop; class TabDecorator: public Decorator { public: TabDecorator(DesktopSettings& settings, - BRect frame); + BRect frame, Desktop* desktop); virtual ~TabDecorator(); protected: @@ -71,6 +72,8 @@ public: uint8 highlight, BRegion* dirty, int32 tab = -1); + virtual void UpdateColors(DesktopSettings& settings); + protected: virtual void _DoLayout(); virtual void _DoTabLayout(); @@ -132,21 +135,21 @@ protected: BRegion fTabsRegion; BRect fOldMovingTab; - const rgb_color kFocusFrameColor; + rgb_color fFocusFrameColor; - const rgb_color kFocusTabColor; - const rgb_color kFocusTabColorLight; - const rgb_color kFocusTabColorBevel; - const rgb_color kFocusTabColorShadow; - const rgb_color kFocusTextColor; + rgb_color fFocusTabColor; + rgb_color fFocusTabColorLight; + rgb_color fFocusTabColorBevel; + rgb_color fFocusTabColorShadow; + rgb_color fFocusTextColor; - const rgb_color kNonFocusFrameColor; + rgb_color fNonFocusFrameColor; - const rgb_color kNonFocusTabColor; - const rgb_color kNonFocusTabColorLight; - const rgb_color kNonFocusTabColorBevel; - const rgb_color kNonFocusTabColorShadow; - const rgb_color kNonFocusTextColor; + rgb_color fNonFocusTabColor; + rgb_color fNonFocusTabColorLight; + rgb_color fNonFocusTabColorBevel; + rgb_color fNonFocusTabColorShadow; + rgb_color fNonFocusTextColor; }; diff --git a/src/servers/app/stackandtile/SATDecorator.cpp b/src/servers/app/stackandtile/SATDecorator.cpp index d4c1503652..62796aa2fa 100644 --- a/src/servers/app/stackandtile/SATDecorator.cpp +++ b/src/servers/app/stackandtile/SATDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010, Haiku, Inc. + * Copyright 2010-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -46,19 +46,29 @@ static const rgb_color kHighlightFrameColors[6] = { { 8, 8, 8, 255 } }; -SATDecorator::SATDecorator(DesktopSettings& settings, BRect frame) +SATDecorator::SATDecorator(DesktopSettings& settings, BRect frame, + Desktop* desktop) : - DefaultDecorator(settings, frame), - kHighlightTabColor(tint_color(kFocusTabColor, B_DARKEN_2_TINT)), - kHighlightTabColorLight(tint_color(kHighlightTabColor, - (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2)), - kHighlightTabColorBevel(tint_color(kHighlightTabColor, B_LIGHTEN_2_TINT)), - kHighlightTabColorShadow(tint_color(kHighlightTabColor, - (B_DARKEN_1_TINT + B_NO_TINT) / 2)) + DefaultDecorator(settings, frame, desktop) { } +void +SATDecorator::UpdateColors(DesktopSettings& settings) +{ + DefaultDecorator::UpdateColors(settings); + + // Called during construction, and during any changes + fHighlightTabColor = tint_color(fFocusTabColor, B_DARKEN_2_TINT); + fHighlightTabColorLight = tint_color(fHighlightTabColor, + (B_LIGHTEN_MAX_TINT + B_LIGHTEN_2_TINT) / 2); + fHighlightTabColorBevel = tint_color(fHighlightTabColor, B_LIGHTEN_2_TINT); + fHighlightTabColorShadow= tint_color(fHighlightTabColor, + (B_DARKEN_1_TINT + B_NO_TINT) / 2); +} + + void SATDecorator::GetComponentColors(Component component, uint8 highlight, ComponentColors _colors, Decorator::Tab* _tab) @@ -82,17 +92,17 @@ SATDecorator::GetComponentColors(Component component, uint8 highlight, case COMPONENT_TAB: _colors[COLOR_TAB_FRAME_LIGHT] = kFrameColors[0]; _colors[COLOR_TAB_FRAME_DARK] = kFrameColors[3]; - _colors[COLOR_TAB] = kHighlightTabColor; - _colors[COLOR_TAB_LIGHT] = kHighlightTabColorLight; - _colors[COLOR_TAB_BEVEL] = kHighlightTabColorBevel; - _colors[COLOR_TAB_SHADOW] = kHighlightTabColorShadow; - _colors[COLOR_TAB_TEXT] = kFocusTextColor; + _colors[COLOR_TAB] = fHighlightTabColor; + _colors[COLOR_TAB_LIGHT] = fHighlightTabColorLight; + _colors[COLOR_TAB_BEVEL] = fHighlightTabColorBevel; + _colors[COLOR_TAB_SHADOW] = fHighlightTabColorShadow; + _colors[COLOR_TAB_TEXT] = fFocusTextColor; break; case COMPONENT_CLOSE_BUTTON: case COMPONENT_ZOOM_BUTTON: - _colors[COLOR_BUTTON] = kHighlightTabColor; - _colors[COLOR_BUTTON_LIGHT] = kHighlightTabColorLight; + _colors[COLOR_BUTTON] = fHighlightTabColor; + _colors[COLOR_BUTTON_LIGHT] = fHighlightTabColorLight; break; case COMPONENT_LEFT_BORDER: diff --git a/src/servers/app/stackandtile/SATDecorator.h b/src/servers/app/stackandtile/SATDecorator.h index 9c2bcd4ad6..4f548b4fb3 100644 --- a/src/servers/app/stackandtile/SATDecorator.h +++ b/src/servers/app/stackandtile/SATDecorator.h @@ -1,5 +1,5 @@ /* - * Copyright 2010, Haiku, Inc. + * Copyright 2010-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -15,6 +15,9 @@ #include "StackAndTile.h" +class Desktop; + + class SATDecorator : public DefaultDecorator { public: enum { @@ -23,18 +26,19 @@ public: public: SATDecorator(DesktopSettings& settings, - BRect frame); + BRect frame, Desktop* desktop); protected: + virtual void UpdateColors(DesktopSettings& settings); virtual void GetComponentColors(Component component, uint8 highlight, ComponentColors _colors, Decorator::Tab* tab = NULL); private: - const rgb_color kHighlightTabColor; - const rgb_color kHighlightTabColorLight; - const rgb_color kHighlightTabColorBevel; - const rgb_color kHighlightTabColorShadow; + rgb_color fHighlightTabColor; + rgb_color fHighlightTabColorLight; + rgb_color fHighlightTabColorBevel; + rgb_color fHighlightTabColorShadow; };