Rectangular Selection: removed direction-based additive/subtractive selection. You can now hold Ctrl to enable subtractive selection, hold Ctrl-Shift to intersect with existing selection.

Point Thing at Cursor action: action now works when used from menu, changed default shortcut to Shift-L. You can now hold Ctrl to point Things away from cursor.
This commit is contained in:
MaxED 2013-04-09 10:56:05 +00:00
parent 8f40e113fe
commit 043590100b
13 changed files with 334 additions and 274 deletions

View file

@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.Editing
protected bool selectpressed; //mxd
private Vector2D selectstart;
protected RectangleF selectionrect;
protected bool subtractiveSelection; //mxd. When set to true, objects will be removed from selection instead of adding
protected MarqueSelectionMode marqueSelectionMode; //mxd
// View panning
protected bool panning;
@ -715,7 +715,6 @@ namespace CodeImp.DoomBuilder.Editing
protected virtual void OnEndMultiSelection()
{
selecting = false;
subtractiveSelection = false; //mxd
}
/// <summary>
@ -724,7 +723,6 @@ namespace CodeImp.DoomBuilder.Editing
protected virtual void StartMultiSelection()
{
selecting = true;
subtractiveSelection = false; //mxd
selectstart = mousemappos;
selectionrect = new RectangleF(selectstart.x, selectstart.y, 0, 0);
}
@ -758,8 +756,20 @@ namespace CodeImp.DoomBuilder.Editing
/// </summary>
protected virtual void RenderMultiSelection()
{
renderer.RenderRectangle(selectionrect, SELECTION_BORDER_SIZE,
subtractiveSelection ? General.Colors.Highlight.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha() : General.Colors.Highlight.WithAlpha(SELECTION_ALPHA), true); //mxd. Added subtractive selection
//mxd
PixelColor marqueColor = PixelColor.Transparent;
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
marqueColor = General.Colors.Selection.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
} else { //should be Intersect
marqueColor = General.Colors.Highlight.WithAlpha(SELECTION_ALPHA).InverseKeepAlpha();
}
renderer.RenderRectangle(selectionrect, SELECTION_BORDER_SIZE, marqueColor, true);
}
/// <summary>
@ -827,4 +837,13 @@ namespace CodeImp.DoomBuilder.Editing
#endregion
}
//mxd
public enum MarqueSelectionMode
{
SELECT,
ADD,
SUBTRACT,
INTERSECT,
}
}

View file

@ -183,11 +183,12 @@ classicselect
{
title = "Select";
category = "classic";
description = "Selects the highlighted item. Also allows selection by dragging a rectangle. Hold shift while dragging a rectangle to toggle additive or normal selection.";
description = "Selects the highlighted item. Also allows selection by dragging a rectangle. Hold shift while dragging a rectangle to toggle additive or normal selection. Hold Ctrl to enable subtractive selection. Hold Ctrl-Shift to intersect with current selection.";
allowkeys = true;
allowmouse = true;
allowscroll = false;
disregardshift = true;
disregardcontrol = true;
}
classicedit

View file

@ -140,18 +140,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected override void OnUpdateMultiSelection() {
base.OnUpdateMultiSelection();
//check for subtractive selection
if(BuilderPlug.Me.MarqueSelectionMode == 0) {
return;
} else if(BuilderPlug.Me.MarqueSelectionMode == 1) { //Left to right adds, right to left removes from selection.
subtractiveSelection = SelectionStart.x > selectionrect.X;
} else if(BuilderPlug.Me.MarqueSelectionMode == 2) { //Left to right removes, right to left adds to selection.
subtractiveSelection = SelectionStart.x == selectionrect.X;
} else if(BuilderPlug.Me.MarqueSelectionMode == 3) { //Top to bottom adds, bottom to top removes from selection.
subtractiveSelection = SelectionStart.y == selectionrect.Y;
} else if(BuilderPlug.Me.MarqueSelectionMode == 4) { //Top to bottom removes, bottom to top adds to selection.
subtractiveSelection = SelectionStart.y > selectionrect.Y;
}
if(General.Interface.CtrlState && General.Interface.ShiftState)
marqueSelectionMode = MarqueSelectionMode.INTERSECT;
else if(General.Interface.CtrlState)
marqueSelectionMode = MarqueSelectionMode.SUBTRACT;
else if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect)
marqueSelectionMode = MarqueSelectionMode.ADD;
else
marqueSelectionMode = MarqueSelectionMode.SELECT;
}
#endregion

View file

@ -657,21 +657,83 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
/*if(BuilderPlug.Me.AutoClearSelection && !selectionvolume)
{
General.Map.Map.ClearSelectedLinedefs();
General.Map.Map.ClearSelectedSectors();
}*/
if(selectionvolume)
{
//mxd. collect changed sectors
if(subtractiveSelection) {
//deselect sectors fully and partially inside selection, leave others untouched
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected)
continue;
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
} else {
//select sectors fully inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
}
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select) SelectSector(s, true, false);
}
} else {
//select sectors fully inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select) SelectSector(s, true, false);
}
}
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
if(BuilderPlug.Me.MarqueSelectTouching) {
//deselect sectors fully and partially inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool deselect = false;
foreach(Sidedef sd in s.Sidedefs) {
@ -681,13 +743,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
if(deselect)
SelectSector(s, false, false);
if(deselect) SelectSector(s, false, false);
}
} else {
//deselect sectors fully inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
if(!s.Selected) continue;
bool deselect = true;
foreach(Sidedef sd in s.Sidedefs) {
@ -697,78 +758,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
if(deselect)
SelectSector(s, false, false);
if(deselect) SelectSector(s, false, false);
}
}
} else { //additive selection
} else { //should be Intersect
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, leave others untouched
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = false;
//deselect sectors which are fully outside selection
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool keep = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
keep = true;
break;
}
if(select)
SelectSector(s, true, false);
}
} else {//select sectors fully and partially inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
if(!keep) SelectSector(s, false, false);
}
} else {
//select sectors fully inside selection, leave others untouched
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = true;
//deselect sectors which are fully and partially outside selection
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool keep = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
keep = false;
break;
}
if(select)
SelectSector(s, true, false);
}
} else {//select sectors fully inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
if(!keep) SelectSector(s, false, false);
}
}
}

View file

@ -543,14 +543,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected override void OnEndMultiSelection()
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
//if(BuilderPlug.Me.AutoClearSelection && !selectionvolume)
//General.Map.Map.ClearSelectedLinedefs();
if(selectionvolume)
{
//mxd
if(subtractiveSelection) {
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
} else {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
}
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
} else {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
}
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs) {
@ -563,24 +578,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
l.Selected = false;
}
}
} else {
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
} else {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
} else { //should be Intersect
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs) {
if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && !selectionrect.Contains(l.End.Position.x, l.End.Position.y))
l.Selected = false;
}
} else {
// Go for all lines
if(BuilderPlug.Me.MarqueSelectTouching) {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
} else {
foreach(Linedef l in General.Map.Map.Linedefs)
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
foreach(Linedef l in General.Map.Map.Linedefs) {
if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || !selectionrect.Contains(l.End.Position.x, l.End.Position.y))
l.Selected = false;
}
}
}

View file

@ -835,18 +835,81 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
/*if(BuilderPlug.Me.AutoClearSelection && !selectionvolume)
{
General.Map.Map.ClearSelectedLinedefs();
General.Map.Map.ClearSelectedSectors();
}*/
if(selectionvolume)
{
//mxd. collect changed sectors
if(subtractiveSelection) {
//deselect sectors fully and partially inside selection, leave others untouched
if(marqueSelectionMode == MarqueSelectionMode.SELECT){
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
}else{
//select sectors fully inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
}
}else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select) SelectSector(s, true, false);
}
}else{
//select sectors fully inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select) SelectSector(s, true, false);
}
}
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
if(BuilderPlug.Me.MarqueSelectTouching) {
//deselect sectors fully and partially inside selection, leave others untouched
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool deselect = false;
@ -876,72 +939,37 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(deselect) SelectSector(s, false, false);
}
}
} else { //additive selection
} else { //should be Intersect
if(BuilderPlug.Me.MarqueSelectTouching) {
//select sectors fully and partially inside selection, leave others untouched
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = false;
//deselect sectors which are fully outside selection
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool keep = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
keep = true;
break;
}
if(select) SelectSector(s, true, false);
}
} else {//select sectors fully and partially inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = false;
foreach(Sidedef sd in s.Sidedefs) {
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = true;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
if(!keep) SelectSector(s, false, false);
}
} else {
//select sectors fully inside selection, leave others untouched
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
foreach(Sector s in General.Map.Map.Sectors) {
if(s.Selected) continue;
bool select = true;
//deselect sectors which are fully and partially outside selection
foreach(Sector s in General.Map.Map.Sectors) {
if(!s.Selected) continue;
bool keep = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
keep = false;
break;
}
if(select) SelectSector(s, true, false);
}
} else {//select sectors fully inside selection, deselect all other sectors
foreach(Sector s in General.Map.Map.Sectors) {
bool select = true;
foreach(Sidedef sd in s.Sidedefs) {
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
select = false;
break;
}
}
if(select && !s.Selected)
SelectSector(s, true, false);
else if(!select && s.Selected)
SelectSector(s, false, false);
}
if(!keep) SelectSector(s, false, false);
}
}
}

View file

@ -63,6 +63,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Interface
private bool editpressed;
private bool thinginserted;
private bool awaitingMouseClick; //mxd
#endregion
@ -282,6 +283,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Selection
protected override void OnSelectBegin()
{
//mxd. Yep, it's kinda hackish...
if(awaitingMouseClick) {
awaitingMouseClick = false;
ThingPointAtCursor();
return;
}
// Item highlighted?
if((highlighted != null) && !highlighted.IsDisposed)
{
@ -548,26 +556,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
//if(BuilderPlug.Me.AutoClearSelection && !selectionvolume)
//General.Map.Map.ClearSelectedThings();
if(selectionvolume)
{
//mxd
if(subtractiveSelection) {
// Go for all things
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected = selectionrect.Contains(t.Position.x, t.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected |= selectionrect.Contains(t.Position.x, t.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
} else {
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
// Go for all things
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected |= selectionrect.Contains(t.Position.x, t.Position.y);
} else {
// Go for all things
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
t.Selected = selectionrect.Contains(t.Position.x, t.Position.y);
}
} else { //should be Intersect
// Go for all vertices
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
if(!selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
}
}
@ -863,16 +870,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
if((selected.Count == 0) && (highlighted != null) && !highlighted.IsDisposed)
selected.Add(highlighted);
if(!mousemappos.IsFinite()) {
General.Interface.DisplayStatus(StatusType.Warning, "Invalid mouse position!");
return;
}
if(selected.Count == 0) {
General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!");
return;
}
//check mouse position
if(!mousemappos.IsFinite()) {
awaitingMouseClick = true;
General.Interface.DisplayStatus(StatusType.Warning, "Now click in the editing area!");
return;
}
awaitingMouseClick = false;
// Make undo
if(selected.Count > 1) {
General.Map.UndoRedo.CreateUndo("Rotate " + selected.Count + " things");
@ -883,10 +894,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
//change angle
foreach(Thing t in selected){
ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type);
if(info == null || info.Category == null || info.Category.Arrow == 0) continue;
t.Rotate(Vector2D.GetAngle(mousemappos, t.Position));
if(General.Interface.CtrlState) { //point away
foreach(Thing t in selected) {
ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type);
if(info == null || info.Category == null || info.Category.Arrow == 0)
continue;
t.Rotate(Vector2D.GetAngle(mousemappos, t.Position) + (float)Math.PI);
}
} else { //point at
foreach(Thing t in selected) {
ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type);
if(info == null || info.Category == null || info.Category.Arrow == 0)
continue;
t.Rotate(Vector2D.GetAngle(mousemappos, t.Position));
}
}
// Update cache values

View file

@ -505,26 +505,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
//if(BuilderPlug.Me.AutoClearSelection && !selectionvolume)
//General.Map.Map.ClearSelectedVertices();
if(selectionvolume)
{
//mxd
if(subtractiveSelection) {
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected = selectionrect.Contains(v.Position.x, v.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected |= selectionrect.Contains(v.Position.x, v.Position.y);
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
if(selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
} else {
if(General.Interface.ShiftState ^ BuilderPlug.Me.AdditiveSelect) {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected |= selectionrect.Contains(v.Position.x, v.Position.y);
} else {
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
v.Selected = selectionrect.Contains(v.Position.x, v.Position.y);
}
} else { //should be Intersect
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
if(!selectionrect.Contains(v.Position.x, v.Position.y)) v.Selected = false;
}
}

View file

@ -115,7 +115,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
private bool autoAlignTextureOffsetsOnCreate;//mxd
private bool autoAlignTextureOffsetsOnDrag;//mxd
private bool dontMoveGeometryOutsideMapBoundary;//mxd
private int marqueSelectionMode; //mxd
private bool marqueSelectTouching; //mxd. Select elements partially/fully inside of marque selection?
private bool syncSelection; //mxd. Sync selection between Visual and Classic modes.
private bool objExportTextures; //mxd
@ -177,7 +176,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool AutoAlignTextureOffsetsOnCreate { get { return autoAlignTextureOffsetsOnCreate; } set { autoAlignTextureOffsetsOnCreate = value; } } //mxd
public bool AutoAlignTextureOffsetsOnDrag { get { return autoAlignTextureOffsetsOnDrag; } set { autoAlignTextureOffsetsOnDrag = value; } } //mxd
public bool DontMoveGeometryOutsideMapBoundary { get { return dontMoveGeometryOutsideMapBoundary; } set { DontMoveGeometryOutsideMapBoundary = value; } } //mxd
public int MarqueSelectionMode { get { return marqueSelectionMode; } set { marqueSelectionMode = value; } } //mxd
public bool MarqueSelectTouching { get { return marqueSelectTouching; } set { marqueSelectTouching = value; } } //mxd
public bool SyncSelection { get { return syncSelection; } set { syncSelection = value; } } //mxd
public bool ObjExportTextures { get { return objExportTextures; } internal set { objExportTextures = value; } } //mxd
@ -327,7 +325,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
autoAlignTextureOffsetsOnCreate = General.Settings.ReadPluginSetting("autoaligntextureoffsetsoncreate", true); //mxd
autoAlignTextureOffsetsOnDrag = General.Settings.ReadPluginSetting("autoaligntextureoffsetsondrag", true); //mxd
dontMoveGeometryOutsideMapBoundary = General.Settings.ReadPluginSetting("dontmovegeometryoutsidemapboundary", false); //mxd
marqueSelectionMode = General.Settings.ReadPluginSetting("marqueselectionmode", 1); //mxd
syncSelection = General.Settings.ReadPluginSetting("syncselection", false); //mxd
objExportTextures = General.Settings.ReadPluginSetting("objexporttextures", false); //mxd
objGZDoomScale = General.Settings.ReadPluginSetting("objgzdoomscale", false); //mxd

View file

@ -31,6 +31,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.tabs = new System.Windows.Forms.TabControl();
this.taboptions = new System.Windows.Forms.TabPage();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.syncSelection = new System.Windows.Forms.CheckBox();
this.dontMoveGeometryOutsideBounds = new System.Windows.Forms.CheckBox();
this.autoalignDraggedSidedefsOffsetX = new System.Windows.Forms.CheckBox();
this.autoaligntexturesoncreate = new System.Windows.Forms.CheckBox();
@ -50,13 +51,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.label4 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label11 = new System.Windows.Forms.Label();
this.marqueBehaviour = new System.Windows.Forms.ComboBox();
this.splitbehavior = new System.Windows.Forms.ComboBox();
this.label10 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.heightbysidedef = new System.Windows.Forms.ComboBox();
this.syncSelection = new System.Windows.Forms.CheckBox();
this.splitlinedefsrange = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
this.stitchrange = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
this.highlightthingsrange = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
@ -107,17 +105,27 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.groupBox3.Controls.Add(this.editnewthing);
this.groupBox3.Controls.Add(this.editnewsector);
this.groupBox3.Controls.Add(this.additiveselect);
this.groupBox3.Location = new System.Drawing.Point(284, 129);
this.groupBox3.Location = new System.Drawing.Point(284, 104);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(379, 262);
this.groupBox3.Size = new System.Drawing.Size(379, 287);
this.groupBox3.TabIndex = 18;
this.groupBox3.TabStop = false;
this.groupBox3.Text = " Options ";
//
// syncSelection
//
this.syncSelection.AutoSize = true;
this.syncSelection.Location = new System.Drawing.Point(13, 250);
this.syncSelection.Name = "syncSelection";
this.syncSelection.Size = new System.Drawing.Size(306, 18);
this.syncSelection.TabIndex = 10;
this.syncSelection.Text = "Synhcronise selection between Visual and Classic modes";
this.syncSelection.UseVisualStyleBackColor = true;
//
// dontMoveGeometryOutsideBounds
//
this.dontMoveGeometryOutsideBounds.AutoSize = true;
this.dontMoveGeometryOutsideBounds.Location = new System.Drawing.Point(13, 217);
this.dontMoveGeometryOutsideBounds.Location = new System.Drawing.Point(13, 225);
this.dontMoveGeometryOutsideBounds.Name = "dontMoveGeometryOutsideBounds";
this.dontMoveGeometryOutsideBounds.Size = new System.Drawing.Size(332, 18);
this.dontMoveGeometryOutsideBounds.TabIndex = 9;
@ -127,7 +135,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// autoalignDraggedSidedefsOffsetX
//
this.autoalignDraggedSidedefsOffsetX.AutoSize = true;
this.autoalignDraggedSidedefsOffsetX.Location = new System.Drawing.Point(13, 193);
this.autoalignDraggedSidedefsOffsetX.Location = new System.Drawing.Point(13, 200);
this.autoalignDraggedSidedefsOffsetX.Name = "autoalignDraggedSidedefsOffsetX";
this.autoalignDraggedSidedefsOffsetX.Size = new System.Drawing.Size(286, 18);
this.autoalignDraggedSidedefsOffsetX.TabIndex = 8;
@ -137,7 +145,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// autoaligntexturesoncreate
//
this.autoaligntexturesoncreate.AutoSize = true;
this.autoaligntexturesoncreate.Location = new System.Drawing.Point(13, 169);
this.autoaligntexturesoncreate.Location = new System.Drawing.Point(13, 175);
this.autoaligntexturesoncreate.Name = "autoaligntexturesoncreate";
this.autoaligntexturesoncreate.Size = new System.Drawing.Size(245, 18);
this.autoaligntexturesoncreate.TabIndex = 7;
@ -147,7 +155,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// autodragonpaste
//
this.autodragonpaste.AutoSize = true;
this.autodragonpaste.Location = new System.Drawing.Point(13, 145);
this.autodragonpaste.Location = new System.Drawing.Point(13, 150);
this.autodragonpaste.Name = "autodragonpaste";
this.autodragonpaste.Size = new System.Drawing.Size(205, 18);
this.autodragonpaste.TabIndex = 6;
@ -157,7 +165,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// visualmodeclearselection
//
this.visualmodeclearselection.AutoSize = true;
this.visualmodeclearselection.Location = new System.Drawing.Point(13, 121);
this.visualmodeclearselection.Location = new System.Drawing.Point(13, 125);
this.visualmodeclearselection.Name = "visualmodeclearselection";
this.visualmodeclearselection.Size = new System.Drawing.Size(220, 18);
this.visualmodeclearselection.TabIndex = 5;
@ -167,7 +175,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// autoclearselection
//
this.autoclearselection.AutoSize = true;
this.autoclearselection.Location = new System.Drawing.Point(13, 97);
this.autoclearselection.Location = new System.Drawing.Point(13, 100);
this.autoclearselection.Name = "autoclearselection";
this.autoclearselection.Size = new System.Drawing.Size(231, 18);
this.autoclearselection.TabIndex = 4;
@ -187,7 +195,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// editnewsector
//
this.editnewsector.AutoSize = true;
this.editnewsector.Location = new System.Drawing.Point(13, 49);
this.editnewsector.Location = new System.Drawing.Point(13, 50);
this.editnewsector.Name = "editnewsector";
this.editnewsector.Size = new System.Drawing.Size(271, 18);
this.editnewsector.TabIndex = 2;
@ -197,7 +205,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// additiveselect
//
this.additiveselect.AutoSize = true;
this.additiveselect.Location = new System.Drawing.Point(13, 73);
this.additiveselect.Location = new System.Drawing.Point(13, 75);
this.additiveselect.Name = "additiveselect";
this.additiveselect.Size = new System.Drawing.Size(211, 18);
this.additiveselect.TabIndex = 3;
@ -218,9 +226,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.groupBox2.Controls.Add(this.label6);
this.groupBox2.Controls.Add(this.label4);
this.groupBox2.Controls.Add(this.label7);
this.groupBox2.Location = new System.Drawing.Point(6, 129);
this.groupBox2.Location = new System.Drawing.Point(6, 104);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(272, 262);
this.groupBox2.Size = new System.Drawing.Size(272, 287);
this.groupBox2.TabIndex = 17;
this.groupBox2.TabStop = false;
this.groupBox2.Text = " Ranges ";
@ -303,44 +311,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
//
// groupBox1
//
this.groupBox1.Controls.Add(this.label11);
this.groupBox1.Controls.Add(this.marqueBehaviour);
this.groupBox1.Controls.Add(this.splitbehavior);
this.groupBox1.Controls.Add(this.label10);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.heightbysidedef);
this.groupBox1.Location = new System.Drawing.Point(6, 6);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(657, 117);
this.groupBox1.Size = new System.Drawing.Size(657, 92);
this.groupBox1.TabIndex = 16;
this.groupBox1.TabStop = false;
this.groupBox1.Text = " Behavior ";
//
// label11
//
this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(165, 91);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(159, 14);
this.label11.TabIndex = 4;
this.label11.Text = "Rectangular selection behavior:";
this.label11.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// marqueBehaviour
//
this.marqueBehaviour.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.marqueBehaviour.FormattingEnabled = true;
this.marqueBehaviour.Items.AddRange(new object[] {
"Always add to selection",
"Left to right adds, right to left removes from selection",
"Left to right removes, right to left adds to selection",
"Top to bottom adds, bottom to top removes from selection",
"Top to bottom removes, bottom to top adds to selection"});
this.marqueBehaviour.Location = new System.Drawing.Point(342, 88);
this.marqueBehaviour.Name = "marqueBehaviour";
this.marqueBehaviour.Size = new System.Drawing.Size(309, 22);
this.marqueBehaviour.TabIndex = 3;
//
// splitbehavior
//
this.splitbehavior.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@ -388,16 +369,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.heightbysidedef.Size = new System.Drawing.Size(309, 22);
this.heightbysidedef.TabIndex = 0;
//
// syncSelection
//
this.syncSelection.AutoSize = true;
this.syncSelection.Location = new System.Drawing.Point(13, 241);
this.syncSelection.Name = "syncSelection";
this.syncSelection.Size = new System.Drawing.Size(306, 18);
this.syncSelection.TabIndex = 10;
this.syncSelection.Text = "Synhcronise selection between Visual and Classic modes";
this.syncSelection.UseVisualStyleBackColor = true;
//
// splitlinedefsrange
//
this.splitlinedefsrange.AllowDecimal = false;
@ -502,8 +473,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
private System.Windows.Forms.CheckBox autoaligntexturesoncreate;
private System.Windows.Forms.CheckBox autoalignDraggedSidedefsOffsetX;
private System.Windows.Forms.CheckBox dontMoveGeometryOutsideBounds;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.ComboBox marqueBehaviour;
private System.Windows.Forms.CheckBox syncSelection;
}
}

View file

@ -71,7 +71,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
autoaligntexturesoncreate.Checked = BuilderPlug.Me.AutoAlignTextureOffsetsOnCreate; //mxd
autoalignDraggedSidedefsOffsetX.Checked = BuilderPlug.Me.AutoAlignTextureOffsetsOnDrag; //mxd
dontMoveGeometryOutsideBounds.Checked = BuilderPlug.Me.DontMoveGeometryOutsideMapBoundary; //mxd
marqueBehaviour.SelectedIndex = BuilderPlug.Me.MarqueSelectionMode; //mxd
syncSelection.Checked = BuilderPlug.Me.SyncSelection; //mxd
}
@ -98,7 +97,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Settings.WritePluginSetting("autoaligntextureoffsetsoncreate", autoaligntexturesoncreate.Checked);//mxd
General.Settings.WritePluginSetting("autoaligntextureoffsetsondrag", autoalignDraggedSidedefsOffsetX.Checked);//mxd
General.Settings.WritePluginSetting("dontmovegeometryoutsidemapboundary", dontMoveGeometryOutsideBounds.Checked);//mxd
General.Settings.WritePluginSetting("marqueselectionmode", marqueBehaviour.SelectedIndex);//mxd
General.Settings.WritePluginSetting("syncselection", syncSelection.Checked);//mxd
}

View file

@ -339,11 +339,12 @@ thinglookatcursor
{
title = "Point Thing to cursor";
category = "things";
description = "Points selected things to cursor position.";
description = "Points selected things to cursor position. Hold Ctrl to point away from cursor.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
default = 131148; //Ctrl-L
disregardcontrol = true;
default = 65612; //Shift-L
}
makesectormode

View file

@ -537,7 +537,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//move things...
if (!absolutePosition) { //...relatively (that's easy)
int camAngle = (int)Math.Round(General.Map.VisualCamera.AngleXY * 180 / Math.PI);
int sector = (int)(General.ClampAngle(camAngle - 45f) / 90f);
int sector = General.ClampAngle(camAngle - 45) / 90;
direction = direction.GetRotated((float)(sector * Math.PI / 2f));
for (int i = 0; i < coordinates.Length; i++)