forked from Mirrors/openclonk
Editor: Object scaling+rotation
parent
bd516dfc44
commit
b70882d7fa
Binary file not shown.
After Width: | Height: | Size: 656 B |
|
@ -193,7 +193,7 @@
|
|||
#define C4FLS_Material "TexMap.txt|*.ocm|*.jpeg|*.jpg|*.bmp|*.png"
|
||||
#define C4FLS_Graphics "Loader*.bmp|Loader*.png|Loader*.jpeg|Loader*.jpg|*.glsl|Font*.png"\
|
||||
"|GUIProgress.png|Endeavour.ttf|GUICaption.png|GUIButton.png|GUIButtonDown.png|GUIButtonHighlight.png|GUIButtonHighlightRound.png|GUIIcons.png|GUIIcons2.png|GUIScroll.png|GUIContext.png|GUISubmenu.png|GUICheckBox.png|GUIBigArrows.png"\
|
||||
"|Control.png|ClonkSkins.png|Fire.png|Background.png|Flag.png|Crew.png|Wealth.png|Player.png|Rank.png|Captain.png|Cursor.png|SelectMark.png|MenuSymbol.png|Menu.png|Logo.png|Construction.png|Energy.png|Options.png|UpperBoard.png|Arrow.png|Exit.png|Hand.png|Gamepad.png|Build.png|Achv*.png"\
|
||||
"|Control.png|ClonkSkins.png|Fire.png|Background.png|Flag.png|Crew.png|Wealth.png|Player.png|Rank.png|Captain.png|Cursor.png|SelectMark.png|MenuSymbol.png|Menu.png|Logo.png|Construction.png|Energy.png|Options.png|UpperBoard.png|Arrow.png|Exit.png|Hand.png|Gamepad.png|Build.png|TransformKnob.png|Achv*.png"\
|
||||
"|StartupMainMenuBG.*|StartupScenSelBG.*|StartupPlrSelBG.*|StartupPlrPropBG.*|StartupNetworkBG.*|StartupAboutBG.*|StartupBigButton.png|StartupBigButtonDown.png|StartupBookScroll.png|StartupContext.png|StartupScenSelIcons.png|StartupScenSelTitleOv.png|StartupDlgPaper.png|StartupOptionIcons.png|StartupTabClip.png|StartupNetGetRef.png|StartupLogo.png"
|
||||
#define C4FLS_Objects "Names*.txt|Desc*.txt|*.ocd"
|
||||
#define C4FLS_System "*.hlp|*.cnt|Language*.txt|*.fon|*.fnt|*.ttf|*.ttc|*.fot|*.otf|Fonts.txt|StringTbl*.txt|PlayerControls.txt|*.c|Names.txt"
|
||||
|
|
|
@ -1369,6 +1369,17 @@ void C4ControlEMMoveObject::Execute() const
|
|||
if (container && obj && container->Status && obj->Status) obj->Enter(container);
|
||||
}
|
||||
break;
|
||||
case EMMO_Transform:
|
||||
{
|
||||
C4Object *pTarget = ::Objects.SafeObjectPointer(iTargetObj);
|
||||
if (pTarget)
|
||||
{
|
||||
int32_t new_rot = fixtoi(this->tx, 1);
|
||||
int32_t new_con = fixtoi(this->ty, FullCon/100);
|
||||
if (pTarget->Def->Rotateable) pTarget->SetRotation(new_rot);
|
||||
if (pTarget->Def->GrowthType) pTarget->DoCon(new_con - pTarget->GetCon(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// update property dlg & status bar
|
||||
if (fLocalCall && eAction != eAction)
|
||||
|
|
|
@ -453,7 +453,8 @@ enum C4ControlEMObjectAction
|
|||
EMMO_Exit, // exit objects
|
||||
EMMO_Select, // select object
|
||||
EMMO_Deselect, // deselect object
|
||||
EMMO_Create // create a new object (used by C4Game::DropDef)
|
||||
EMMO_Create, // create a new object (used by C4Game::DropDef)
|
||||
EMMO_Transform // adjust rotation / con of selected object
|
||||
};
|
||||
|
||||
class C4ControlEMMoveObject : public C4ControlPacket // sync
|
||||
|
|
|
@ -85,7 +85,14 @@ void C4ConsoleQtViewportView::mouseMoveEvent(QMouseEvent *eventMove)
|
|||
else
|
||||
{
|
||||
cvp->pWindow->EditCursorMove(eventMove->x() * pr, eventMove->y() * pr, GetShiftWParam());
|
||||
this->setCursor(::Console.EditCursor.GetShapes()->HasDragCursor() ? ::Console.EditCursor.GetShapes()->GetDragCursor() : Qt::CrossCursor);
|
||||
Qt::CursorShape cursor;
|
||||
if (::Console.EditCursor.HasTransformCursor())
|
||||
cursor = Qt::SizeAllCursor;
|
||||
else if (::Console.EditCursor.GetShapes()->HasDragCursor())
|
||||
cursor = ::Console.EditCursor.GetShapes()->GetDragCursor();
|
||||
else
|
||||
cursor = Qt::CrossCursor;
|
||||
this->setCursor(cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ void C4EditCursor::ClearPointers(C4Object *pObj)
|
|||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
bool C4EditCursor::Move(float iX, float iY, DWORD dwKeyState)
|
||||
bool C4EditCursor::Move(float iX, float iY, float iZoom, DWORD dwKeyState)
|
||||
{
|
||||
// alt check
|
||||
bool fAltIsDown = (dwKeyState & MK_ALT) != 0;
|
||||
|
@ -220,17 +220,48 @@ bool C4EditCursor::Move(float iX, float iY, DWORD dwKeyState)
|
|||
|
||||
// Offset movement
|
||||
float xoff = iX-X; float yoff = iY-Y;
|
||||
X=iX; Y=iY;
|
||||
X = iX; Y = iY; Zoom = iZoom;
|
||||
|
||||
// Drag rotation/scale of object
|
||||
if (DragTransform)
|
||||
{
|
||||
C4Object *obj = selection.GetObject();
|
||||
if (obj)
|
||||
{
|
||||
int32_t new_rot = (DragRot0 + int32_t(float(X - X2)*Zoom)) % 360;
|
||||
if (new_rot < 0) new_rot += 360;
|
||||
if (fShiftIsDown) new_rot = (new_rot + 23) / 45 * 45;
|
||||
int32_t new_con = DragCon0 + int32_t(float(Y2 - Y)*Zoom*(FullCon / 200));
|
||||
int32_t con_step = FullCon / 5;
|
||||
if (fShiftIsDown) new_con = (new_con + con_step/2) / con_step * con_step;
|
||||
if (!obj->Def->Oversize) new_con = std::min<int32_t>(new_con, FullCon);
|
||||
new_con = std::max<int32_t>(new_con, fShiftIsDown ? 1 : con_step);
|
||||
bool any_change = false;
|
||||
if (obj->Def->Rotateable)
|
||||
if (new_rot != DragRotLast)
|
||||
any_change = true;
|
||||
if (obj->Def->GrowthType)
|
||||
if (new_con != DragConLast)
|
||||
any_change = true;
|
||||
if (any_change)
|
||||
{
|
||||
EMMoveObject(EMMO_Transform, itofix(new_rot, 1), itofix(new_con, FullCon/100), obj, nullptr);
|
||||
DragRotLast = new_rot;
|
||||
DragConLast = new_con;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
case C4CNS_ModeEdit:
|
||||
#ifdef WITH_QT_EDITOR
|
||||
shapes->MouseMove(X, Y, Hold, 3.0f /* TODO: Depend on zoom */);
|
||||
shapes->MouseMove(X, Y, Hold, 3.0f/Zoom);
|
||||
#endif
|
||||
// Hold
|
||||
if (!DragFrame && Hold && !DragShape)
|
||||
if (!DragFrame && Hold && !DragShape && !DragTransform)
|
||||
{
|
||||
MoveSelection(ftofix(xoff),ftofix(yoff));
|
||||
UpdateDropTarget(dwKeyState);
|
||||
|
@ -369,12 +400,22 @@ bool C4EditCursor::LeftButtonDown(DWORD dwKeyState)
|
|||
{
|
||||
// Click on shape?
|
||||
#ifdef WITH_QT_EDITOR
|
||||
if (shapes->MouseDown(X, Y, 3.0f /* TODO: Depend on zoom */))
|
||||
if (shapes->MouseDown(X, Y, 3.0f/Zoom))
|
||||
{
|
||||
DragShape = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// Click rotate/scale marker?
|
||||
if (IsHoveringTransformMarker())
|
||||
{
|
||||
DragTransform = true;
|
||||
X2 = X; Y2 = Y;
|
||||
C4Object *dragged_obj = selection.GetObject();
|
||||
DragRot0 = DragRotLast = dragged_obj->GetR();
|
||||
DragCon0 = DragConLast = dragged_obj->GetCon();
|
||||
break;
|
||||
}
|
||||
// Click on unselected: select single
|
||||
if (Target)
|
||||
{
|
||||
|
@ -496,6 +537,7 @@ bool C4EditCursor::LeftButtonUp(DWORD dwKeyState)
|
|||
DragFrame=false;
|
||||
DragLine=false;
|
||||
DragShape = false;
|
||||
DragTransform = false;
|
||||
DropTarget=NULL;
|
||||
// Update
|
||||
UpdateStatusBar();
|
||||
|
@ -610,7 +652,7 @@ bool C4EditCursor::Duplicate()
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4EditCursor::DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight)
|
||||
void C4EditCursor::DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight, bool draw_transform_marker)
|
||||
{
|
||||
// target pos (parallax)
|
||||
float line_width = std::max<float>(1.0f, 1.0f / cgo.Zoom);
|
||||
|
@ -647,6 +689,45 @@ void C4EditCursor::DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t selec
|
|||
cobj->ColorMod = dwOldMod;
|
||||
cobj->BlitMode = dwOldBlitMode;
|
||||
}
|
||||
// Transformer knob
|
||||
if (draw_transform_marker)
|
||||
{
|
||||
float transform_marker_x = 0.0f, transform_marker_y = 0.0f;
|
||||
if (HasTransformMarker(&transform_marker_x, &transform_marker_y, cgo.Zoom))
|
||||
{
|
||||
transform_marker_x += offX; transform_marker_y += offY;
|
||||
float sz = float(::GraphicsResource.fctTransformKnob.Hgt) / cgo.Zoom;
|
||||
C4Facet transform_target_sfc(cgo.Surface, transform_marker_x-sz/2, transform_marker_y-sz/2, sz, sz);
|
||||
::GraphicsResource.fctTransformKnob.Draw(transform_target_sfc);
|
||||
// Transform knob while dragging
|
||||
if (DragTransform)
|
||||
{
|
||||
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
||||
transform_target_sfc.X += X - X2;
|
||||
transform_target_sfc.Y += Y - Y2;
|
||||
::GraphicsResource.fctTransformKnob.Draw(transform_target_sfc);
|
||||
pDraw->ResetBlitMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool C4EditCursor::HasTransformMarker(float *x, float *y, float zoom) const
|
||||
{
|
||||
// Single selection only (assume obj is in selection)
|
||||
if (selection.size() != 1) return false;
|
||||
C4Object *obj = selection.GetObject();
|
||||
if (!obj) return false;
|
||||
// Show knob only for objects that can be scaled or rotated
|
||||
if (!obj->Def->GrowthType && !obj->Def->Rotateable) return false;
|
||||
// Show knob only if the shape has a certain minimum size in either extent (so small objects can still be moved)
|
||||
float vis_wdt = float(obj->Shape.Wdt) * zoom;
|
||||
float vis_hgt = float(obj->Shape.Wdt) * zoom;
|
||||
if (vis_wdt < ::GraphicsResource.fctTransformKnob.Hgt && vis_hgt < ::GraphicsResource.fctTransformKnob.Hgt) return false;
|
||||
// It's visible: Put it to the bottom of the shape without the shape expansion through rotation
|
||||
*x = 0;
|
||||
*y = float(obj->Def->Shape.y + obj->Def->Shape.Hgt) * obj->GetCon() / FullCon - float(::GraphicsResource.fctTransformKnob.Hgt) / (zoom*2);
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4EditCursor::Draw(C4TargetFacet &cgo)
|
||||
|
@ -662,7 +743,7 @@ void C4EditCursor::Draw(C4TargetFacet &cgo)
|
|||
{
|
||||
C4Object *cobj = obj.getObj();
|
||||
if (!cobj) continue;
|
||||
DrawObject(cgo, cobj, 0xffffffff, fShiftWasDown); // highlight selection if shift is pressed
|
||||
DrawObject(cgo, cobj, 0xffffffff, fShiftWasDown, true); // highlight selection if shift is pressed
|
||||
}
|
||||
// Draw drag frame
|
||||
if (DragFrame)
|
||||
|
@ -702,7 +783,7 @@ void C4EditCursor::Draw(C4TargetFacet &cgo)
|
|||
}
|
||||
// Draw object highlight
|
||||
C4Object *highlight = highlighted_object.getObj();
|
||||
if (highlight) DrawObject(cgo, highlight, 0xffff8000, true); // highlight selection if shift is pressed
|
||||
if (highlight) DrawObject(cgo, highlight, 0xffff8000, true, false); // highlight selection if shift is pressed
|
||||
}
|
||||
|
||||
|
||||
|
@ -782,12 +863,13 @@ void C4EditCursor::Default()
|
|||
#ifdef USE_WIN32_WINDOWS
|
||||
hMenu=NULL;
|
||||
#endif
|
||||
Hold=DragFrame=DragLine=DragShape=false;
|
||||
Hold=DragFrame=DragLine=DragShape=DragTransform=false;
|
||||
selection.clear();
|
||||
creator_def = NULL;
|
||||
creator_overlay = NULL;
|
||||
has_mouse_hover = false;
|
||||
selection_invalid = false;
|
||||
DragRot0 = DragRotLast = 0; DragCon0 = DragConLast = FullCon;
|
||||
}
|
||||
|
||||
void C4EditCursor::Clear()
|
||||
|
@ -1320,4 +1402,18 @@ bool C4EditCursor::GetCurrentSelectionPosition(int32_t *x, int32_t *y)
|
|||
void C4EditCursor::SetHighlightedObject(C4Object *new_highlight)
|
||||
{
|
||||
highlighted_object = C4VObj(new_highlight);
|
||||
}
|
||||
|
||||
bool C4EditCursor::IsHoveringTransformMarker() const
|
||||
{
|
||||
float trf_marker_x, trf_marker_y;
|
||||
if (HasTransformMarker(&trf_marker_x, &trf_marker_y, Zoom))
|
||||
{
|
||||
C4Object *obj = selection.GetObject();
|
||||
float dx = (float(X - obj->GetX()) - trf_marker_x) * Zoom;
|
||||
float dy = (float(Y - obj->GetY()) - trf_marker_y) * Zoom;
|
||||
if (dx*dx + dy*dy <= ::GraphicsResource.fctTransformKnob.Hgt * ::GraphicsResource.fctTransformKnob.Hgt / 4)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -56,8 +56,9 @@ protected:
|
|||
bool has_mouse_hover;
|
||||
bool selection_invalid; // if true, the property list should be updated on next execution
|
||||
int32_t Mode;
|
||||
float X,Y,X2,Y2;
|
||||
bool Hold,DragFrame,DragLine,DragShape;
|
||||
float X,Y,X2,Y2,Zoom;
|
||||
bool Hold,DragFrame,DragLine,DragShape,DragTransform;
|
||||
int32_t DragRot0, DragCon0, DragRotLast, DragConLast;
|
||||
C4Object *Target,*DropTarget;
|
||||
C4Value highlighted_object;
|
||||
class C4Def *creator_def;
|
||||
|
@ -108,7 +109,7 @@ public:
|
|||
bool RightButtonDown(DWORD dwKeyState);
|
||||
bool KeyDown(C4KeyCode KeyCode, DWORD dwKeyState);
|
||||
bool KeyUp(C4KeyCode KeyCode, DWORD dwKeyState);
|
||||
bool Move(float iX, float iY, DWORD dwKeyState);
|
||||
bool Move(float iX, float iY, float zoom, DWORD dwKeyState);
|
||||
bool Init();
|
||||
bool EditingOK(bool for_landscape_drawing=false);
|
||||
C4EditCursorSelection &GetSelection() { return selection; }
|
||||
|
@ -118,6 +119,8 @@ public:
|
|||
bool AltUp();
|
||||
void SetMouseHover(bool h) { has_mouse_hover = h; }
|
||||
class C4ConsoleQtShapes *GetShapes() const { return shapes.get(); }
|
||||
bool HasTransformCursor() const { return DragTransform || IsHoveringTransformMarker(); }
|
||||
bool IsHoveringTransformMarker() const;
|
||||
protected:
|
||||
void UpdateStatusBar();
|
||||
void ApplyCreateObject(bool contained);
|
||||
|
@ -131,8 +134,9 @@ protected:
|
|||
void ApplyToolRect();
|
||||
void ApplyToolLine();
|
||||
void ApplyToolBrush();
|
||||
void DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight);
|
||||
void DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight, bool draw_transform_marker);
|
||||
void DrawSelectMark(C4Facet &cgo, FLOAT_RECT r, float width, uint32_t color = 0xffffffff);
|
||||
bool HasTransformMarker(float *x, float *y, float zoom) const;
|
||||
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);
|
||||
|
|
|
@ -219,5 +219,5 @@ void C4ViewportWindow::Close()
|
|||
}
|
||||
void C4ViewportWindow::EditCursorMove(int X, int Y, uint32_t state)
|
||||
{
|
||||
Console.EditCursor.Move(cvp->WindowToGameX(X), cvp->WindowToGameY(Y), state);
|
||||
Console.EditCursor.Move(cvp->WindowToGameX(X), cvp->WindowToGameY(Y), cvp->GetZoom(), state);
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags)
|
|||
switch (button)
|
||||
{
|
||||
case C4MC_Button_LeftDown:
|
||||
Console.EditCursor.Move(viewport->GetViewX()+x/viewport->GetZoom(), viewport->GetViewY()+y/viewport->GetZoom(), flags);
|
||||
Console.EditCursor.Move(viewport->GetViewX()+x/viewport->GetZoom(), viewport->GetViewY()+y/viewport->GetZoom(), viewport->GetZoom(), flags);
|
||||
Console.EditCursor.LeftButtonDown(flags);
|
||||
break;
|
||||
case C4MC_Button_LeftUp:
|
||||
|
|
|
@ -85,6 +85,8 @@ void C4GraphicsResource::Default()
|
|||
fctOKCancel.Default();
|
||||
fctMouse.Default();
|
||||
|
||||
fctTransformKnob.Default();
|
||||
|
||||
iNumRanks=1;
|
||||
idRegisteredMainGroupSetFiles=-1;
|
||||
}
|
||||
|
@ -123,6 +125,7 @@ void C4GraphicsResource::Clear()
|
|||
fctHand.Clear();
|
||||
fctGamepad.Clear();
|
||||
fctBuild.Clear();
|
||||
fctTransformKnob.Clear();
|
||||
// GUI data
|
||||
sfcCaption.Clear(); sfcButton.Clear(); sfcButtonD.Clear(); sfcScroll.Clear(); sfcContext.Clear();
|
||||
idSfcCaption = idSfcButton = idSfcButtonD = idSfcScroll = idSfcContext = 0;
|
||||
|
@ -136,6 +139,7 @@ void C4GraphicsResource::Clear()
|
|||
fctProgressBar.Clear();
|
||||
fctContext.Default();
|
||||
|
||||
|
||||
// unhook deflist from font
|
||||
FontRegular.SetCustomImages(NULL);
|
||||
|
||||
|
@ -265,6 +269,7 @@ bool C4GraphicsResource::Init()
|
|||
if (!LoadFile(fctHand, "Hand", Files, C4FCT_Height, C4FCT_Full, false, 0)) return false;
|
||||
if (!LoadFile(fctGamepad, "Gamepad", Files, 80, C4FCT_Full, false, 0)) return false;
|
||||
if (!LoadFile(fctBuild, "Build", Files, C4FCT_Full, C4FCT_Full, false, 0)) return false;
|
||||
if (!LoadFile(fctTransformKnob,"TransformKnob",Files,C4FCT_Full, C4FCT_Full, false, 0)) return false;
|
||||
|
||||
// achievements
|
||||
if (!Achievements.Init(Files)) return false;
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
C4Facet fctCommand;
|
||||
C4Facet fctKey;
|
||||
C4Facet fctOKCancel;
|
||||
C4FacetID fctTransformKnob;
|
||||
C4FacetID fctCrewClr; // ColorByOwner-surface of fctCrew
|
||||
C4FacetID fctFlagClr; // ColorByOwner-surface of fctFlag
|
||||
C4FacetID fctPlayerClr; // ColorByOwner-surface of fctPlayer
|
||||
|
|
Loading…
Reference in New Issue