diff --git a/aegisub/subs_edit_box.cpp b/aegisub/subs_edit_box.cpp index 8535ab6c5..5f5db85cf 100644 --- a/aegisub/subs_edit_box.cpp +++ b/aegisub/subs_edit_box.cpp @@ -928,8 +928,11 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b // Current tag name wxString alttagname = tagname; + wxString removeTag; if (tagname == _T("\\1c")) tagname = _T("\\c"); if (tagname == _T("\\fr")) tagname = _T("\\frz"); + if (tagname == _T("\\pos")) removeTag = _T("\\move"); + if (tagname == _T("\\move")) removeTag = _T("\\pos"); // Get block at start size_t blockn = BlockAtPos(selstart); @@ -999,9 +1002,6 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b startcolor = style->shadow.GetWXColor(); isColor = true; } - else if (tagname == _T("\\pos")) { - isGeneric = true; - } else if (tagname == _T("\\frz")) { startangle = style->angle; isAngle = true; @@ -1018,9 +1018,8 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b startScale = style->scaley; isScale = true; } - else if (tagname == _T("\\clip")) { - isGeneric = true; - } + else isGeneric = true; + bool hasEnd = isFlag; // Find current value of style @@ -1163,7 +1162,8 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b // Remove old of same for (size_t i=0;iTags.size()-nInserted;i++) { //if (insert.Contains(override->Tags.at(i)->Name)) { - if (insertTags.Index(override->Tags.at(i)->Name) != wxNOT_FOUND) { + wxString name = override->Tags.at(i)->Name; + if (insertTags.Index(name) != wxNOT_FOUND || removeTag == name) { shift -= override->Tags.at(i)->ToString().Length(); override->Tags.erase(override->Tags.begin() + i); i--; @@ -1200,7 +1200,8 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b // Remove old of same for (size_t i=0;iTags.size()-nInserted;i++) { - if (insert.Contains(override->Tags.at(i)->Name)) { + wxString name = override->Tags.at(i)->Name; + if (insert.Contains(name) || removeTag == name) { shift -= override->Tags.at(i)->ToString().Length(); override->Tags.erase(override->Tags.begin() + i); i--; diff --git a/aegisub/visual_feature.cpp b/aegisub/visual_feature.cpp index 241372e61..6b06a0101 100644 --- a/aegisub/visual_feature.cpp +++ b/aegisub/visual_feature.cpp @@ -50,16 +50,28 @@ VisualDraggableFeature::VisualDraggableFeature() { layer = 0; lineN = -1; line = NULL; + for (int i=0;i<4;i++) brother[i] = NULL; } ///////////////////// // Is mouse over it? bool VisualDraggableFeature::IsMouseOver(int mx,int my) { + // Square if (type == DRAG_BIG_SQUARE) { if (mx < x-8 || mx > x+8 || my < y-8 || my > y+8) return false; return true; } + + // Circle + if (type == DRAG_BIG_CIRCLE) { + int dx = mx-x; + int dy = my-y; + if (dx*dx + dy*dy <= 64) return true; + return false; + } + + // Fallback return false; } @@ -69,9 +81,15 @@ bool VisualDraggableFeature::IsMouseOver(int mx,int my) { void VisualDraggableFeature::Draw(OpenGLWrapper *gl) { wxASSERT(gl); + // Square if (type == DRAG_BIG_SQUARE) { gl->DrawRectangle(x-8,y-8,x+8,y+8); gl->DrawLine(x,y-16,x,y+16); gl->DrawLine(x-16,y,x+16,y); } + + // Circle + if (type == DRAG_BIG_CIRCLE) { + gl->DrawCircle(x,y,8); + } } diff --git a/aegisub/visual_feature.h b/aegisub/visual_feature.h index 1408829fa..8da54b2c7 100644 --- a/aegisub/visual_feature.h +++ b/aegisub/visual_feature.h @@ -70,6 +70,8 @@ public: AssDialogue *line; int lineN; + VisualDraggableFeature *brother[4]; + bool IsMouseOver(int x,int y); void Draw(OpenGLWrapper *gl); diff --git a/aegisub/visual_tool.cpp b/aegisub/visual_tool.cpp index 332459ab0..15b4b2f9f 100644 --- a/aegisub/visual_tool.cpp +++ b/aegisub/visual_tool.cpp @@ -351,7 +351,7 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in tag = override->Tags.at(j); // Position - if ((tag->Name == _T("\\pos") || tag->Name == _("\\move")) && tag->Params.size() >= 2) { + if ((tag->Name == _T("\\pos") || tag->Name == _T("\\move")) && tag->Params.size() >= 2) { if (!posSet) { posx = tag->Params[0]->AsInt(); posy = tag->Params[1]->AsInt(); @@ -420,6 +420,43 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in } +/////////////////////////////////////// +// Get the destination of move, if any +void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) { + // Parse tags + hasMove = false; + diag->ParseASSTags(); + AssDialogueBlockOverride *override; + AssOverrideTag *tag; + size_t blockn = diag->Blocks.size(); + + // For each block + for (size_t i=0;iBlocks.at(i)); + if (override) { + for (size_t j=0;jTags.size();j++) { + tag = override->Tags.at(j); + + // Position + if (tag->Name == _T("\\move") && tag->Params.size() >= 4) { + hasMove = true; + x1 = tag->Params[0]->AsInt(); + y1 = tag->Params[1]->AsInt(); + x2 = tag->Params[2]->AsInt(); + y2 = tag->Params[3]->AsInt(); + if (tag->Params.size() >= 6) { + t1 = tag->Params[4]->AsInt(); + t2 = tag->Params[5]->AsInt(); + } + return; + } + } + } + } + diag->ClearBlocks(); +} + + /////////////////////// // Get line's rotation void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) { diff --git a/aegisub/visual_tool.h b/aegisub/visual_tool.h index 652474a09..ebe6a3cfb 100644 --- a/aegisub/visual_tool.h +++ b/aegisub/visual_tool.h @@ -80,6 +80,7 @@ protected: void GetLinePosition(AssDialogue *diag,int &x,int &y); void GetLinePosition(AssDialogue *diag,int &x,int &y,int &orgx,int &orgy); + void GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2); void GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz); void GetLineScale(AssDialogue *diag,float &scalX,float &scalY); void GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2); diff --git a/aegisub/visual_tool_drag.cpp b/aegisub/visual_tool_drag.cpp index 289ac6ec0..356c76265 100644 --- a/aegisub/visual_tool_drag.cpp +++ b/aegisub/visual_tool_drag.cpp @@ -69,6 +69,40 @@ void VisualToolDrag::Update() { // Draw void VisualToolDrag::Draw() { DrawAllFeatures(); + + // Draw arrows + for (size_t i=0;ibrother[0]; + + // See if the distance between them is at least 30 pixels + int dx = p2->x - p1->x; + int dy = p2->y - p1->y; + int dist = (int)sqrt(double(dx*dx + dy*dy)); + if (dist < 30) continue; + + // Get end points + int x1 = p1->x + dx*10/dist; + int x2 = p2->x - dx*20/dist; + int y1 = p1->y + dy*10/dist; + int y2 = p2->y - dy*20/dist; + + // Draw line + SetLineColour(colour[3],0.8f,2); + DrawLine(x1,y1,x2,y2); + + // Draw arrow + double angle = atan2(double(y2-y1),double(x2-x1))+1.570796; + int sx = int(cos(angle)*4); + int sy = int(-sin(angle)*4); + DrawLine(x2+sx,y2-sy,x2-sx,y2+sy); + DrawLine(x2+sx,y2-sy,x2+dx*10/dist,y2+dy*10/dist); + DrawLine(x2-sx,y2+sy,x2+dx*10/dist,y2+dy*10/dist); + } + } } @@ -92,20 +126,40 @@ void VisualToolDrag::PopulateFeatureList() { int f2 = VFR_Output.GetFrameAtTime(diag->End.GetMS(),false); if (f1 <= framen && f2 >= framen) { // Get position - int lineX,lineY; + int x1,x2,y1,y2; + int t1=0; + int t2=diag->End.GetMS()-diag->Start.GetMS(); int torgx,torgy; - GetLinePosition(diag,lineX,lineY,torgx,torgy); + bool hasMove; + GetLinePosition(diag,x1,y1,torgx,torgy); + GetLineMove(diag,hasMove,x1,y1,x2,y2,t1,t2); // Create \pos feature VisualDraggableFeature feat; - feat.x = lineX; - feat.y = lineY; + feat.x = x1; + feat.y = y1; feat.layer = 0; feat.type = DRAG_BIG_SQUARE; - feat.value = 0; + feat.value = t1; feat.line = diag; feat.lineN = i; features.push_back(feat); + + // Create move destination feature + if (hasMove) { + feat.x = x2; + feat.y = y2; + feat.layer = 1; + feat.type = DRAG_BIG_CIRCLE; + feat.value = t2; + feat.line = diag; + feat.lineN = i; + + // Add each other as brothers. Yes, this looks weird. + feat.brother[0] = &features.back(); + features.push_back(feat); + feat.brother[0]->brother[0] = &features.back(); + } } } } @@ -121,11 +175,30 @@ void VisualToolDrag::InitializeDrag(VisualDraggableFeature &feature) { /////////////// // Update drag void VisualToolDrag::UpdateDrag(VisualDraggableFeature &feature) { + // Update "value" to reflect the time of the frame in which the feature is being dragged + int frame_n = VideoContext::Get()->GetFrameN(); + int time = VFR_Output.GetTimeAtFrame(frame_n,true,true); + feature.value = MID(0,time - feature.line->Start.GetMS(),feature.line->End.GetMS()-feature.line->Start.GetMS()); } /////////////// // Commit drag void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) { - SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); + // Position + if (feature.brother[0] == NULL) { + SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); + } + + // Move + else { + // Get source on p1 and dest on p2 + VisualDraggableFeature *p1,*p2; + p1 = &feature; + if (p1->type == DRAG_BIG_CIRCLE) p1 = p1->brother[0]; + p2 = p1->brother[0]; + + // Set override + SetOverride(_T("\\move"),wxString::Format(_T("(%i,%i,%i,%i,%i,%i)"),p1->x,p1->y,p2->x,p2->y,p1->value,p2->value)); + } }