forked from Mirrors/openclonk
Editor: Add graph, polyline and polygon shape delegates
parent
75289dabb5
commit
54e8c14666
|
@ -2058,11 +2058,11 @@ bool C4PropertyDelegateRect::IsPasteValid(const C4Value &val) const
|
|||
// Proplist-stored rect must have defined properties
|
||||
C4PropertyName def_property_names[2][4] = { { P_x, P_y, P_wdt, P_hgt },{ P_X, P_Y, P_Wdt, P_Hgt } };
|
||||
C4PropertyName *property_names = nullptr;
|
||||
if (storage->GetData() == "proplist")
|
||||
if (storage == &::Strings.P[P_proplist])
|
||||
{
|
||||
property_names = def_property_names[0];
|
||||
}
|
||||
else if (storage->GetData() == "Proplist")
|
||||
else if (storage == &::Strings.P[P_Proplist])
|
||||
{
|
||||
property_names = def_property_names[1];
|
||||
}
|
||||
|
@ -2146,6 +2146,169 @@ bool C4PropertyDelegatePoint::IsPasteValid(const C4Value &val) const
|
|||
}
|
||||
|
||||
|
||||
/* Areas shown in viewport: Graph */
|
||||
|
||||
C4PropertyDelegateGraph::C4PropertyDelegateGraph(const class C4PropertyDelegateFactory *factory, C4PropList *props)
|
||||
: C4PropertyDelegateShape(factory, props)
|
||||
{
|
||||
if (props)
|
||||
{
|
||||
storage = props->GetPropertyStr(P_Storage);
|
||||
}
|
||||
}
|
||||
|
||||
void C4PropertyDelegateGraph::DoPaint(QPainter *painter, const QRect &inner_rect) const
|
||||
{
|
||||
// Draw symbol as a bunch of connected lines
|
||||
QPoint ctr = inner_rect.center();
|
||||
int r = inner_rect.height() * 7 / 20;
|
||||
painter->drawLine(ctr, ctr + QPoint(-r / 2, -r));
|
||||
painter->drawLine(ctr, ctr + QPoint(+r / 2, -r));
|
||||
painter->drawLine(ctr, ctr + QPoint(0, +r));
|
||||
}
|
||||
|
||||
bool C4PropertyDelegateGraph::IsVertexPasteValid(const C4Value &val) const
|
||||
{
|
||||
// Check that it's an array of at least one point
|
||||
const C4ValueArray *arr = val.getArray();
|
||||
if (!arr || !arr->GetSize()) return false;
|
||||
// Check validity of each point
|
||||
bool store_as_proplist = (storage == &::Strings.P[P_Proplist]);
|
||||
const int32_t n_props = 2;
|
||||
C4PropertyName property_names[n_props] = { P_X, P_Y };
|
||||
for (int32_t i_pt = 0; i_pt < arr->GetSize(); ++i_pt)
|
||||
{
|
||||
const C4Value &pt = arr->GetItem(i_pt);
|
||||
if (store_as_proplist)
|
||||
{
|
||||
const C4PropList *ptp = pt.getPropList();
|
||||
if (!ptp) return false;
|
||||
for (int32_t i_prop = 0; i_prop < n_props; ++i_prop)
|
||||
{
|
||||
C4Value ptprop;
|
||||
if (!ptp->GetProperty(property_names[i_prop], &ptprop)) return false;
|
||||
if (ptprop.GetType() != C4V_Int) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const C4ValueArray *pta = pt.getArray();
|
||||
if (!pta) return false;
|
||||
if (pta->GetSize() < n_props) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4PropertyDelegateGraph::IsEdgePasteValid(const C4Value &val) const
|
||||
{
|
||||
// Check that it's an array
|
||||
// Empty is OK; it could be a graph with one vertex and no edges
|
||||
const C4ValueArray *arr = val.getArray();
|
||||
if (!arr || !arr->GetSize()) return false;
|
||||
// Check validity of each edge
|
||||
bool store_as_proplist = (storage == &::Strings.P[P_Proplist]);
|
||||
for (int32_t i_pt = 0; i_pt < arr->GetSize(); ++i_pt)
|
||||
{
|
||||
const C4Value pt = arr->GetItem(i_pt);
|
||||
const C4ValueArray *pta;
|
||||
if (store_as_proplist)
|
||||
{
|
||||
const C4PropList *ptp = pt.getPropList();
|
||||
if (!ptp) return false;
|
||||
pta = ptp->GetPropertyArray(P_Vertices);
|
||||
}
|
||||
else
|
||||
{
|
||||
pta = pt.getArray();
|
||||
}
|
||||
if (!pta) return false;
|
||||
// Needs two vertices (may have more values which are ignored)
|
||||
if (pta->GetSize() < 2) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4PropertyDelegateGraph::IsPasteValid(const C4Value &val) const
|
||||
{
|
||||
// Check storage as prop list
|
||||
const int32_t n_props = 2;
|
||||
C4Value prop_vals[n_props]; // vertices & edges
|
||||
C4PropertyName property_names[n_props] = { P_Vertices, P_Edges };
|
||||
bool store_as_proplist = (storage == &::Strings.P[P_Proplist]);
|
||||
if (store_as_proplist)
|
||||
{
|
||||
C4PropList *val_proplist = val.getPropList();
|
||||
if (!val_proplist) return false;
|
||||
for (int32_t i = 0; i < n_props; ++i)
|
||||
{
|
||||
val_proplist->GetProperty(property_names[i], &prop_vals[i]);
|
||||
}
|
||||
// extra properties are OK
|
||||
}
|
||||
else
|
||||
{
|
||||
C4ValueArray *val_array = val.getArray();
|
||||
if (!val_array || val_array->GetSize() != n_props) return false;
|
||||
for (int32_t i = 0; i < n_props; ++i)
|
||||
{
|
||||
prop_vals[i] = val_array->GetItem(i);
|
||||
}
|
||||
}
|
||||
// Check validity of vertices and edges
|
||||
return IsVertexPasteValid(prop_vals[0]) && IsEdgePasteValid(prop_vals[1]);
|
||||
}
|
||||
|
||||
|
||||
/* Areas shown in viewport: Polyline */
|
||||
|
||||
C4PropertyDelegatePolyline::C4PropertyDelegatePolyline(const class C4PropertyDelegateFactory *factory, C4PropList *props)
|
||||
: C4PropertyDelegateGraph(factory, props)
|
||||
{
|
||||
}
|
||||
|
||||
void C4PropertyDelegatePolyline::DoPaint(QPainter *painter, const QRect &inner_rect) const
|
||||
{
|
||||
// Draw symbol as a sequence of connected lines
|
||||
QPoint ctr = inner_rect.center();
|
||||
int r = inner_rect.height() * 7 / 20;
|
||||
painter->drawLine(ctr + QPoint(-r, +r), ctr + QPoint(-r/3, -r));
|
||||
painter->drawLine(ctr + QPoint(-r / 3, -r), ctr + QPoint(+r / 3, +r));
|
||||
painter->drawLine(ctr + QPoint(+r / 3, +r), ctr + QPoint(+r, -r));
|
||||
}
|
||||
|
||||
bool C4PropertyDelegatePolyline::IsPasteValid(const C4Value &val) const
|
||||
{
|
||||
// Expect just a vertex array
|
||||
return IsVertexPasteValid(val);
|
||||
}
|
||||
|
||||
|
||||
/* Areas shown in viewport: Closed polyon */
|
||||
|
||||
C4PropertyDelegatePolygon::C4PropertyDelegatePolygon(const class C4PropertyDelegateFactory *factory, C4PropList *props)
|
||||
: C4PropertyDelegateGraph(factory, props)
|
||||
{
|
||||
}
|
||||
|
||||
void C4PropertyDelegatePolygon::DoPaint(QPainter *painter, const QRect &inner_rect) const
|
||||
{
|
||||
// Draw symbol as a parallelogram
|
||||
QPoint ctr = inner_rect.center();
|
||||
int r = inner_rect.height() * 7 / 20;
|
||||
painter->drawLine(ctr + QPoint(-r * 3 / 2, +r), ctr + QPoint(-r, -r));
|
||||
painter->drawLine(ctr + QPoint(-r, -r), ctr + QPoint(+r * 3 / 2, -r));
|
||||
painter->drawLine(ctr + QPoint(+r * 3 / 2, -r), ctr + QPoint(+r, +r));
|
||||
painter->drawLine(ctr + QPoint(+r, +r), ctr + QPoint(-r * 3 / 2, +r));
|
||||
}
|
||||
|
||||
bool C4PropertyDelegatePolygon::IsPasteValid(const C4Value &val) const
|
||||
{
|
||||
// Expect just a vertex array
|
||||
return IsVertexPasteValid(val);
|
||||
}
|
||||
|
||||
|
||||
/* Delegate factory: Create delegates based on the C4Value type */
|
||||
|
||||
C4PropertyDelegateFactory::C4PropertyDelegateFactory() : current_editor(nullptr), property_model(nullptr), effect_delegate(this, nullptr)
|
||||
|
@ -2176,6 +2339,9 @@ C4PropertyDelegate *C4PropertyDelegateFactory::CreateDelegateByPropList(C4PropLi
|
|||
if (str->GetData() == "rect") return new C4PropertyDelegateRect(this, props);
|
||||
if (str->GetData() == "circle") return new C4PropertyDelegateCircle(this, props);
|
||||
if (str->GetData() == "point") return new C4PropertyDelegatePoint(this, props);
|
||||
if (str->GetData() == "graph") return new C4PropertyDelegateGraph(this, props);
|
||||
if (str->GetData() == "polyline") return new C4PropertyDelegatePolyline(this, props);
|
||||
if (str->GetData() == "polygon") return new C4PropertyDelegatePolygon(this, props);
|
||||
if (str->GetData() == "any") return new C4PropertyDelegateC4ValueInput(this, props);
|
||||
// unknown type
|
||||
LogF("Invalid delegate type: %s.", str->GetCStr());
|
||||
|
|
|
@ -555,6 +555,35 @@ public:
|
|||
bool IsPasteValid(const C4Value &val) const override;
|
||||
};
|
||||
|
||||
class C4PropertyDelegateGraph : public C4PropertyDelegateShape
|
||||
{
|
||||
C4RefCntPointer<C4String> storage;
|
||||
|
||||
void DoPaint(QPainter *painter, const QRect &inner_rect) const override;
|
||||
protected:
|
||||
bool IsVertexPasteValid(const C4Value &val) const;
|
||||
bool IsEdgePasteValid(const C4Value &val) const;
|
||||
public:
|
||||
C4PropertyDelegateGraph(const class C4PropertyDelegateFactory *factory, C4PropList *props);
|
||||
bool IsPasteValid(const C4Value &val) const override;
|
||||
};
|
||||
|
||||
class C4PropertyDelegatePolyline : public C4PropertyDelegateGraph
|
||||
{
|
||||
void DoPaint(QPainter *painter, const QRect &inner_rect) const override;
|
||||
public:
|
||||
C4PropertyDelegatePolyline(const class C4PropertyDelegateFactory *factory, C4PropList *props);
|
||||
bool IsPasteValid(const C4Value &val) const override;
|
||||
};
|
||||
|
||||
class C4PropertyDelegatePolygon : public C4PropertyDelegateGraph
|
||||
{
|
||||
void DoPaint(QPainter *painter, const QRect &inner_rect) const override;
|
||||
public:
|
||||
C4PropertyDelegatePolygon(const class C4PropertyDelegateFactory *factory, C4PropList *props);
|
||||
bool IsPasteValid(const C4Value &val) const override;
|
||||
};
|
||||
|
||||
class C4PropertyDelegateFactory : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,25 +37,25 @@ protected:
|
|||
|
||||
protected:
|
||||
// Return shape color, or dragged border color if index is the border currently being dragged
|
||||
uint32_t GetBorderColor(int32_t border_index, bool dragging_border_is_bitmask) const;
|
||||
uint32_t GetBorderColor(int32_t border_index, bool dragging_border_is_bitmask, uint32_t default_color = 0u) const;
|
||||
public:
|
||||
C4ConsoleQtShape(class C4Object *for_obj, C4PropList *props, const class C4PropertyDelegateShape *parent_delegate);
|
||||
|
||||
virtual bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border) = 0;
|
||||
virtual bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border, bool shift_down, bool ctrl_down) = 0;
|
||||
virtual void Draw(class C4TargetFacet &cgo, float line_width) = 0;
|
||||
|
||||
// Coordinate transform: Add object
|
||||
int32_t AbsX(int32_t rel_x) const;
|
||||
int32_t AbsY(int32_t rel_x) const;
|
||||
int32_t AbsX(int32_t rel_x=0) const;
|
||||
int32_t AbsY(int32_t rel_y=0) const;
|
||||
|
||||
// Start/stop dragging
|
||||
void StartDragging(int32_t border) { dragging_border = border; }
|
||||
void StopDragging() { dragging_border = -1; }
|
||||
virtual void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy) = 0;
|
||||
virtual bool StartDragging(int32_t border, int32_t x, int32_t y, bool shift_down, bool ctrl_down) { dragging_border = border; return true; }
|
||||
virtual void StopDragging();
|
||||
virtual void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy, int32_t hit_range, Qt::CursorShape *drag_cursor) = 0;
|
||||
bool IsDragging() const { return dragging_border != -1; }
|
||||
|
||||
// Return current shape as C4Value to be stored back to property
|
||||
virtual C4Value GetValue() const = 0;
|
||||
virtual void SetValue(const C4Value &val) = 0;
|
||||
virtual C4Value GetValue() const = 0; // Return current shape as C4Value to be stored back to property
|
||||
|
||||
const class C4PropertyDelegateShape *GetParentDelegate() const { return parent_delegate; }
|
||||
|
||||
|
@ -71,12 +71,13 @@ private:
|
|||
bool store_as_proplist;
|
||||
bool properties_lowercase;
|
||||
public:
|
||||
C4ConsoleQtRect(class C4Object *for_obj, C4PropList *props, const C4Value &val, const class C4PropertyDelegateShape *parent_delegate);
|
||||
C4ConsoleQtRect(class C4Object *for_obj, C4PropList *props, 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;
|
||||
bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border, bool shift_down, bool ctrl_down) 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;
|
||||
void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy, int32_t hit_range, Qt::CursorShape *drag_cursor) override;
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
C4Value GetValue() const override;
|
||||
};
|
||||
|
||||
|
@ -88,12 +89,13 @@ private:
|
|||
int32_t cx, cy;
|
||||
bool can_move_center;
|
||||
public:
|
||||
C4ConsoleQtCircle(class C4Object *for_obj, C4PropList *props, const C4Value &val, const class C4PropertyDelegateShape *parent_delegate);
|
||||
C4ConsoleQtCircle(class C4Object *for_obj, C4PropList *props, 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;
|
||||
bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border, bool shift_down, bool ctrl_down) 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;
|
||||
void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy, int32_t hit_range, Qt::CursorShape *drag_cursor) override;
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
C4Value GetValue() const override;
|
||||
};
|
||||
|
||||
|
@ -103,15 +105,127 @@ 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);
|
||||
C4ConsoleQtPoint(class C4Object *for_obj, C4PropList *props, 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;
|
||||
bool IsHit(int32_t x, int32_t y, int32_t hit_range, Qt::CursorShape *drag_cursor, int32_t *drag_border, bool shift_down, bool ctrl_down) 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;
|
||||
void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy, int32_t hit_range, Qt::CursorShape *drag_cursor) override;
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
C4Value GetValue() const override;
|
||||
};
|
||||
|
||||
// Vertices and edges
|
||||
class C4ConsoleQtGraph : public C4ConsoleQtShape
|
||||
{
|
||||
protected:
|
||||
struct Vertex
|
||||
{
|
||||
int32_t x, y;
|
||||
uint32_t color; // 0 = default color
|
||||
|
||||
Vertex() : x(0), y(0), color(0u) {}
|
||||
};
|
||||
|
||||
struct Edge
|
||||
{
|
||||
int32_t vertex_indices[2]; // index into vertices array
|
||||
uint32_t color; // 0 = default color
|
||||
uint32_t line_thickness;
|
||||
|
||||
Edge() : color(0u), line_thickness(1) { vertex_indices[0] = vertex_indices[1] = -1; }
|
||||
bool connects_to(int32_t vertex_index) const;
|
||||
bool connects_to(int32_t vertex_index, int32_t *idx) const;
|
||||
};
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<Edge> edges;
|
||||
bool store_as_proplist;
|
||||
bool properties_lowercase;
|
||||
bool allow_edge_selection; // If edges on the graph can be selected
|
||||
|
||||
// Drag snap to other vertices
|
||||
int32_t drag_snap_offset_x = 0, drag_snap_offset_y = 0;
|
||||
bool drag_snapped = false;
|
||||
int32_t drag_snap_vertex = -1, drag_source_vertex_index = -1;
|
||||
|
||||
// Resolve border_index to vertices/edges: Use negative indices for edges and zero/positive indices for vertices
|
||||
static bool IsVertexDrag(int32_t border) { return border >= 0; }
|
||||
static bool IsEdgeDrag(int32_t border) { return border < -1; }
|
||||
static int32_t DragBorderToVertex(int32_t border) { return border; }
|
||||
static int32_t DragBorderToEdge(int32_t border) { return -2 - border; }
|
||||
static int32_t VertexToDragBorder(int32_t vertex) { return vertex; }
|
||||
static int32_t EdgeToDragBorder(int32_t edge) { return -edge - 2; }
|
||||
public:
|
||||
C4ConsoleQtGraph(class C4Object *for_obj, C4PropList *props, 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, bool shift_down, bool ctrl_down) override;
|
||||
void Draw(class C4TargetFacet &cgo, float line_width) override;
|
||||
void Drag(int32_t x, int32_t y, int32_t dx, int32_t dy, int32_t hit_range, Qt::CursorShape *drag_cursor) override;
|
||||
bool StartDragging(int32_t border, int32_t x, int32_t y, bool shift_down, bool ctrl_down) override;
|
||||
void StopDragging() override;
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
C4Value GetValue() const override;
|
||||
|
||||
protected:
|
||||
void InsertVertexBefore(int32_t insert_vertex_index, int32_t x, int32_t y);
|
||||
void InsertEdgeBefore(int32_t insert_edge_index, int32_t vertex1, int32_t vertex2);
|
||||
virtual int32_t InsertVertexOnEdge(int32_t split_edge_index, int32_t x, int32_t y);
|
||||
virtual int32_t InsertVertexOnVertex(int32_t target_vertex_index, int32_t x, int32_t y);
|
||||
virtual void RemoveEdge(int32_t edge_index);
|
||||
virtual void RemoveVertex(int32_t vertex_index, bool create_skip_connection);
|
||||
int32_t GetEdgeCountForVertex(int32_t vertex_index) const;
|
||||
|
||||
virtual bool IsPolyline() const { return false; }
|
||||
|
||||
C4ValueArray *GetVerticesValue() const;
|
||||
C4ValueArray *GetEdgesValue() const;
|
||||
void SetVerticesValue(const C4ValueArray *vvertices);
|
||||
void SetEdgesValue(const C4ValueArray *vedges);
|
||||
|
||||
// Check if given vertex/edge can be modified under given shift state
|
||||
virtual bool IsVertexHit(int32_t vertex_index, Qt::CursorShape *drag_cursor, bool shift_down, bool ctrl_down);
|
||||
virtual bool IsEdgeHit(int32_t edge_index, Qt::CursorShape *drag_cursor, bool shift_down, bool ctrl_down);
|
||||
|
||||
};
|
||||
|
||||
// Specialization of graph: One line of connected vertices
|
||||
class C4ConsoleQtPolyline : public C4ConsoleQtGraph
|
||||
{
|
||||
public:
|
||||
C4ConsoleQtPolyline(class C4Object *for_obj, C4PropList *props, const class C4PropertyDelegateShape *parent_delegate)
|
||||
: C4ConsoleQtGraph(for_obj, props, parent_delegate) {}
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
C4Value GetValue() const override;
|
||||
|
||||
protected:
|
||||
int32_t InsertVertexOnEdge(int32_t split_edge_index, int32_t x, int32_t y) override;
|
||||
int32_t InsertVertexOnVertex(int32_t target_vertex_index, int32_t x, int32_t y) override;
|
||||
void RemoveEdge(int32_t edge_index) override;
|
||||
|
||||
bool IsVertexHit(int32_t vertex_index, Qt::CursorShape *drag_cursor, bool shift_down, bool ctrl_down) override;
|
||||
bool IsPolyline() const override { return true; }
|
||||
};
|
||||
|
||||
// Specialization of graph: One closed line of connected vertices
|
||||
class C4ConsoleQtPolygon : public C4ConsoleQtPolyline
|
||||
{
|
||||
public:
|
||||
C4ConsoleQtPolygon(class C4Object *for_obj, C4PropList *props, const class C4PropertyDelegateShape *parent_delegate)
|
||||
: C4ConsoleQtPolyline(for_obj, props, parent_delegate) {}
|
||||
|
||||
void SetValue(const C4Value &val) override;
|
||||
|
||||
protected:
|
||||
int32_t InsertVertexOnEdge(int32_t split_edge_index, int32_t x, int32_t y) override;
|
||||
int32_t InsertVertexOnVertex(int32_t target_vertex_index, int32_t x, int32_t y) override;
|
||||
void RemoveEdge(int32_t edge_index) override;
|
||||
|
||||
bool IsVertexHit(int32_t vertex_index, Qt::CursorShape *drag_cursor, bool shift_down, bool ctrl_down) override;
|
||||
};
|
||||
|
||||
/* List of all current editable Qt shapes */
|
||||
class C4ConsoleQtShapes
|
||||
{
|
||||
|
@ -129,9 +243,9 @@ public:
|
|||
void ClearShapes();
|
||||
|
||||
// Mouse callbacks from viewports to execute shape dragging
|
||||
bool MouseDown(float x, float y, float hit_range); // return true if a shape was hit
|
||||
void MouseMove(float x, float y, bool left_down, float hit_range); // move move: Execute shape dragging
|
||||
void MouseUp(float x, float y);
|
||||
bool MouseDown(float x, float y, float hit_range, bool shift_down, bool ctrl_down); // return true if a shape was hit
|
||||
void MouseMove(float x, float y, bool left_down, float hit_range, bool shift_down, bool ctrl_down); // move move: Execute shape dragging
|
||||
void MouseUp(float x, float y, bool shift_down, bool ctrl_down);
|
||||
|
||||
void Draw(C4TargetFacet &cgo);
|
||||
|
||||
|
|
|
@ -149,9 +149,9 @@ void C4ConsoleQtViewportView::ShowContextMenu(const QPoint &pos)
|
|||
}
|
||||
|
||||
// Get Shift state as Win32 wParam
|
||||
uint32_t GetShiftWParam()
|
||||
uint32_t GetShiftWParam(QKeyEvent * event = nullptr)
|
||||
{
|
||||
auto modifiers = QGuiApplication::keyboardModifiers();
|
||||
auto modifiers = event ? event->modifiers() : QGuiApplication::keyboardModifiers();
|
||||
uint32_t result = 0;
|
||||
if (modifiers & Qt::ShiftModifier) result |= MK_SHIFT;
|
||||
if (modifiers & Qt::ControlModifier) result |= MK_CONTROL;
|
||||
|
@ -172,6 +172,12 @@ void C4ConsoleQtViewportView::mouseMoveEvent(QMouseEvent *eventMove)
|
|||
else
|
||||
{
|
||||
cvp->pWindow->EditCursorMove(eventMove->x() * pr, eventMove->y() * pr, GetShiftWParam());
|
||||
UpdateCursor();
|
||||
}
|
||||
}
|
||||
|
||||
void C4ConsoleQtViewportView::UpdateCursor()
|
||||
{
|
||||
Qt::CursorShape cursor;
|
||||
if (::Console.EditCursor.HasTransformCursor())
|
||||
cursor = Qt::SizeAllCursor;
|
||||
|
@ -180,8 +186,6 @@ void C4ConsoleQtViewportView::mouseMoveEvent(QMouseEvent *eventMove)
|
|||
else
|
||||
cursor = Qt::CrossCursor;
|
||||
this->setCursor(cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void C4ConsoleQtViewportView::mousePressEvent(QMouseEvent *eventPress)
|
||||
|
@ -376,6 +380,12 @@ void C4ConsoleQtViewportView::keyPressEvent(QKeyEvent * event)
|
|||
// Handled if handled as player control or main editor
|
||||
if (!handled) handled = Game.DoKeyboardInput(code, KEYEV_Down, !!(event->modifiers() & Qt::AltModifier), !!(event->modifiers() & Qt::ControlModifier), !!(event->modifiers() & Qt::ShiftModifier), event->isAutoRepeat(), NULL);
|
||||
if (!handled) handled = dock->main_window->HandleEditorKeyDown(event);
|
||||
// Modifiers may update the cursor state; refresh
|
||||
if (event->key() == Qt::Key_Shift || event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_AltGr)
|
||||
{
|
||||
::Console.EditCursor.Move(GetShiftWParam(event));
|
||||
UpdateCursor();
|
||||
}
|
||||
event->setAccepted(handled);
|
||||
}
|
||||
|
||||
|
@ -386,6 +396,12 @@ void C4ConsoleQtViewportView::keyReleaseEvent(QKeyEvent * event)
|
|||
// Handled if handled as player control
|
||||
bool handled = Game.DoKeyboardInput(code, KEYEV_Up, !!(event->modifiers() & Qt::AltModifier), !!(event->modifiers() & Qt::ControlModifier), !!(event->modifiers() & Qt::ShiftModifier), event->isAutoRepeat(), NULL);
|
||||
if (!handled) handled = dock->main_window->HandleEditorKeyUp(event);
|
||||
// Modifiers may update the cursor state; refresh
|
||||
if (event->key() == Qt::Key_Shift || event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_AltGr)
|
||||
{
|
||||
::Console.EditCursor.Move(GetShiftWParam(event));
|
||||
UpdateCursor();
|
||||
}
|
||||
event->setAccepted(handled);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ private:
|
|||
qreal GetDevicePixelRatio();
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
void AddSelectObjectContextEntry(C4Object *obj, QMenu *menu);
|
||||
void UpdateCursor();
|
||||
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent * event) override;
|
||||
|
|
|
@ -244,7 +244,7 @@ bool C4EditCursor::Move(float iX, float iY, float iZoom, DWORD dwKeyState)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
case C4CNS_ModeEdit:
|
||||
#ifdef WITH_QT_EDITOR
|
||||
shapes->MouseMove(X, Y, Hold, 3.0f/Zoom);
|
||||
shapes->MouseMove(X, Y, Hold, 3.0f/Zoom, !!(dwKeyState & MK_SHIFT), !!(dwKeyState & MK_CONTROL));
|
||||
#endif
|
||||
// Hold
|
||||
if (!DragFrame && Hold && !DragShape && !DragTransform)
|
||||
|
@ -288,6 +288,12 @@ bool C4EditCursor::Move(float iX, float iY, float iZoom, DWORD dwKeyState)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool C4EditCursor::Move(DWORD new_key_state)
|
||||
{
|
||||
// Move at last position with new key state
|
||||
return Move(X, Y, Zoom, new_key_state);
|
||||
}
|
||||
|
||||
void C4EditCursor::UpdateStatusBar()
|
||||
{
|
||||
int32_t X=this->X, Y=this->Y;
|
||||
|
@ -360,6 +366,14 @@ bool C4EditCursor::LeftButtonDown(DWORD dwKeyState)
|
|||
{
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
case C4CNS_ModeEdit:
|
||||
// Click on shape?
|
||||
#ifdef WITH_QT_EDITOR
|
||||
if (shapes->MouseDown(X, Y, 3.0f / Zoom, !!(dwKeyState & MK_SHIFT), !!(dwKeyState & MK_CONTROL)))
|
||||
{
|
||||
DragShape = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (dwKeyState & MK_CONTROL)
|
||||
{
|
||||
// Toggle target
|
||||
|
@ -369,14 +383,6 @@ bool C4EditCursor::LeftButtonDown(DWORD dwKeyState)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Click on shape?
|
||||
#ifdef WITH_QT_EDITOR
|
||||
if (shapes->MouseDown(X, Y, 3.0f/Zoom))
|
||||
{
|
||||
DragShape = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// Click rotate/scale marker?
|
||||
if (IsHoveringTransformMarker())
|
||||
{
|
||||
|
@ -502,7 +508,7 @@ bool C4EditCursor::LeftButtonUp(DWORD dwKeyState)
|
|||
|
||||
// Release
|
||||
#ifdef WITH_QT_EDITOR
|
||||
shapes->MouseUp(X, Y);
|
||||
shapes->MouseUp(X, Y, !!(dwKeyState & MK_SHIFT), !!(dwKeyState & MK_CONTROL));
|
||||
#endif
|
||||
Hold=false;
|
||||
DragFrame=false;
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
bool KeyDown(C4KeyCode KeyCode, DWORD dwKeyState);
|
||||
bool KeyUp(C4KeyCode KeyCode, DWORD dwKeyState);
|
||||
bool Move(float iX, float iY, float zoom, DWORD dwKeyState);
|
||||
bool Move(DWORD new_key_state);
|
||||
bool Init();
|
||||
bool EditingOK(bool for_landscape_drawing=false);
|
||||
C4EditCursorSelection &GetSelection() { return selection; }
|
||||
|
|
|
@ -114,8 +114,13 @@ C4StringTable::C4StringTable()
|
|||
P[P_Hgt] = "Hgt";
|
||||
P[P_wdt] = "wdt";
|
||||
P[P_hgt] = "hgt";
|
||||
P[P_Vertices] = "Vertices";
|
||||
P[P_Edges] = "Edges";
|
||||
P[P_LineWidth] = "LineWidth";
|
||||
P[P_OffX] = "OffX";
|
||||
P[P_OffY] = "OffY";
|
||||
P[P_Proplist] = "Proplist";
|
||||
P[P_proplist] = "proplist";
|
||||
P[P_FacetBase] = "FacetBase";
|
||||
P[P_FacetTopFace] = "FacetTopFace";
|
||||
P[P_FacetTargetStretch] = "FacetTargetStretch";
|
||||
|
|
|
@ -344,8 +344,13 @@ enum C4PropertyName
|
|||
P_Hgt,
|
||||
P_wdt,
|
||||
P_hgt,
|
||||
P_Vertices,
|
||||
P_Edges,
|
||||
P_LineWidth,
|
||||
P_OffX,
|
||||
P_OffY,
|
||||
P_proplist,
|
||||
P_Proplist,
|
||||
P_FacetBase,
|
||||
P_FacetTopFace,
|
||||
P_FacetTargetStretch,
|
||||
|
|
Loading…
Reference in New Issue