Editor: Object scaling+rotation

qteditor
Sven Eberhardt 2016-06-17 00:07:49 -04:00
parent bd516dfc44
commit b70882d7fa
11 changed files with 143 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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