From 15c87be3ead81e86041e5a1bef680144471e89fa Mon Sep 17 00:00:00 2001 From: John Scipione Date: Sun, 18 May 2025 11:47:10 -0400 Subject: [PATCH] ColorListView: Handle color dropped on unselected Remove shared message handling from ColorListView, you are expected to implement this yourself and these message constants were not actually being used by the message target. Do color drop handling in Appearance and Terminal. Handle all color drops in WasDropped(). Allow current selection to remain, only update color. TODO Changing selection on external drops should be fixed in BListView. Work-around in BColorListView. Fixes #19562 Change-Id: Ic99bbb1288fd736778eac831d38e453122815abc Reviewed-on: https://review.haiku-os.org/c/haiku/+/9296 Reviewed-by: John Scipione Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/private/shared/ColorListView.h | 10 +-- src/apps/terminal/TermWindow.cpp | 2 - src/apps/terminal/ThemeView.cpp | 75 ++++++++----------- src/apps/terminal/ThemeView.h | 2 +- src/kits/shared/ColorListView.cpp | 44 +---------- src/preferences/appearance/ColorsView.cpp | 91 ++++++++++------------- src/preferences/appearance/ColorsView.h | 1 + 7 files changed, 79 insertions(+), 146 deletions(-) diff --git a/headers/private/shared/ColorListView.h b/headers/private/shared/ColorListView.h index a141ac4230..2203626ee8 100644 --- a/headers/private/shared/ColorListView.h +++ b/headers/private/shared/ColorListView.h @@ -18,19 +18,13 @@ namespace BPrivate { class BColorListView : public BListView { public: - enum { - B_MESSAGE_SET_CURRENT_COLOR = 'sccl', - B_MESSAGE_SET_COLOR = 'sclr' - }; - BColorListView(const char* name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); virtual ~BColorListView(); - virtual bool InitiateDrag(BPoint where, int32 index, - bool wasSelected); - virtual void MessageReceived(BMessage* message); + virtual bool InitiateDrag(BPoint where, int32 index, bool wasSelected); + virtual void MouseUp(BPoint where); }; diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 100eb1aa36..fc8852ab30 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -1007,8 +1007,6 @@ TermWindow::MessageReceived(BMessage *message) break; case MSG_COLOR_SCHEME_CHANGED: - case BColorListView::B_MESSAGE_SET_CURRENT_COLOR: - case BColorListView::B_MESSAGE_SET_COLOR: case MSG_UPDATE_COLOR: _SetTermColors(); break; diff --git a/src/apps/terminal/ThemeView.cpp b/src/apps/terminal/ThemeView.cpp index 036e3545ec..2246905ea1 100644 --- a/src/apps/terminal/ThemeView.cpp +++ b/src/apps/terminal/ThemeView.cpp @@ -34,7 +34,7 @@ #define B_TRANSLATION_CONTEXT "Terminal ThemeView" -#define COLOR_DROPPED 'cldp' +#define MSG_COLOR_DROPPED 'cldp' #define DECORATOR_CHANGED 'dcch' @@ -94,7 +94,7 @@ ThemeView::ThemeView(const char* name, const BMessenger& messenger) fColorSchemeMenu = new BPopUpMenu(""); fColorSchemeField = new BMenuField(B_TRANSLATE("Color scheme:"), fColorSchemeMenu); - fColorPreview = new BColorPreview("color preview", "", new BMessage(COLOR_DROPPED)); + fColorPreview = new BColorPreview("color preview", "", new BMessage(MSG_COLOR_DROPPED)); fPicker = new BColorControl(B_ORIGIN, B_CELLS_32x8, 8.0, "picker", new BMessage(MSG_UPDATE_COLOR)); @@ -292,8 +292,23 @@ ThemeView::MessageReceived(BMessage* message) ssize_t size; if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK && message->FindData(name, type, (const void**)&color, &size) == B_OK) { - _SetCurrentColor(*color); - modified = true; + BPoint dropLoc = message->DropPoint(); + if (fAttrList->Bounds().Contains(fAttrList->ConvertFromScreen(dropLoc))) { + // dropped on color list view + int32 index = fAttrList->IndexOf(fAttrList->ConvertFromScreen(dropLoc)); + bool selected = index == fAttrList->CurrentSelection(); + if (index < 0 || index >= fAttrList->CountItems() || selected) + _SetCurrentColor(*color); + else + _SetColor(index, *color); + + modified = true; + } else if (fColorPreview->Bounds().Contains(fColorPreview->ConvertFromScreen(dropLoc)) + || fPicker->Bounds().Contains(fPicker->ConvertFromScreen(dropLoc))) { + // dropped on color preview or color control + _SetCurrentColor(*color); + modified = true; + } } } @@ -308,26 +323,6 @@ ThemeView::MessageReceived(BMessage* message) break; } - case BColorListView::B_MESSAGE_SET_CURRENT_COLOR: - case BColorListView::B_MESSAGE_SET_COLOR: - { - // Received from color list view when color changes - char* name; - type_code type; - rgb_color* color; - ssize_t size; - if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK - && message->FindData(name, type, (const void**)&color, &size) == B_OK) { - bool current = message->GetBool("current", false); - if (current) - _SetCurrentColor(*color); - else - _SetColor(name, *color); - modified = true; - } - break; - } - case MSG_UPDATE_COLOR: { // Received from the color fPicker when its color changes @@ -341,11 +336,12 @@ ThemeView::MessageReceived(BMessage* message) case MSG_COLOR_ATTRIBUTE_CHOSEN: { // Received when the user chooses a GUI fAttribute from the list - const int32 currentIndex = fAttrList->CurrentSelection(); - if (currentIndex < 0) + + const int32 index = fAttrList->CurrentSelection(); + if (index < 0 || index >= fAttrList->CountItems()) break; - rgb_color color = PrefHandler::Default()->getRGB(kColorTable[currentIndex]); + rgb_color color = PrefHandler::Default()->getRGB(kColorTable[index]); _SetCurrentColor(color); break; } @@ -382,8 +378,8 @@ ThemeView::SetDefaults() fAttrList->InvalidateItem(index); } - int32 currentIndex = fAttrList->CurrentSelection(); - BColorItem* item = static_cast(fAttrList->ItemAt(currentIndex)); + int32 index = fAttrList->CurrentSelection(); + BColorItem* item = static_cast(fAttrList->ItemAt(index)); if (item != NULL) { rgb_color color = item->Color(); fPicker->SetValue(color); @@ -532,24 +528,19 @@ ThemeView::_MakeColorSchemeMenu() void ThemeView::_SetCurrentColor(rgb_color color) { - int32 currentIndex = fAttrList->CurrentSelection(); - BColorItem* item = static_cast(fAttrList->ItemAt(currentIndex)); - if (item != NULL) { - item->SetColor(color); - fAttrList->InvalidateItem(currentIndex); - - PrefHandler::Default()->setRGB(kColorTable[currentIndex], color); - } - + _SetColor(fAttrList->CurrentSelection(), color); fPicker->SetValue(color); fColorPreview->SetColor(color); } void -ThemeView::_SetColor(const char* name, rgb_color color) +ThemeView::_SetColor(int32 index, rgb_color color) { - PrefHandler::Default()->setRGB(name, color); - - _UpdateStyle(); + BColorItem* item = dynamic_cast(fAttrList->ItemAt(index)); + if (item != NULL) { + item->SetColor(color); + fAttrList->InvalidateItem(index); + PrefHandler::Default()->setRGB(kColorTable[index], color); + } } diff --git a/src/apps/terminal/ThemeView.h b/src/apps/terminal/ThemeView.h index 4f480db7a1..5266478e73 100644 --- a/src/apps/terminal/ThemeView.h +++ b/src/apps/terminal/ThemeView.h @@ -63,7 +63,7 @@ private: void _ChangeColorScheme(color_scheme* scheme); void _SetCurrentColorScheme(); void _SetCurrentColor(rgb_color color); - void _SetColor(const char* name, rgb_color color); + void _SetColor(int32 index, rgb_color color); void _MakeColorSchemeMenu(); void _MakeColorSchemeMenuItem(const color_scheme *item); diff --git a/src/kits/shared/ColorListView.cpp b/src/kits/shared/ColorListView.cpp index 4edc141fc9..47315afcbe 100644 --- a/src/kits/shared/ColorListView.cpp +++ b/src/kits/shared/ColorListView.cpp @@ -116,48 +116,10 @@ BColorListView::InitiateDrag(BPoint where, int32 index, bool wasSelected) void -BColorListView::MessageReceived(BMessage* message) +BColorListView::MouseUp(BPoint where) { - // if we received a dropped message, see if it contains color data - if (!message->WasDropped()) - return BListView::MessageReceived(message); - - BPoint dropPoint = message->DropPoint(); - ConvertFromScreen(&dropPoint); - int32 index = IndexOf(dropPoint); - BColorItem* item = dynamic_cast(ItemAt(index)); - if (item == NULL) - return BListView::MessageReceived(message); - - char* name; - type_code type; - rgb_color* color; - ssize_t size; - if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK - && message->FindData(name, type, (const void**)&color, &size) == B_OK) { - // set message command to set current color or new - bool current = index == CurrentSelection(); - uint32 command = (current ? BColorListView::B_MESSAGE_SET_CURRENT_COLOR - : BColorListView::B_MESSAGE_SET_COLOR); - message->what = command; - - // if setting different color, add which color to set - if (current) - message->AddBool("current", true); - else - message->AddUInt32("which", (uint32)item->ColorWhich()); - - // build messenger and send message - BMessenger messenger = BMessenger(Parent()); - if (messenger.IsValid()) - messenger.SendMessage(message); - - // set current color redraws for us - if (!current) { - item->SetColor(*color); - InvalidateItem(index); - } - } + // TODO drag and drop from an external view should not alter selection + BView::MouseUp(where); } diff --git a/src/preferences/appearance/ColorsView.cpp b/src/preferences/appearance/ColorsView.cpp index e9265c201d..b640c59414 100644 --- a/src/preferences/appearance/ColorsView.cpp +++ b/src/preferences/appearance/ColorsView.cpp @@ -109,59 +109,37 @@ void ColorsView::MessageReceived(BMessage* message) { if (message->WasDropped()) { - // Received from color preview when dropped on char* name; type_code type; rgb_color* color; ssize_t size; if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK && message->FindData(name, type, (const void**)&color, &size) == B_OK) { - _SetCurrentColor(*color); - Window()->PostMessage(kMsgUpdate); - } + BPoint dropLoc = message->DropPoint(); + if (fAttrList->Bounds().Contains(fAttrList->ConvertFromScreen(dropLoc))) { + // dropped on color list view + int32 index = fAttrList->IndexOf(fAttrList->ConvertFromScreen(dropLoc)); + bool selected = index == fAttrList->CurrentSelection(); + if (index < 0 || index >= fAttrList->CountItems() || selected) + _SetCurrentColor(*color); + else + _SetColor(index, *color); - return BView::MessageReceived(message); - } - - switch (message->what) { - // Received from color preview when dropped on - case COLOR_DROPPED: - // Received from the color list view when color changes - case BColorListView::B_MESSAGE_SET_CURRENT_COLOR: - { - char* name; - type_code type; - rgb_color* color; - ssize_t size; - - if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK - && message->FindData(name, type, (const void**)&color, &size) == B_OK) { + Window()->PostMessage(kMsgUpdate); + } else if (fColorPreview->Bounds().Contains(fColorPreview->ConvertFromScreen(dropLoc)) + || fPicker->Bounds().Contains(fPicker->ConvertFromScreen(dropLoc))) { + // dropped on color preview or color control _SetCurrentColor(*color); Window()->PostMessage(kMsgUpdate); } - break; - } - - case BColorListView::B_MESSAGE_SET_COLOR: - { - char* name; - type_code type; - rgb_color* color; - ssize_t size; - color_which which; - - if (message->GetInfo(B_RGB_COLOR_TYPE, 0, &name, &type) == B_OK - && message->FindData(name, type, (const void**)&color, &size) == B_OK - && message->FindUInt32("which", (uint32*)&which) == B_OK) { - _SetColor(which, *color); - Window()->PostMessage(kMsgUpdate); - } - break; } + } + switch (message->what) { case UPDATE_COLOR: { // Received from the color fPicker when its color changes + rgb_color color = fPicker->ValueAsColor(); _SetCurrentColor(color); Window()->PostMessage(kMsgUpdate); @@ -172,11 +150,16 @@ ColorsView::MessageReceived(BMessage* message) { // Received when the user chooses a GUI fAttribute from the list - BColorItem* item - = static_cast(fAttrList->ItemAt(fAttrList->CurrentSelection())); - fWhich = item->ColorWhich(); - rgb_color color = ui_color(fWhich); - _SetCurrentColor(color); + int32 index = fAttrList->CurrentSelection(); + if (index < 0 || index >= fAttrList->CountItems()) + break; + + BColorItem* item = dynamic_cast(fAttrList->ItemAt(index)); + if (item != NULL) { + fWhich = item->ColorWhich(); + rgb_color color = ui_color(fWhich); + _SetCurrentColor(color); + } break; } @@ -306,20 +289,24 @@ ColorsView::_SetUIColors(const BMessage& colors) void ColorsView::_SetCurrentColor(rgb_color color) { - _SetColor(fWhich, color); - - int32 currentIndex = fAttrList->CurrentSelection(); - BColorItem* item = static_cast(fAttrList->ItemAt(currentIndex)); - if (item != NULL) { - item->SetColor(color); - fAttrList->InvalidateItem(currentIndex); - } - + _SetColor(fAttrList->CurrentSelection(), color); fPicker->SetValue(color); fColorPreview->SetColor(color); } +void +ColorsView::_SetColor(int32 index, rgb_color color) +{ + BColorItem* item = dynamic_cast(fAttrList->ItemAt(index)); + if (item != NULL) { + item->SetColor(color); + fAttrList->InvalidateItem(index); + _SetColor(item->ColorWhich(), color); + } +} + + void ColorsView::_SetColor(color_which which, rgb_color color) { diff --git a/src/preferences/appearance/ColorsView.h b/src/preferences/appearance/ColorsView.h index f89f06d18e..a413a566c4 100644 --- a/src/preferences/appearance/ColorsView.h +++ b/src/preferences/appearance/ColorsView.h @@ -58,6 +58,7 @@ private: void _CreateItems(); void _UpdatePreviews(const BMessage& colors); + void _SetColor(int32 index, rgb_color color); void _SetColor(color_which which, rgb_color color); void _SetOneColor(color_which which, rgb_color color); void _SetCurrentColor(rgb_color color);