Qt Editor: Highlight objects hovered in object selection delegate in viewport

qteditor
Sven Eberhardt 2016-06-16 16:15:15 -04:00
parent 2f22a3a8fe
commit f913b4d012
4 changed files with 92 additions and 54 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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