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 <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
John Scipione
2025-06-30 14:56:42 +00:00
parent 0d91cd6464
commit 15c87be3ea
7 changed files with 79 additions and 146 deletions
+2 -8
View File
@@ -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);
};
-2
View File
@@ -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;
+33 -42
View File
@@ -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<BColorItem*>(fAttrList->ItemAt(currentIndex));
int32 index = fAttrList->CurrentSelection();
BColorItem* item = static_cast<BColorItem*>(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<BColorItem*>(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<BColorItem*>(fAttrList->ItemAt(index));
if (item != NULL) {
item->SetColor(color);
fAttrList->InvalidateItem(index);
PrefHandler::Default()->setRGB(kColorTable[index], color);
}
}
+1 -1
View File
@@ -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);
+3 -41
View File
@@ -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<BColorItem*>(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);
}
+39 -52
View File
@@ -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<BColorItem*>(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<BColorItem*>(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<BColorItem*>(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<BColorItem*>(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)
{
+1
View File
@@ -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);