mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Color pickers compared global coordinates with screen dimensions, placing Minifig Wizard and Blender preferences palettes far from their controls on secondary monitors. The numeric ladder also used incorrect half-size bounds. Share monitor selection and available-area clamping through lcGetPopupPosition(), using the anchor or cursor to select the monitor. Size color palettes before placement and reuse the helper when resizing part-selection menus. Preserve monitor offsets, reserve desktop work areas, and align oversized popups to the screen's top or left edge. Validation: macOS Qt 6 build and 49 offscreen placement checks across four simulated monitors, including negative coordinates, oversized popups, and primary-screen fallback. Windows hardware testing remains outstanding. Fixes #1041
198 lines
4.3 KiB
C++
198 lines
4.3 KiB
C++
#include "lc_global.h"
|
|
#include "lc_colorpicker.h"
|
|
#include "lc_colorlist.h"
|
|
#include "lc_colors.h"
|
|
#include "lc_qutils.h"
|
|
|
|
lcColorPickerPopup::lcColorPickerPopup(QWidget* Parent, int ColorIndex, bool AllowNoColor)
|
|
: QFrame(Parent, Qt::Popup)
|
|
{
|
|
setFrameStyle(QFrame::StyledPanel);
|
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setMouseTracking(true);
|
|
|
|
QGridLayout *layout = new QGridLayout(this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
setLayout(layout);
|
|
|
|
mColorList = new lcColorList(this, AllowNoColor);
|
|
connect(mColorList, &lcColorList::ColorChanged, this, &lcColorPickerPopup::ColorChanged);
|
|
connect(mColorList, &lcColorList::ColorSelected, this, &lcColorPickerPopup::ColorSelected);
|
|
layout->addWidget(mColorList);
|
|
|
|
mColorList->blockSignals(true);
|
|
mColorList->SetCurrentColor(ColorIndex);
|
|
mColorList->blockSignals(false);
|
|
|
|
mEventLoop = nullptr;
|
|
}
|
|
|
|
lcColorPickerPopup::~lcColorPickerPopup()
|
|
{
|
|
if (mEventLoop)
|
|
mEventLoop->exit();
|
|
}
|
|
|
|
void lcColorPickerPopup::exec()
|
|
{
|
|
show();
|
|
|
|
QEventLoop EventLoop;
|
|
mEventLoop = &EventLoop;
|
|
(void) EventLoop.exec();
|
|
mEventLoop = nullptr;
|
|
}
|
|
|
|
void lcColorPickerPopup::SetPosition(const QWidget* Anchor)
|
|
{
|
|
ensurePolished();
|
|
adjustSize();
|
|
|
|
const QPoint Position = Anchor->mapToGlobal(Anchor->rect().bottomLeft());
|
|
const QPoint ScreenPosition = Anchor->mapToGlobal(Anchor->rect().center());
|
|
move(lcGetPopupPosition(Position, size(), ScreenPosition));
|
|
}
|
|
|
|
void lcColorPickerPopup::mouseReleaseEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
if (!rect().contains(MouseEvent->pos()))
|
|
hide();
|
|
}
|
|
|
|
void lcColorPickerPopup::hideEvent(QHideEvent* HideEvent)
|
|
{
|
|
if (mEventLoop)
|
|
mEventLoop->exit();
|
|
|
|
emit Hid();
|
|
QFrame::hideEvent(HideEvent);
|
|
}
|
|
|
|
void lcColorPickerPopup::ColorChanged(int ColorIndex)
|
|
{
|
|
emit Changed(ColorIndex);
|
|
}
|
|
|
|
void lcColorPickerPopup::ColorSelected(int ColorIndex)
|
|
{
|
|
emit Selected(ColorIndex);
|
|
hide();
|
|
}
|
|
|
|
void lcColorPickerPopup::showEvent(QShowEvent* ShowEvent)
|
|
{
|
|
Q_UNUSED(ShowEvent);
|
|
|
|
mColorList->setFocus();
|
|
}
|
|
|
|
lcColorPicker::lcColorPicker(QWidget* Parent, bool AllowNoColor)
|
|
: QPushButton(Parent), mAllowNoColor(AllowNoColor)
|
|
{
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
setAutoDefault(false);
|
|
setCheckable(true);
|
|
|
|
UpdateIcon();
|
|
|
|
connect(this, &QPushButton::toggled, this, &lcColorPicker::ButtonPressed);
|
|
}
|
|
|
|
lcColorPicker::~lcColorPicker()
|
|
{
|
|
}
|
|
|
|
void lcColorPicker::SetCurrentColor(int ColorIndex)
|
|
{
|
|
Selected(ColorIndex);
|
|
}
|
|
|
|
void lcColorPicker::SetCurrentColorCode(int ColorCode)
|
|
{
|
|
SetCurrentColor(lcGetColorIndex(ColorCode));
|
|
}
|
|
|
|
int lcColorPicker::GetCurrentColor() const
|
|
{
|
|
return mCurrentColorIndex;
|
|
}
|
|
|
|
int lcColorPicker::GetCurrentColorCode() const
|
|
{
|
|
return gColorList[mCurrentColorIndex].Code;
|
|
}
|
|
|
|
void lcColorPicker::ButtonPressed(bool Toggled)
|
|
{
|
|
if (!Toggled)
|
|
return;
|
|
|
|
lcColorPickerPopup* Popup = new lcColorPickerPopup(this, mCurrentColorIndex, mAllowNoColor);
|
|
connect(Popup, &lcColorPickerPopup::Changed, this, &lcColorPicker::Changed);
|
|
connect(Popup, &lcColorPickerPopup::Selected, this, &lcColorPicker::Selected);
|
|
connect(Popup, &lcColorPickerPopup::Hid, this, &lcColorPicker::PopupClosed);
|
|
Popup->setMinimumSize(300, 200);
|
|
Popup->SetPosition(this);
|
|
|
|
clearFocus();
|
|
update();
|
|
|
|
Popup->setFocus();
|
|
Popup->show();
|
|
}
|
|
|
|
void lcColorPicker::UpdateIcon()
|
|
{
|
|
const int IconSize = 14;//style()->pixelMetric(QStyle::PM_SmallIconSize);
|
|
QPixmap Pixmap(IconSize, IconSize);
|
|
|
|
QPainter Painter(&Pixmap);
|
|
|
|
Painter.setPen(Qt::darkGray);
|
|
|
|
const lcColor* Color = &gColorList[mCurrentColorIndex];
|
|
|
|
if (Color->Code != LC_COLOR_NOCOLOR)
|
|
{
|
|
Painter.setBrush(QColor::fromRgbF(Color->Value[0], Color->Value[1], Color->Value[2]));
|
|
Painter.drawRect(0, 0, Pixmap.width() - 1, Pixmap.height() - 1);
|
|
}
|
|
else
|
|
lcDrawNoColorRect(Painter, QRect(0, 0, Pixmap.width() - 1, Pixmap.height() - 1));
|
|
|
|
Painter.end();
|
|
|
|
setIcon(QIcon(Pixmap));
|
|
}
|
|
|
|
void lcColorPicker::PopupClosed()
|
|
{
|
|
if (mInitialColorIndex != mCurrentColorIndex)
|
|
Changed(mInitialColorIndex);
|
|
|
|
setChecked(false);
|
|
setFocus();
|
|
}
|
|
|
|
void lcColorPicker::Changed(int ColorIndex)
|
|
{
|
|
if (ColorIndex == mCurrentColorIndex)
|
|
return;
|
|
|
|
mCurrentColorIndex = ColorIndex;
|
|
UpdateIcon();
|
|
|
|
update();
|
|
|
|
emit ColorChanged(mCurrentColorIndex);
|
|
}
|
|
|
|
void lcColorPicker::Selected(int ColorIndex)
|
|
{
|
|
mInitialColorIndex = ColorIndex;
|
|
Changed(ColorIndex);
|
|
}
|