forked from Mirrors/openclonk
Qt Editor: Highlight objects hovered in object selection delegate in viewport
parent
2f22a3a8fe
commit
f913b4d012
|
@ -492,6 +492,13 @@ C4DeepQComboBox::C4DeepQComboBox(QWidget *parent)
|
|||
}
|
||||
}
|
||||
});
|
||||
// On selection, highlight object in editor
|
||||
view->setMouseTracking(true);
|
||||
connect(view, &QTreeView::entered, this, [this](const QModelIndex &index)
|
||||
{
|
||||
::Console.EditCursor.SetHighlightedObject(static_cast<C4Object *>(this->model()->data(index, ObjectHighlightRole).value<void *>()));
|
||||
});
|
||||
// Connect view to combobox
|
||||
setView(view);
|
||||
view->viewport()->installEventFilter(this);
|
||||
}
|
||||
|
@ -508,7 +515,7 @@ void C4DeepQComboBox::showPopup()
|
|||
void C4DeepQComboBox::hidePopup()
|
||||
{
|
||||
QModelIndex current = view()->currentIndex();
|
||||
QVariant selected_data = model()->data(current, Qt::UserRole + 1);
|
||||
QVariant selected_data = model()->data(current, OptionIndexRole);
|
||||
if (item_clicked && (selected_data.type() != QVariant::Int || !descending))
|
||||
{
|
||||
// Clicked somewhere into the list box: Avoid closing to allow navigation in the tree
|
||||
|
@ -530,6 +537,7 @@ void C4DeepQComboBox::hidePopup()
|
|||
// Otherwise, finish selection
|
||||
setRootModelIndex(current.parent());
|
||||
setCurrentIndex(current.row());
|
||||
::Console.EditCursor.SetHighlightedObject(nullptr);
|
||||
QComboBox::hidePopup();
|
||||
}
|
||||
descending = item_clicked = false;
|
||||
|
@ -628,7 +636,9 @@ QStandardItemModel *C4PropertyDelegateEnum::CreateOptionModel() const
|
|||
}
|
||||
}
|
||||
QStandardItem *new_item = new QStandardItem(QString(opt.name->GetCStr()));
|
||||
new_item->setData(QVariant(idx), Qt::UserRole + 1);
|
||||
new_item->setData(QVariant(idx), C4DeepQComboBox::OptionIndexRole);
|
||||
void *item_obj_data = opt.value.getObj();
|
||||
new_item->setData(qVariantFromValue(item_obj_data), C4DeepQComboBox::ObjectHighlightRole);
|
||||
parent->appendRow(new_item);
|
||||
++idx;
|
||||
}
|
||||
|
@ -767,7 +777,7 @@ QModelIndex C4PropertyDelegateEnum::GetModelIndexByID(QStandardItemModel *model,
|
|||
for (int row = 0; row < parent_item->rowCount(); ++row)
|
||||
{
|
||||
QStandardItem *child = parent_item->child(row, 0);
|
||||
QVariant v = child->data(Qt::UserRole + 1);
|
||||
QVariant v = child->data(C4DeepQComboBox::OptionIndexRole);
|
||||
if (v.type() == QVariant::Int && v.toInt() == id) return model->index(row, 0, parent);
|
||||
if (child->rowCount())
|
||||
{
|
||||
|
@ -799,7 +809,7 @@ void C4PropertyDelegateEnum::SetModelData(QObject *aeditor, const C4PropertyPath
|
|||
Editor *editor = static_cast<Editor*>(aeditor);
|
||||
QStandardItemModel *model = static_cast<QStandardItemModel *>(editor->option_box->model());
|
||||
QModelIndex selected_model_index = model->index(editor->option_box->currentIndex(), 0, editor->option_box->rootModelIndex());
|
||||
QVariant vidx = model->data(selected_model_index, Qt::UserRole + 1);
|
||||
QVariant vidx = model->data(selected_model_index, C4DeepQComboBox::OptionIndexRole);
|
||||
if (vidx.type() != QVariant::Int) return;
|
||||
int32_t idx = vidx.toInt();
|
||||
if (idx < 0 || idx >= options.size()) return;
|
||||
|
@ -1330,6 +1340,7 @@ void C4PropertyDelegateFactory::destroyEditor(QWidget *editor, const QModelIndex
|
|||
{
|
||||
current_editor = nullptr;
|
||||
current_editor_delegate = nullptr;
|
||||
::Console.EditCursor.SetHighlightedObject(nullptr);
|
||||
}
|
||||
QStyledItemDelegate::destroyEditor(editor, index);
|
||||
}
|
||||
|
|
|
@ -204,6 +204,12 @@ class C4DeepQComboBox : public QComboBox
|
|||
int last_popup_height;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
OptionIndexRole = Qt::UserRole + 1,
|
||||
ObjectHighlightRole = Qt::UserRole + 2,
|
||||
};
|
||||
|
||||
C4DeepQComboBox(QWidget *parent);
|
||||
|
||||
void showPopup() override;
|
||||
|
|
|
@ -610,6 +610,45 @@ bool C4EditCursor::Duplicate()
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4EditCursor::DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight)
|
||||
{
|
||||
// target pos (parallax)
|
||||
float line_width = std::max<float>(1.0f, 1.0f / cgo.Zoom);
|
||||
float offX, offY, newzoom;
|
||||
cobj->GetDrawPosition(cgo, offX, offY, newzoom);
|
||||
ZoomDataStackItem zdsi(cgo.X, cgo.Y, newzoom);
|
||||
if (select_mark_color)
|
||||
{
|
||||
FLOAT_RECT frame =
|
||||
{
|
||||
offX + cobj->Shape.x,
|
||||
offX + cobj->Shape.x + cobj->Shape.Wdt,
|
||||
offY + cobj->Shape.y,
|
||||
offY + cobj->Shape.y + cobj->Shape.Hgt
|
||||
};
|
||||
DrawSelectMark(cgo, frame, line_width, select_mark_color);
|
||||
}
|
||||
if (highlight)
|
||||
{
|
||||
uint32_t dwOldMod = cobj->ColorMod;
|
||||
uint32_t dwOldBlitMode = cobj->BlitMode;
|
||||
cobj->ColorMod = 0xffffffff;
|
||||
cobj->BlitMode = C4GFXBLIT_CLRSFC_MOD2 | C4GFXBLIT_ADDITIVE;
|
||||
|
||||
if (cobj->pMeshInstance)
|
||||
cobj->pMeshInstance->SetFaceOrdering(StdSubMeshInstance::FO_NearestToFarthest);
|
||||
|
||||
cobj->Draw(cgo, -1);
|
||||
cobj->DrawTopFace(cgo, -1);
|
||||
|
||||
if (cobj->pMeshInstance)
|
||||
cobj->pMeshInstance->SetFaceOrderingForClrModulation(cobj->ColorMod);
|
||||
|
||||
cobj->ColorMod = dwOldMod;
|
||||
cobj->BlitMode = dwOldBlitMode;
|
||||
}
|
||||
}
|
||||
|
||||
void C4EditCursor::Draw(C4TargetFacet &cgo)
|
||||
{
|
||||
ZoomDataStackItem zdsi(cgo.X, cgo.Y, cgo.Zoom);
|
||||
|
@ -623,38 +662,7 @@ void C4EditCursor::Draw(C4TargetFacet &cgo)
|
|||
{
|
||||
C4Object *cobj = obj.getObj();
|
||||
if (!cobj) continue;
|
||||
// target pos (parallax)
|
||||
float offX, offY, newzoom;
|
||||
cobj->GetDrawPosition(cgo, offX, offY, newzoom);
|
||||
ZoomDataStackItem zdsi(cgo.X, cgo.Y, newzoom);
|
||||
FLOAT_RECT frame =
|
||||
{
|
||||
offX+cobj->Shape.x,
|
||||
offX+cobj->Shape.x + cobj->Shape.Wdt,
|
||||
offY+cobj->Shape.y,
|
||||
offY+cobj->Shape.y + cobj->Shape.Hgt
|
||||
};
|
||||
DrawSelectMark(cgo, frame, line_width);
|
||||
// highlight selection if shift is pressed
|
||||
if (fShiftWasDown)
|
||||
{
|
||||
uint32_t dwOldMod = cobj->ColorMod;
|
||||
uint32_t dwOldBlitMode = cobj->BlitMode;
|
||||
cobj->ColorMod = 0xffffffff;
|
||||
cobj->BlitMode = C4GFXBLIT_CLRSFC_MOD2 | C4GFXBLIT_ADDITIVE;
|
||||
|
||||
if(cobj->pMeshInstance)
|
||||
cobj->pMeshInstance->SetFaceOrdering(StdSubMeshInstance::FO_NearestToFarthest);
|
||||
|
||||
cobj->Draw(cgo,-1);
|
||||
cobj->DrawTopFace(cgo, -1);
|
||||
|
||||
if(cobj->pMeshInstance)
|
||||
cobj->pMeshInstance->SetFaceOrderingForClrModulation(cobj->ColorMod);
|
||||
|
||||
cobj->ColorMod = dwOldMod;
|
||||
cobj->BlitMode = dwOldBlitMode;
|
||||
}
|
||||
DrawObject(cgo, cobj, 0xffffffff, fShiftWasDown); // highlight selection if shift is pressed
|
||||
}
|
||||
// Draw drag frame
|
||||
if (DragFrame)
|
||||
|
@ -692,10 +700,13 @@ void C4EditCursor::Draw(C4TargetFacet &cgo)
|
|||
}
|
||||
creator_overlay->Draw(cgo_creator, NULL, NO_OWNER);
|
||||
}
|
||||
// Draw object highlight
|
||||
C4Object *highlight = highlighted_object.getObj();
|
||||
if (highlight) DrawObject(cgo, highlight, 0xffff8000, true); // highlight selection if shift is pressed
|
||||
}
|
||||
|
||||
|
||||
void C4EditCursor::DrawSelectMark(C4Facet &cgo, FLOAT_RECT frame, float width)
|
||||
void C4EditCursor::DrawSelectMark(C4Facet &cgo, FLOAT_RECT frame, float width, uint32_t color)
|
||||
{
|
||||
if ((cgo.Wdt<1) || (cgo.Hgt<1)) return;
|
||||
|
||||
|
@ -703,26 +714,28 @@ void C4EditCursor::DrawSelectMark(C4Facet &cgo, FLOAT_RECT frame, float width)
|
|||
|
||||
const float EDGE_WIDTH = 2.f;
|
||||
|
||||
unsigned char c[4] = { (color >> 16) & 0xff, (color >> 8) & 0xff , (color >> 0) & 0xff , (color >> 24) & 0xff };
|
||||
|
||||
const C4BltVertex vertices[] = {
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left+EDGE_WIDTH, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.top+EDGE_WIDTH, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left + EDGE_WIDTH, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.top+EDGE_WIDTH, 0.f },
|
||||
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left+EDGE_WIDTH, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.left, frame.bottom-1-EDGE_WIDTH, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left+EDGE_WIDTH, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.left, frame.bottom-1-EDGE_WIDTH, 0.f },
|
||||
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1-EDGE_WIDTH, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.top+EDGE_WIDTH, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1-EDGE_WIDTH, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.top, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.top+EDGE_WIDTH, 0.f },
|
||||
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1-EDGE_WIDTH, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { 0xFF, 0xFF, 0xFF, 0xFF }, frame.right-1, frame.bottom-1-EDGE_WIDTH, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1-EDGE_WIDTH, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.bottom-1, 0.f },
|
||||
{ 0.f, 0.f, { c[0], c[1], c[2], c[3] }, frame.right-1, frame.bottom-1-EDGE_WIDTH, 0.f },
|
||||
};
|
||||
|
||||
const unsigned int n_vertices = sizeof(vertices) / sizeof(vertices[0]);
|
||||
|
@ -1303,3 +1316,8 @@ bool C4EditCursor::GetCurrentSelectionPosition(int32_t *x, int32_t *y)
|
|||
*y = obj->GetY();
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4EditCursor::SetHighlightedObject(C4Object *new_highlight)
|
||||
{
|
||||
highlighted_object = C4VObj(new_highlight);
|
||||
}
|
|
@ -59,6 +59,7 @@ protected:
|
|||
float X,Y,X2,Y2;
|
||||
bool Hold,DragFrame,DragLine,DragShape;
|
||||
C4Object *Target,*DropTarget;
|
||||
C4Value highlighted_object;
|
||||
class C4Def *creator_def;
|
||||
std::unique_ptr<C4GraphicsOverlay> creator_overlay;
|
||||
struct ObjselItemDt {
|
||||
|
@ -130,7 +131,8 @@ protected:
|
|||
void ApplyToolRect();
|
||||
void ApplyToolLine();
|
||||
void ApplyToolBrush();
|
||||
void DrawSelectMark(C4Facet &cgo, FLOAT_RECT r, float width);
|
||||
void DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight);
|
||||
void DrawSelectMark(C4Facet &cgo, FLOAT_RECT r, float width, uint32_t color = 0xffffffff);
|
||||
void FrameSelection();
|
||||
void MoveSelection(C4Real iXOff, C4Real iYOff);
|
||||
void EMMoveObject(enum C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, const C4EditCursorSelection *pObjs = NULL, const char *szScript = NULL);
|
||||
|
@ -157,6 +159,7 @@ public:
|
|||
void ValidateSelection() { selection_invalid = false; }
|
||||
bool IsSelectionInvalidated() const { return selection_invalid; }
|
||||
bool GetCurrentSelectionPosition(int32_t *x, int32_t *y); // return center of first selected object
|
||||
void SetHighlightedObject(C4Object *new_highlight);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue