BColorControl: Rebuild control after mode switch

App Server sends each window a message that the screen has changed:
https://www.haiku-os.org/legacy-docs/bebook/BWindow.html#BWindow_ScreenChanged
Propegate B_SCREEN_CHANGED message to all child views first

Tell BColorControl to read the B_SCREEN_CHANGED message and reinitialize itself.

* Only reinit if switching to or from B_CMAP8
* Initialize all pointers to NULL in constructor
* Don't destroy and rebuild offscreen view (and text views) on reinit
* Reinitialize offscreen view on reinit.

Fixes #8035

Also initialzing the pointers to NULL in constructor fixes #12673
This commit is contained in:
John Scipione
2016-03-12 19:13:35 -08:00
parent 0e3b3f92ef
commit 76b9d53bd0
3 changed files with 72 additions and 9 deletions
+44 -2
View File
@@ -52,7 +52,12 @@ BColorControl::BColorControl(BPoint leftTop, color_control_layout layout,
float cellSize, const char* name, BMessage* message, bool useOffscreen) float cellSize, const char* name, BMessage* message, bool useOffscreen)
: :
BControl(BRect(leftTop, leftTop), name, NULL, message, BControl(BRect(leftTop, leftTop), name, NULL, message,
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE),
fRedText(NULL),
fGreenText(NULL),
fBlueText(NULL),
fBitmap(NULL),
fOffscreenView(NULL)
{ {
_InitData(layout, cellSize, useOffscreen, NULL); _InitData(layout, cellSize, useOffscreen, NULL);
} }
@@ -60,7 +65,12 @@ BColorControl::BColorControl(BPoint leftTop, color_control_layout layout,
BColorControl::BColorControl(BMessage* data) BColorControl::BColorControl(BMessage* data)
: :
BControl(data) BControl(data),
fRedText(NULL),
fGreenText(NULL),
fBlueText(NULL),
fBitmap(NULL),
fOffscreenView(NULL)
{ {
int32 layout; int32 layout;
float cellSize; float cellSize;
@@ -174,6 +184,7 @@ BColorControl::_InitData(color_control_layout layout, float size,
ResizeToPreferred(); ResizeToPreferred();
if (useOffscreen) { if (useOffscreen) {
if (fOffscreenView != NULL) {
BRect bounds = _PaletteFrame(); BRect bounds = _PaletteFrame();
fBitmap = new BBitmap(bounds, B_RGB32, true, false); fBitmap = new BBitmap(bounds, B_RGB32, true, false);
fOffscreenView = new BView(bounds, "off_view", 0, 0); fOffscreenView = new BView(bounds, "off_view", 0, 0);
@@ -181,6 +192,7 @@ BColorControl::_InitData(color_control_layout layout, float size,
fBitmap->Lock(); fBitmap->Lock();
fBitmap->AddChild(fOffscreenView); fBitmap->AddChild(fOffscreenView);
fBitmap->Unlock(); fBitmap->Unlock();
}
} else { } else {
fBitmap = NULL; fBitmap = NULL;
fOffscreenView = NULL; fOffscreenView = NULL;
@@ -363,6 +375,36 @@ BColorControl::MessageReceived(BMessage* message)
Invoke(); Invoke();
break; break;
} }
case B_SCREEN_CHANGED:
{
BRect frame;
uint32 mode;
if (message->FindRect("frame", &frame) == B_OK
&& message->FindInt32("mode", (int32*)&mode) == B_OK) {
if ((fPaletteMode && mode == B_CMAP8)
|| (!fPaletteMode && mode != B_CMAP8)) {
// not switching to or from B_CMAP8, break
break;
}
// fake an archive message (so we don't rebuild views)
BMessage* data = new BMessage();
data->AddInt32("_val", Value());
// reinititialize
bool useOffscreen = fOffscreenView != NULL;
_InitData((color_control_layout)fColumns, fCellSize,
useOffscreen, data);
if (useOffscreen)
_InitOffscreen();
// cleanup
delete data;
}
break;
}
default: default:
BControl::MessageReceived(message); BControl::MessageReceived(message);
} }
+12
View File
@@ -4955,6 +4955,18 @@ BView::MessageReceived(BMessage* message)
case B_FONTS_UPDATED: case B_FONTS_UPDATED:
break; break;
case B_SCREEN_CHANGED:
{
// propegate message to child views
int32 childCount = CountChildren();
for (int32 i = 0; i < childCount; i++) {
BView* view = ChildAt(i);
if (view != NULL)
view->MessageReceived(message);
}
break;
}
default: default:
BHandler::MessageReceived(message); BHandler::MessageReceived(message);
break; break;
+10 -1
View File
@@ -1111,8 +1111,17 @@ FrameMoved(origin);
BRect frame; BRect frame;
uint32 mode; uint32 mode;
if (message->FindRect("frame", &frame) == B_OK if (message->FindRect("frame", &frame) == B_OK
&& message->FindInt32("mode", (int32*)&mode) == B_OK) && message->FindInt32("mode", (int32*)&mode) == B_OK) {
// propegate message to child views
int32 childCount = CountChildren();
for (int32 i = 0; i < childCount; i++) {
BView* view = ChildAt(i);
if (view != NULL)
view->MessageReceived(message);
}
// call hook method
ScreenChanged(frame, (color_space)mode); ScreenChanged(frame, (color_space)mode);
}
} else } else
target->MessageReceived(message); target->MessageReceived(message);
break; break;