Qt Editor: Add point property delegate

qteditor
Sven Eberhardt 2016-07-30 01:05:12 -04:00
parent bdea3876d6
commit affa2aebb0
4 changed files with 100 additions and 9 deletions

View File

@ -1590,7 +1590,21 @@ bool C4PropertyDelegateShape::Paint(QPainter *painter, const QStyleOptionViewIte
QPen rect_pen(QBrush(frame_color), width, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
painter->setPen(rect_pen);
QRect inner_rect = option.rect.adjusted(width / 2, width / 2, -width / 2, -width / 2);
if (shape_type && shape_type->GetData() == "circle")
if (inner_rect.width() > inner_rect.height())
{
// Draw shape in right corner
inner_rect.adjust(inner_rect.width() - inner_rect.height(), 0, 0, 0);
}
if (shape_type && shape_type->GetData() == "point")
{
QPoint ctr = inner_rect.center();
int r = inner_rect.height() * 7 / 20;
painter->drawLine(ctr + QPoint(-r, -r), ctr + QPoint(+r, +r));
painter->drawLine(ctr + QPoint(+r, -r), ctr + QPoint(-r, +r));
painter->drawEllipse(inner_rect);
}
else if (shape_type && shape_type->GetData() == "circle")
{
painter->drawEllipse(inner_rect);
if (can_move_center) painter->drawPoint(inner_rect.center());
@ -1626,7 +1640,7 @@ C4PropertyDelegate *C4PropertyDelegateFactory::CreateDelegateByPropList(C4PropLi
if (str->GetData() == "bool") return new C4PropertyDelegateBool(this, props);
if (str->GetData() == "has_effect") return new C4PropertyDelegateHasEffect(this, props);
if (str->GetData() == "c4valueenum") return new C4PropertyDelegateC4ValueEnum(this, props);
if (str->GetData() == "rect" || str->GetData() == "circle") return new C4PropertyDelegateShape(this, props);
if (str->GetData() == "rect" || str->GetData() == "circle" || str->GetData() == "point") return new C4PropertyDelegateShape(this, props);
if (str->GetData() == "any") return new C4PropertyDelegateC4ValueInput(this, props);
// unknown type
LogF("Invalid delegate type: %s.", str->GetCStr());
@ -1793,7 +1807,7 @@ C4ConsoleQtPropListModel::~C4ConsoleQtPropListModel()
{
}
bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *target_proplist, C4Object *base_effect_object, C4String *default_selection, int32_t *default_selection_index)
bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *target_proplist, C4Object *base_object, C4String *default_selection, int32_t *default_selection_index)
{
auto new_properties = add_proplist->GetSortedLocalProperties(false);
if (!new_properties.size()) return false;
@ -1810,14 +1824,15 @@ bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_
layout_valid = false;
properties.props.resize(new_properties.size());
}
C4Effect *fx = target_proplist->GetEffect();
for (int32_t i = 0; i < new_properties.size(); ++i)
{
Property *prop = &properties.props[i];
// Property access path
prop->parent_value.SetPropList(target_proplist);
if (base_effect_object)
if (fx)
// Access to effect
prop->property_path = C4PropertyPath(target_proplist->GetEffect(), base_effect_object);
prop->property_path = C4PropertyPath(fx, base_object);
else
prop->property_path = target_path;
// ID for default selection memory
@ -1854,7 +1869,7 @@ bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_
prop->shape_property_path = new_shape_property_path;
if (new_shape_delegate)
{
C4ConsoleQtShape *shape = ::Console.EditCursor.GetShapes()->CreateShape(base_effect_object ? base_effect_object : target_proplist->GetObject(), new_shape_delegate->GetCreationProps().getPropList(), v, new_shape_delegate);
C4ConsoleQtShape *shape = ::Console.EditCursor.GetShapes()->CreateShape(base_object ? base_object : target_proplist->GetObject(), new_shape_delegate->GetCreationProps().getPropList(), v, new_shape_delegate);
C4PropertyDelegateFactory *factory = this->delegate_factory;
connect(shape, &C4ConsoleQtShape::ShapeDragged, new_shape_delegate, [factory, new_shape_delegate, shape, prop]() {
new_shape_delegate->SetModelData(nullptr, prop->shape_property_path, shape);
@ -1985,6 +2000,7 @@ int32_t C4ConsoleQtPropListModel::UpdateValuePropList(C4PropList *target_proplis
{
assert(target_proplist);
C4PropList *base_proplist = this->base_proplist.getPropList();
C4Object *base_obj = this->base_proplist.getObj();
C4PropList *info_proplist = this->info_proplist.getPropList();
int32_t num_groups = 0;
// Published properties
@ -2016,7 +2032,7 @@ int32_t C4ConsoleQtPropListModel::UpdateValuePropList(C4PropList *target_proplis
name = QString(proplist_static->GetDataString().getData());
else
name = info_proplist->GetName();
if (AddPropertyGroup(info_editorprops, num_groups, name, target_proplist, nullptr, default_selection, default_selection_index))
if (AddPropertyGroup(info_editorprops, num_groups, name, target_proplist, base_obj, default_selection, default_selection_index))
++num_groups;
// Assign group for default selection
if (*default_selection_index >= 0)
@ -2033,7 +2049,7 @@ int32_t C4ConsoleQtPropListModel::UpdateValuePropList(C4PropList *target_proplis
if (editor_base)
{
C4PropList *info_editorprops = editor_base->GetPropertyPropList(P_EditorProps);
if (AddPropertyGroup(info_editorprops, num_groups, LoadResStr("IDS_CNS_OBJECT"), target_proplist, nullptr, nullptr, nullptr))
if (AddPropertyGroup(info_editorprops, num_groups, LoadResStr("IDS_CNS_OBJECT"), target_proplist, base_obj, nullptr, nullptr))
++num_groups;
}
}

View File

@ -587,7 +587,7 @@ public:
void SetSelectionModel(QItemSelectionModel *m) { selection_model = m; }
bool AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *ignore_overridden, C4Object *base_effect_object, C4String *default_selection, int32_t *default_selection_index);
bool AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *ignore_overridden, C4Object *base_object, C4String *default_selection, int32_t *default_selection_index);
void SetBasePropList(C4PropList *new_proplist); // Clear stack and select new proplist
void DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path); // Add proplist to stack
void AscendPath(); // go back one element in target path stack

View File

@ -285,6 +285,65 @@ C4Value C4ConsoleQtCircle::GetValue() const
}
/* Point shape */
C4ConsoleQtPoint::C4ConsoleQtPoint(class C4Object *for_obj, C4PropList *props, const C4Value &val, const class C4PropertyDelegateShape *parent_delegate)
: C4ConsoleQtShape(for_obj, props, parent_delegate), cx(0), cy(0)
{
// Expect value as [x,y]
C4ValueArray *aval = val.getArray();
if (aval && aval->GetSize() == 2)
{
cx = aval->GetItem(0).getInt();
cy = aval->GetItem(1).getInt();
}
}
bool C4ConsoleQtPoint::IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border)
{
// Get relative circle center pos
x -= AbsX(cx);
y -= AbsY(cy);
int32_t r = x*x + y*y;
// Hits point?
if (r <= hit_range*hit_range*6)
{
*drag_cursor = Qt::CursorShape::SizeAllCursor;
*drag_border = 0;
return true;
}
return false;
}
void C4ConsoleQtPoint::Draw(class C4TargetFacet &cgo, float line_width)
{
// Circle with cross inside
uint32_t clr = GetBorderColor(0, false);
float d = line_width * 3;
float dc = sqrtf(2) * d;
int32_t x = AbsX(cx) + cgo.X - cgo.TargetX;
int32_t y = AbsY(cy) + cgo.Y - cgo.TargetY;
pDraw->DrawLineDw(cgo.Surface, x - d, y - d, x + d, y + d, clr, line_width);
pDraw->DrawLineDw(cgo.Surface, x - d, y + d, x + d, y - d, clr, line_width);
pDraw->DrawCircleDw(cgo.Surface, x, y, dc, clr, line_width);
}
void C4ConsoleQtPoint::Drag(int32_t x, int32_t y, int32_t dx, int32_t dy)
{
cx += dx;
cy += dy;
}
C4Value C4ConsoleQtPoint::GetValue() const
{
// Return [cx, cy]
C4ValueArray *pos_array = new C4ValueArray(2);
pos_array->SetItem(0, C4VInt(cx));
pos_array->SetItem(1, C4VInt(cy));
return C4VArray(pos_array);
}
/* Shape list */
C4ConsoleQtShape *C4ConsoleQtShapes::CreateShape(class C4Object *for_obj, C4PropList *props, const C4Value &val, const class C4PropertyDelegateShape *parent_delegate)
@ -294,6 +353,7 @@ C4ConsoleQtShape *C4ConsoleQtShapes::CreateShape(class C4Object *for_obj, C4Prop
C4ConsoleQtShape *shape = nullptr;
if (type->GetData() == "rect") shape = new C4ConsoleQtRect(for_obj, props, val, parent_delegate);
else if (type->GetData() == "circle") shape = new C4ConsoleQtCircle(for_obj, props, val, parent_delegate);
else if (type->GetData() == "point") shape = new C4ConsoleQtPoint(for_obj, props, val, parent_delegate);
return shape;
}

View File

@ -97,6 +97,21 @@ public:
C4Value GetValue() const override;
};
// Single position shape
class C4ConsoleQtPoint : public C4ConsoleQtShape
{
private:
int32_t cx, cy;
public:
C4ConsoleQtPoint(class C4Object *for_obj, C4PropList *props, const C4Value &val, const class C4PropertyDelegateShape *parent_delegate);
bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border) override;
void Draw(class C4TargetFacet &cgo, float line_width) override;
void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy) override;
C4Value GetValue() const override;
};
/* List of all current editable Qt shapes */
class C4ConsoleQtShapes
{