/// <summary> /// Creates a new <c>DrawQuery</c> that refers to the specified feature type(s), /// drawing the results of the spatial query to the specified display. /// </summary> /// <param name="index">The index to query</param> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> /// <param name="types">The type(s) of spatial feature to draw</param> public DrawQuery(ISpatialIndex index, ISpatialDisplay display, IDrawStyle style, SpatialType types) { m_Display = display; m_Style = style; m_DoPaint = false; Timer t = new Timer(500); t.Elapsed += new ElapsedEventHandler(Timer_Elapsed); t.Start(); index.QueryWindow(m_Display.Extent, types, OnQueryHit); t.Close(); display.PaintNow(); }
public override void ShowContextMenu(ISpatialDisplay where, IPosition p) { ContextMenuStrip menu = null; if (m_Command != null) { menu = m_Command.CreateContextMenu(); } if (menu == null) { menu = m_Main.CreateContextMenu(this.SpatialSelection); } if (menu != null) { where.ShowContextMenu(p, menu); } }
internal void Draw() // was Paint { // Ensure nothing else is currently selected/highlighted. ISpatialDisplay view = m_Cmd.ActiveDisplay; //m_Cmd.ErasePainting(); // If we've got a terminal line, highlight it. if (m_Line != null) { m_Line.Render(view, new HighlightStyle()); } // And draw the terminal position on top of it. if (m_Terminal != null) { EditingController.Current.Style(Color.Yellow).Render(view, m_Terminal); } }
/// <summary> /// Repaint icon(s) representing this check result. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The style for the drawing</param> internal override void Render(ISpatialDisplay display, IDrawStyle style) { // Draw stuff that's now irrelevant RenderPaintOuts(display, style); // Return if the label has been de-activated. if (m_Label.IsInactive) { return; } // Remember the display position of the label (top left corner). IPosition p = m_Label.Position; Place = p; // Figure out a position that is a bit to the left (a bit bigger than an icon) double shift = GetIconSpacing(display); p = new Position(p.X - shift, p.Y); // Draw icon(s). CheckType types = Types; if ((types & CheckType.NoPolygonForLabel) != 0) { style.Render(display, p, Resources.CheckNoPolygonForLabelIcon); p = new Position(p.X - shift, p.Y); } if ((types & CheckType.NoAttributes) != 0) { style.Render(display, p, Resources.CheckNoAttributesIcon); p = new Position(p.X - shift, p.Y); } if ((types & CheckType.MultiLabel) != 0) { style.Render(display, p, Resources.CheckMultiLabelIcon); p = new Position(p.X - shift, p.Y); } }
/// <summary> /// Paints out those results that no longer apply. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The style for the drawing</param> /// <param name="newTypes">The new results</param> internal override void PaintOut(ISpatialDisplay display, IDrawStyle style, CheckType newTypes) { IPosition p = this.Place; double shift = IconSize(display); CheckType oldTypes = Types; // Shift a bit so the icon is a bit to the left of the reference position p = new Position(p.X - shift / 2, p.Y + shift / 2); // Any subsequent shifts will be a bit more shift *= 1.1; if (IsPaintOut(CheckType.SmallLine, oldTypes, newTypes)) { AddPaintOut(p, Resources.CheckSmallLineIcon); p = new Position(p.X - shift, p.Y); } if (IsPaintOut(CheckType.Dangle, oldTypes, newTypes)) { AddPaintOut(p, Resources.CheckDanglingIcon); p = new Position(p.X - shift, p.Y); } if (IsPaintOut(CheckType.Overlap, oldTypes, newTypes)) { AddPaintOut(p, Resources.CheckOverlapIcon); p = new Position(p.X - shift, p.Y); } if (IsPaintOut(CheckType.Floating, oldTypes, newTypes)) { AddPaintOut(p, Resources.CheckFloatingIcon); p = new Position(p.X - shift, p.Y); } if (IsPaintOut(CheckType.Bridge, oldTypes, newTypes)) { AddPaintOut(p, Resources.CheckBridgeIcon); p = new Position(p.X - shift, p.Y); } }
/// <summary> /// Sets color for a point. /// </summary> /// <param name="point">The point to draw.</param> /// <param name="c">The field that the point relates to. The default is /// the field that currently has the focus.</param> void SetColor(PointFeature point, Control c) { // Return if point not specified. if (point == null) { return; } ISpatialDisplay display = m_Command.ActiveDisplay; Control field = (c == null ? m_Focus : c); if (Object.ReferenceEquals(field, fromTextBox)) { point.Draw(display, Color.DarkBlue); } else if (Object.ReferenceEquals(field, toTextBox)) { point.Draw(display, Color.Cyan); } }
/// <summary> /// Ensures this style has a pen that is compatible with the supplied draw object. /// </summary> /// <param name="draw">The draw object</param> /// <returns>The corresponding pen</returns> internal ScaleSpecificPen GetPen(ISpatialDisplay draw) { if (IsScaleDependent) { if (m_Pen != null && m_Pen.IsCompatible(draw)) { return(m_Pen); } m_Pen = new ScaleSpecificPen(this, draw); return(m_Pen); } if (m_Pen == null) { m_Pen = new ScaleSpecificPen(this, draw); } return(m_Pen); }
/// <summary> /// Ensures a point is visible on the active display (expands the draw window /// if necessary), and optionally selects it. /// </summary> /// <param name="p">The point that needs to be shown.</param> /// <param name="select">Specify true if the point should be selected.</param> internal void EnsureVisible(PointFeature p, bool select) { // Ensure the draw window shows the point. ISpatialDisplay display = ActiveDisplay; IWindow drawExtent = display.Extent; if (drawExtent == null || drawExtent.IsEmpty) { display.DrawOverview(); } else if (!drawExtent.IsOverlap(p)) { display.Center = p; } // Select the point if requested if (select) { SetSelection(new Selection(p, p)); } }
/// <summary> /// Do any command-specific drawing. /// </summary> /// <param name="point">The specific point (if any) that the parent window has drawn. /// Not used.</param> internal override void Paint(PointFeature point) { if (m_LastPosition != null) { // Draw gray text in the original position ISpatialDisplay display = ActiveDisplay; m_Text.Draw(display, Color.Gray); // Draw the text at the last mouse position IPointGeometry p = m_Text.Position; try { m_Text.TextGeometry.Position = m_LastPosition; m_Text.Draw(display, Color.Red); } finally { m_Text.TextGeometry.Position = p; } } }
/// <summary> /// Defines the supplied pen with this style /// </summary> /// <param name="pen">The pen to define</param> /// <param name="draw">The definition of the draw</param> internal override void DefinePen(ScaleSpecificPen pen, ISpatialDisplay draw) { float fwt = (m_Weight > 0.0 ? draw.LengthToDisplay(m_Weight) : 0.0F); if (m_Pattern != null) { m_Pattern.DefinePen(pen.Pen, draw, fwt, new SolidBrush(this.Color)); } // MUST be solid for anything that has non-zero weight //else if ((int)fwt != 0) // pen.CreateSolidPen(fwt, this.Color); else { pen.CreateSolidPen(0.0F, this.Color); Pen p = pen.Pen; p.DashStyle = m_Style; p.Width = fwt; p.StartCap = LineCap.Round; p.EndCap = LineCap.Round; } }
/// <summary> /// Handles a key up event /// </summary> /// <param name="sender">The display where the key event originated</param> /// <param name="k">Information about the event</param> public override void KeyUp(ISpatialDisplay sender, KeyEventArgs k) { // Whereas Control.ModifierKeys sees Keys.Control, the KeyUp event passes Keys.ControlKey if (k.KeyCode == Keys.ControlKey && m_Sel != null) { // Grab the selected items (if any) and merge any currently selected features. Selection s = m_Sel.Selection; FreeAreaSelectionTool(); if (s.Count > 0) { s.AddRange(this.SpatialSelection.Items); SetSelection(s); } // Ensure everything is back to normal ActiveDisplay.RestoreLastDraw(); // Force any prior selection to show m_HasSelectionChanged = true; //ActiveDisplay.PaintNow(); } }
/// <summary> /// Checks the current map. /// </summary> /// <returns>The number of objects checked (-1 if the map currently has an /// active operation in progress).</returns> int CheckMap() { Debug.Assert(m_Status != null); // Reset current set of problems. KillResults(); // Return if the map has an active operation. CadastralMapModel map = CadastralMapModel.Current; if (map.IsCommittingEdit) { MessageBox.Show("Cannot make check because an edit appears to be in progress."); return(-1); } ISpatialDisplay display = EditingController.Current.ActiveDisplay; Control c = display.MapPanel; try { c.Cursor = Cursors.WaitCursor; FileCheckQuery check = new FileCheckQuery(map, m_Options, OnCheck); m_Results = check.Result; return(check.NumChecked); } catch (Exception e) { MessageBox.Show(e.Message); return(-1); } finally { c.Cursor = Cursors.Default; } }
/// <summary> /// Sees whether the orientation of the new text should be altered. This /// occurs if the auto-orient capability is enabled, and the specified /// position is close to any visible lne. /// </summary> /// <param name="posn">The position to use for making the check.</param> /// <returns></returns> LineFeature GetOrientation(IPointGeometry posn) { // The ground tolerance is 2mm at the draw scale. ISpatialDisplay display = ActiveDisplay; double tol = 0.002 * display.MapScale; // If we previously selected something, see if the search point // lies within tolerance. If so, there's no change. if (m_Orient != null) { double dist = m_Orient.Distance(posn).Meters; if (dist < tol) { return(m_Orient); } } // Get the map to find the closest line CadastralMapModel map = CadastralMapModel.Current; ISpatialIndex index = map.Index; return(index.QueryClosest(posn, new Length(tol), SpatialType.Line) as LineFeature); }
public override void MouseDown(ISpatialDisplay sender, IPosition p, MouseButtons b) { if (b == MouseButtons.Right) { ShowContextMenu(sender, p); } // If there's no command, or it doesn't handle left clicks... else if (m_Command == null || !m_Command.LButtonDown(p)) { bool isMultiSelect = (Control.ModifierKeys & Keys.Shift) != 0; // If we're currently auto-highlighting, and the user is doing // a multi-select, turn off auto-highlight and get rid of the // properties window (confusing). // TODO: May want to keep the properties window, but disabled. In the // past, it was ok to close because the dialog rested on top of the // map. Now, closing the property window causes a redraw, which is // a bit unexpected in the middle of a multiselect. if (isMultiSelect) { m_IsAutoSelect = 0; m_Main.ClosePropertiesWindow(); } if (m_Sel == null) { OnSelect(sender, p, isMultiSelect); } else { m_Sel.CtrlMouseDown(p); } } }
/// <summary> /// Draws sections on the specified display, excluding dangling ends. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> internal void RenderTrimmed(ISpatialDisplay display, IDrawStyle style) { // If we're highlighting, dangling portions should be drawn dotted IDrawStyle dangleStyle = (style is HighlightStyle ? new DottedStyle(Color.Red) : null); bool sDangle = Line.IsStartDangle(); bool eDangle = Line.IsEndDangle(); int last = m_Sections.Count - 1; for (int i = 0; i <= last; i++) { if ((i == 0 && !sDangle) || (i > 0 && i < last) || (i == last && !eDangle)) { IDivider d = m_Sections[i]; d.Line.RenderDivider(d, display, style); } else if (dangleStyle != null && ((i == 0 && sDangle) || (i == last && eDangle))) { IDivider d = m_Sections[i]; d.Line.RenderDivider(d, display, dangleStyle); } } }
public override void MouseMove(ISpatialDisplay sender, IPosition p, MouseButtons b) { if (m_Sel != null) // means the CTRL key is pressed { m_Sel.CtrlMouseMoveTo(p); } else { // The main window of the cadastral editor provides the option to // display the current position of the mouse m_Main.MouseMove(sender, p, b); // Auto-highlight option if (m_IsAutoSelect > 0) { Select(sender, p, SpatialType.All); } if (m_Command != null) { m_Command.MouseMove(p); } } }
/// <summary> /// Creates new <c>CommandUI</c> that isn't an update. /// </summary> /// <param name="cc">The container that may be used to display any sort of /// user dialog (null if no dialog is involved)</param> /// <param name="cmdId">The item used to invoke the command.</param> /// <param name="update">The object (if any) that was selected for update</param> /// <param name="recall">An operation that is being recalled (null if this is an update).</param> protected CommandUI(IControlContainer cc, IUserAction cmdId, ISpatialObject update, Operation recall) { m_Container = cc; m_Draw = EditingController.Current.ActiveDisplay; //m_Update = update; m_UpdCmd = null; m_Recall = recall; if (cmdId is EditingAction) { m_EditId = (cmdId as EditingAction).EditId; } else { m_EditId = EditingActionId.Null; } if (cmdId is RecalledEditingAction) { m_Recall = (cmdId as RecalledEditingAction).RecalledEdit; } Debug.Assert(m_Draw != null); }
/// <summary> /// Dialog-specific painting. /// </summary> internal void Draw() { // Draw the features originally created by the op in gray. ISpatialDisplay display = m_UpdCmd.ActiveDisplay; IDrawStyle style = m_UpdCmd.Controller.Style(Color.Gray); style.IsFixed = true; m_pop.Render(display, style, true); // Ensure the current face has up-to-date geometry and draw that using magenta draw style m_CurrentFace.CalculateGeometry(m_pop.Parent, null); style = m_UpdCmd.Controller.Style(Color.Magenta); style.IsFixed = true; foreach (LineFeature line in m_CurrentFace.Sections) { line.Render(display, style); } // Highlight the currently selected section (if any). if (m_SelectedLine != null) { m_SelectedLine.Render(display, new HighlightStyle()); } }
/// <summary> /// Tries to select something at the specified position /// </summary> /// <param name="p">The position where a left-click has occurred</param> /// <param name="isMultiSelect">True if performing a multi-select (SHIFT key is pressed)</param> void OnSelect(ISpatialDisplay display, IPosition p, bool isMultiSelect) { /* * // If importing from background, there's no way to select * // anything from the main map. * if (m_pGetBack) * { * m_pGetBack->OnSelect(point); * return; * } */ // Try to select something. ISpatialObject thing = SelectObject(display, p, SpatialType.All); if (thing != null) { // Caution: If we're auto-highlighting, and the thing // we've just selected is the thing that's already // selected, don't do ANYTHING (not even if the user // is apparently doing a multi-select). // Note that if the user IS doing a multi-select, any // auto-highlighting is supposed to go away automatically // (see OnLButtonDown && OnMouseMove). if (m_IsAutoSelect == 1 && Object.ReferenceEquals(thing, SpatialSelection.Item)) { return; } if (isMultiSelect) { // Add the thing to the selection (or remove it if // it's currently selected). AddOrRemoveFromSelection(thing); } else { SetSelection(new Selection(thing, p)); } } else { // Ensure the selection has been unhighlited & clear out the selection. if (!isMultiSelect) { ClearSelection(); // was m_Sel.RemoveSel(); } } // If we've now got a simple selection, notify any commands // that are running so that their stuff will draw on top // of the highlighting. //OnSelect(); // If we are doing an inverse dialog, make sure its point // coloring remains regardless of what is currently selected. if (m_Inverse != null) { m_Inverse.Draw(); } }
/// <summary> /// Perform any processing whenever a display has changed the drawn extent /// of a map. This saves the extent as part of the project settings. /// </summary> /// <param name="sender">The display that has changed</param> public override void OnSetExtent(ISpatialDisplay sender) { m_Project.Settings.LastDraw = new DrawInfo(sender.Extent, sender.MapScale); }
/// <summary> /// Creates a new <c>ScaleSpecificPen</c> /// </summary> /// <param name="style">The style that makes reference to this pen</param> /// <param name="draw">The drawing tool that holds the current scale</param> internal ScaleSpecificPen(Style style, ISpatialDisplay draw) { m_Pen = new Pen(Color.Black); m_Scale = (int)draw.MapScale; style.DefinePen(this, draw); }
/// <summary> /// Displays all ranges. /// </summary> /// <param name="win"></param> void ShowRanges(IWindow win) { // Erase whatever's currently in the list controlTextBox.Text = String.Empty; // Return if there are no ranges. if (m_Ranges.Count == 0) { return; } // If the map doesn't have a defined extent, we'll need to initialize // the display with the window we've got if (m_NewMap) { ISpatialDisplay display = m_Cmd.ActiveDisplay; display.ReplaceMapModel(win); // Tell the user the draw scale that has been defined, and ensure points are drawn // at that scale. ProjectSettings ps = EditingController.Current.Project.Settings; double scale = GetSensibleScale(display.MapScale); display.MapScale = scale; if (!m_Cmd.ArePointsDrawn()) { ps.ShowPointScale = (scale + 1); Debug.Assert(m_Cmd.ArePointsDrawn()); } // Ensure the point size isn't TOO small (2mm at the display scale should be fine) ps.PointHeight = 0.002 * scale; string scalemsg = String.Format("Draw scale has been set to 1:{0}", (uint)scale); MessageBox.Show(scalemsg); } // Only show the first 100 ranges (any more, and the string // might get too long to display). StringBuilder sb = new StringBuilder(1000); for (int i = 0; i < Math.Min(100, m_Ranges.Count); i++) { ControlRange r = m_Ranges[i]; // Get the range uint minkey = r.Min; uint maxkey = r.Max; // Form status string string status; int nfound = r.NumDefined; int ncontr = r.NumControl; if (nfound == ncontr) { if (nfound == 1) { status = "found"; } else { status = "all found"; } } else { status = String.Format("found {0} out of {1}", nfound, ncontr); } string output; if (minkey == maxkey) { output = String.Format("{0} ({1})", minkey, status); } else { output = String.Format("{0}-{1} ({2})", minkey, maxkey, status); } sb.Append(output); sb.Append(System.Environment.NewLine); } controlTextBox.Text = sb.ToString(); // Message if all the ranges could not be shown. if (m_Ranges.Count > 100) { string msg = String.Format("Only the first 100 ranges (of {0}) have been listed.", m_Ranges.Count); MessageBox.Show(msg); } }
/// <summary> /// Draws intersection points /// </summary> /// <param name="display">The display to draw to</param> internal void DrawIntersections(ISpatialDisplay display) { IDrawStyle style = EditingController.Current.DrawStyle; style.FillColor = Color.Transparent; new DrawQuery(m_ExtraData, display, style, SpatialType.Point); }
public void Render(ISpatialDisplay display, IDrawStyle style) { style.Render(display, this); }
public override void MouseMove(ISpatialDisplay sender, IPosition p, MouseButtons b) { if (m_Sel != null) // means the CTRL key is pressed { m_Sel.CtrlMouseMoveTo(p); } else { // The main window of the cadastral editor provides the option to // display the current position of the mouse m_Main.MouseMove(sender, p, b); // Auto-highlight option if (m_IsAutoSelect > 0) Select(sender, p, SpatialType.All); if (m_Command != null) m_Command.MouseMove(p); } }
public virtual void MouseUp(ISpatialDisplay sender, IPosition p, MouseButtons b) { }
public virtual void MouseDown(ISpatialDisplay sender, IPosition p, MouseButtons b) { if (b==MouseButtons.Right) ShowContextMenu(sender, p); else Select(sender, p, SpatialType.All); }
/// <summary> /// Handles a mouse double click event. This implementation does nothing. /// </summary> /// <param name="sender">The display where the mouse event originated</param> /// <param name="p">The position where the mouse click occurred</param> public virtual void MouseDoubleClick(ISpatialDisplay sender, IPosition p) { }
public virtual void KeyUp(ISpatialDisplay sender, KeyEventArgs k) { }
/// <summary> /// Perform any processing whenever a display has changed the drawn extent /// of a map. This implementation does nothing, derived classes may override. /// </summary> /// <param name="sender">The display that has changed</param> public virtual void OnSetExtent(ISpatialDisplay sender) { // do nothing }
public virtual void KeyUp(ISpatialDisplay sender, KeyEventArgs k) { }
/// <summary> /// Draws a distance alongside this line. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> /// <param name="dist">The observed distance (if any).</param> /// <param name="drawObserved">Draw observed distance? Specify <c>false</c> for /// actual distance.</param> internal override void RenderDistance(ISpatialDisplay display, IDrawStyle style, Distance dist, bool drawObserved) { Make().RenderDistance(display, style, dist, drawObserved); }
// Called by ViewController.MouseMove internal void OnMouseMove(ISpatialDisplay sender, IPosition p, System.Windows.Forms.MouseButtons b) { positionLabel.Text = String.Format("{0:0.000}E, {1:0.000}N", p.X, p.Y); if (mnuViewAutoSelect.Checked) m_Controller.Select(sender, p, SpatialType.Feature); }
/// <summary> /// Perform any processing whenever a display has changed the drawn extent /// of a map. This implementation does nothing, derived classes may override. /// </summary> /// <param name="sender">The display that has changed</param> public virtual void OnSetExtent(ISpatialDisplay sender) { // do nothing }
public override void ShowContextMenu(ISpatialDisplay where, IPosition p) { ContextMenuStrip menu = null; if (m_Command != null) menu = m_Command.CreateContextMenu(); if (menu==null) menu = m_Main.CreateContextMenu(this.SpatialSelection); if (menu!=null) where.ShowContextMenu(p, menu); }
public void Register(ISpatialDisplay display) { if (!m_Displays.Contains(display)) m_Displays.Add(display); // Redraw the display now (ensures the background has the expected colour) //display.Redraw(); }
/// <summary> /// Draws sections on the specified display, excluding dangling ends. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> internal void RenderTrimmed(ISpatialDisplay display, IDrawStyle style) { // If we're highlighting, dangling portions should be drawn dotted IDrawStyle dangleStyle = (style is HighlightStyle ? new DottedStyle(Color.Red) : null); bool sDangle = Line.IsStartDangle(); bool eDangle = Line.IsEndDangle(); int last = m_Sections.Count-1; for (int i=0; i<=last; i++) { if ((i==0 && !sDangle) || (i>0 && i<last) || (i==last && !eDangle)) { IDivider d = m_Sections[i]; d.Line.RenderDivider(d, display, style); } else if (dangleStyle!=null && ((i==0 && sDangle) || (i==last && eDangle))) { IDivider d = m_Sections[i]; d.Line.RenderDivider(d, display, dangleStyle); } } }
public virtual void Select(ISpatialDisplay display, IPosition p, SpatialType spatialType) { if (m_Data==null) return; // Use a tolerance of 2mm at the map scale of the supplied display ILength size = new Length(0.002 * display.MapScale); ISpatialObject so = m_Data.QueryClosest(p, size, spatialType); SetSelection(new SpatialSelection(so)); }
/// <summary> /// Draws the features that were created by this editing operation /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> /// <param name="drawInactive">Should features that are currently inactive be drawn too?</param> internal void Render(ISpatialDisplay display, IDrawStyle style, bool drawInactive) { foreach (Feature f in this.Features) { if (!drawInactive && f.IsInactive) continue; f.Render(display, style); } }
/// <summary> /// Placeholder that displays a context menu. This implementation does nothing, since /// the relevant context menu depends on the functionality provided by the application /// that utilizes this controller. Derived classes (ones that know something about the /// application) are expected to override. /// </summary> /// <param name="where">The display where the context menu should appear</param> /// <param name="p">The preferred position for the menu (may not be honoured if /// the context menu would be obscured)</param> public virtual void ShowContextMenu(ISpatialDisplay where, IPosition p) { }
/// <summary> /// Is this pen compatible with the supplied draw object? /// </summary> /// <param name="draw">The draw to check</param> /// <returns>True if the specified draw has the same scale as this pen</returns> internal bool IsCompatible(ISpatialDisplay draw) { return ((int)draw.MapScale == m_Scale); }
/// <summary> /// Creates a context menu by getting the application's main window to display a /// context menu that is appropriate for the current selection (if any). /// This overrides the do-nothing implementation provided by <c>SpatialController</c>. /// </summary> /// <param name="where">The display where the context menu should appear</param> /// <param name="p">The preferred position for the menu (may not be honoured if /// the context menu would be obscured)</param> public override void ShowContextMenu(ISpatialDisplay where, IPosition p) { ContextMenuStrip menu = m_Main.CreateContextMenu(SpatialSelection); where.ShowContextMenu(p, menu); }
/// <summary> /// Handles a mouse double click event by attempting to select a spatial object /// at the supplied position. If the resultant selection refers to just one object, /// it will be processed with <see cref="RunUpdate"/>. /// </summary> /// <param name="sender">The display where the mouse event originated</param> /// <param name="p">The position where the mouse click occurred</param> public override void MouseDoubleClick(ISpatialDisplay sender, IPosition p) { // Attempt to select something OnSelect(sender, p, false); // Update the selected item ISpatialSelection ss = SpatialSelection; RunUpdate(null, ss.Item); }
/// <summary> /// Perform any processing whenever a display has changed the drawn extent /// of a map. This saves the extent as part of the project settings. /// </summary> /// <param name="sender">The display that has changed</param> public override void OnSetExtent(ISpatialDisplay sender) { m_Project.Settings.LastDraw = new DrawInfo(sender.Extent, sender.MapScale); }
public override void Select(ISpatialDisplay display, IPosition p, SpatialType spatialType) { ISpatialObject so = SelectObject(display, p, spatialType); if (so!=null) SetSelection(new Selection(so, p)); else SetSelection(null); }
private ISpatialObject SelectObject(ISpatialDisplay display, IPosition p, SpatialType spatialType) { ProjectSettings ps = m_Project.Settings; CadastralMapModel cmm = this.CadastralMapModel; ISpatialSelection currentSel = this.SpatialSelection; ISpatialObject oldItem = currentSel.Item; ISpatialObject newItem; // Try to find a point feature if points are drawn. if ((spatialType & SpatialType.Point) != 0 && display.MapScale <= ps.ShowPointScale) { ILength size = new Length(ps.PointHeight * 0.5); newItem = cmm.QueryClosest(p, size, SpatialType.Point); if (newItem != null) { return(newItem); } } // If we are adding a line, don't bother trying to select // lines or polygons or text. /* * if (m_Op==ID_LINE_NEW || m_Op==ID_LINE_CURVE) * return 0; */ ILength tol = new Length(0.001 * display.MapScale); // Try to find a line, using a tolerance of 1mm at the draw scale. if ((spatialType & SpatialType.Line) != 0) { // If we previously selected something, see if the search point // lies within tolerance. If so, just return with what we've already got // ...just make the query (the issue here has to do with special highlighting // for topological sections -- if you point at another section of a line, the // highlighting doesn't move). // if (oldItem!=null && oldItem.SpatialType==SpatialType.Line) // { // ILength dist = oldItem.Distance(p); // if (dist.Meters < tol.Meters) // return; // } newItem = cmm.QueryClosest(p, tol, SpatialType.Line); if (newItem != null) { return(newItem); } } // Try for a text string if text is drawn. // The old software handles text by checking that the point is inside // the outline, not sure whether the new index provides acceptable alternative. if ((spatialType & SpatialType.Text) != 0 && display.MapScale <= ps.ShowLabelScale) { newItem = cmm.QueryClosest(p, tol, SpatialType.Text); if (newItem != null) { return(newItem); } } // Just return if a command dialog is up, // since selecting a polygon is distracting at that stage // (really, this applies to things like intersect commands). // There MIGHT be cases at some later date where we really // do want to select pols... // For updates, allow polygon selection if (IsCommandRunning && !(m_Command is UpdateUI)) { return(null); } if ((spatialType & SpatialType.Polygon) != 0) { // If we currently have a selected polygon, see if we're still inside it. /* * if (oldItem is Polygon) * { * Polygon oldPol = (oldItem is Polygon); * if (oldPol.IsEnclosing(p)) * * } */ IPointGeometry pg = PointGeometry.Create(p); ISpatialIndex index = cmm.Index; Polygon pol = new FindPointContainerQuery(index, pg).Result; if (pol != null) { return(pol); } } return(null); }
/// <summary> /// Redraws any check icons. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The style for the drawing</param> internal void Render(ISpatialDisplay display, IDrawStyle style) { if (m_Results==null) return; foreach (CheckItem check in m_Results) check.Render(display, style); // Tell the status window too. if (m_Status!=null) m_Status.Render(display, style); }
internal override void Render(ISpatialDisplay display, IDrawStyle style) { Make().Render(display, style); }
public static void Render(ICircleGeometry g, ISpatialDisplay display, IDrawStyle style) { style.Render(display, g.Center, g.Radius); }
/// <summary> /// Draws the new line based on currently entered data. This is called by the /// <c>base.Paint</c> method. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing style</param> internal override void RenderGeometry(ISpatialDisplay display, IDrawStyle style) { // The supplied style is a solid magenta line, which doesn't show up well // on top of a dotted magenta circle. So make it a bit thicker. if (m_Geom!=null) { DrawStyle thickStyle = new DrawStyle(style.LineColor); thickStyle.Pen.Width = 3.0f; m_Geom.Render(display, thickStyle); } }
/// <summary> /// Reacts to selection of the OK button in the dialog. /// </summary> /// <param name="wnd">The dialog window. If this matches the dialog that /// this command knows about, the command will be executed (and, on success, /// the dialog will be destroyed). If it's some other window, it must /// be a sub-dialog created by our guy, so let it handle the request.</param> /// <returns>True if command finished ok</returns> internal override bool DialFinish(Control wnd) { // If it's the offset dialog that's just finished, grab info // from it, delete it, and go to the dialog for the first // terminal line. ISpatialDisplay view = ActiveDisplay; UpdateUI up = this.Update; if (m_ParDial != null) { // Get info from dialog (it'll be ONE of the two). The dialog // should only call this function after validating that one // of them is defined. m_OffsetPoint = m_ParDial.OffsetPoint; if (m_OffsetPoint == null) { m_Offset = m_ParDial.OffsetDistance; } // Destroy the dialog. KillDialogs(); // Calculate the positions for the parallel points. Calculate(); // Repaint what we know about. Draw(); // And start the dialog for the first terminal line. if (up != null) { m_TermDial1 = new TerminalControl(up, false); } else { m_TermDial1 = new TerminalControl(this, false); } //m_TermDial1.Show(); this.Container.Display(m_TermDial1); return(true); } if (m_TermDial1 != null) { // Get the first terminal line (if any). And the position. m_TermLine1 = m_TermDial1.TerminalLine; m_Term1 = m_TermDial1.TerminalPosition; // And move on to the 2nd terminal dialog. KillDialogs(); // Repaint what we know about. Draw(); // And start the dialog for the first terminal line. if (up != null) { m_TermDial2 = new TerminalControl(up, true); } else { m_TermDial2 = new TerminalControl(this, true); } this.Container.Display(m_TermDial2); //m_TermDial2.Show(); return(true); } if (m_TermDial2 == null) { throw new Exception("ParallelLineUI.DialFinish - No dialog!"); } // Get the nortthern terminal line (if any). And the position. m_TermLine2 = m_TermDial2.TerminalLine; m_Term2 = m_TermDial2.TerminalPosition; // Erase everything special that we've drawn. ErasePainting(); // And ensure the view has nothing selected (sometimes the line // last selected had been unhighlighted, although it's end points // stay highlighted for some reason). EditingController.Current.ClearSelection(); // If we are doing an update, remember the changes if (up != null) { // Get the original operation. ParallelLineOperation op = (ParallelLineOperation)up.GetOp(); if (op == null) { throw new Exception("ParallelLineUI.DialFinish - Unexpected edit type."); } // Note the offset (it SHOULD be defined) Observation offset = null; if (m_Offset != null) { offset = m_Offset; } else if (m_OffsetPoint != null) { offset = new OffsetPoint(m_OffsetPoint); } Debug.Assert(offset != null); // Remember the changes as part of the UI object (the original edit remains // unchanged for now) UpdateItemCollection changes = op.GetUpdateItems(m_Line, offset, m_TermLine1, m_TermLine2, m_IsReversed); if (!up.AddUpdate(op, changes)) { return(false); } } else { Observation offset = m_Offset; if (offset == null && m_OffsetPoint != null) { offset = new OffsetPoint(m_OffsetPoint); } Debug.Assert(offset != null); // Execute the edit ParallelLineOperation op = null; try { op = new ParallelLineOperation(m_Line, offset, m_TermLine1, m_TermLine2, m_IsReversed); op.Execute(); } catch (Exception ex) { MessageBox.Show(ex.StackTrace, ex.Message); return(false); } } // Destroy the dialog(s). KillDialogs(); // Get the base class to finish up. return(FinishCommand()); }
/// <summary> /// Draws the outline of all child nodes (if the child is also an /// instance of <see cref="IndexNode"/>, this will just cause further /// drilldown - something will only get drawn if the child is an /// instance of some other class). /// </summary> /// <param name="display">The display to draw to.</param> /// <param name="style">The style for the draw.</param> internal override void Render(ISpatialDisplay display, IDrawStyle style) { foreach (Node n in m_Children) n.Render(display, style); }
public void Render(ISpatialDisplay display, IDrawStyle style) { CircleGeometry.Render(this, display, style); }
// Called by EditingController internal new void MouseMove(ISpatialDisplay sender, IPosition p, System.Windows.Forms.MouseButtons b) { if (positionLabel.Visible) positionLabel.Text = String.Format("{0:0.000}N, {1:0.000}E", p.Y, p.X); }
/// <summary> /// Draws the extent of the nodes in this index (excluding the higher level nodes). /// For experimentation. /// </summary> /// <param name="display">The display to draw to</param> /// <param name="style">The drawing tools to use</param> internal void Render(ISpatialDisplay display, IDrawStyle style) { m_Root.Render(display, style); }
/// <summary> /// The diagonal length of a line that spans the display when it is /// drawn at the overview scale. /// </summary> /// <param name="display"></param> /// <returns></returns> double GetMaxDiagonal(ISpatialDisplay display) { IWindow x = display.MaxExtent; return(Geom.Distance(x.Min, x.Max)); }
public void Unregister(ISpatialDisplay display) { m_Displays.Remove(display); }
public override void MouseDown(ISpatialDisplay sender, IPosition p, MouseButtons b) { if (b == MouseButtons.Right) ShowContextMenu(sender, p); // If there's no command, or it doesn't handle left clicks... else if (m_Command == null || !m_Command.LButtonDown(p)) { bool isMultiSelect = (Control.ModifierKeys & Keys.Shift) != 0; // If we're currently auto-highlighting, and the user is doing // a multi-select, turn off auto-highlight and get rid of the // properties window (confusing). // TODO: May want to keep the properties window, but disabled. In the // past, it was ok to close because the dialog rested on top of the // map. Now, closing the property window causes a redraw, which is // a bit unexpected in the middle of a multiselect. if (isMultiSelect) { m_IsAutoSelect = 0; m_Main.ClosePropertiesWindow(); } if (m_Sel==null) OnSelect(sender, p, isMultiSelect); else m_Sel.CtrlMouseDown(p); } }
/// <summary> /// Override calls <c>SpatialController.MouseMove</c>, and additionally tells /// the application's main window (the main window may also need to display the /// current mouse position). /// </summary> /// <param name="sender"></param> /// <param name="p"></param> /// <param name="b"></param> public override void MouseMove(ISpatialDisplay sender, IPosition p, System.Windows.Forms.MouseButtons b) { m_Main.OnMouseMove(sender, p, b); base.MouseMove(sender, p, b); }
/// <summary> /// Draws the current state of the edit /// </summary> internal void Draw() { Debug.Assert(m_Line != null); ISpatialDisplay view = ActiveDisplay; // Figure out the positions for the ends of the parallel line (if any) ... // Assume we already know both terminals. IPosition start = m_Term1; IPosition end = m_Term2; // If either one is undefined, but a dialog for it is active, // try to get the terminal from there instead. if (m_TermDial1 != null && start == null) { start = m_TermDial1.TerminalPosition; } if (m_TermDial2 != null && end == null) { end = m_TermDial2.TerminalPosition; } // If they weren't actually defined, use the parallel points instead. if (start == null) { start = m_Par1; } if (end == null) { end = m_Par2; } // If those weren't defined either, try to calculate them now. if (end == null && Calculate()) { start = m_Par1; end = m_Par2; } // Any offset point if (m_OffsetPoint != null) { m_OffsetPoint.Draw(view, Color.Green); } // Everything else should draw in usual command-style colour. IDrawStyle style = EditingController.Current.Style(Color.Magenta); IDrawStyle dottedStyle = new DottedStyle(); // If the reference line is a curve, get the curve info. ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { bool iscw = arc.IsClockwise; // Reverse the direction if necessary. if (m_IsReversed) { iscw = !iscw; } // Draw the parallel line (the rest of the circle being dotted). if (start != null) { CircularArcGeometry parArc = new CircularArcGeometry(arc.Circle, start, end, iscw); style.Render(view, parArc); parArc.IsClockwise = !parArc.IsClockwise; dottedStyle.Render(view, parArc); } } else { // PARALLEL IS STRAIGHT // If we've got something, figure out positions for dotted portion. if (start != null) { // What's the max length of a diagonal crossing the entire screen? double maxdiag = this.MaxDiagonal; // What's the bearing from the start to the end of the parallel? double bearing = Geom.BearingInRadians(start, end); // Project to a point before the start end of the parallel, as // well as a point after the end. IPosition before = Geom.Polar(start, bearing + Constants.PI, maxdiag); IPosition after = Geom.Polar(end, bearing, maxdiag); LineSegmentGeometry.Render(before, start, view, dottedStyle); LineSegmentGeometry.Render(start, end, view, style); LineSegmentGeometry.Render(end, after, view, dottedStyle); } } // Draw terminal positions (if defined). if (m_Term1 != null) { style.Render(view, m_Term1); } if (m_Term2 != null) { style.Render(view, m_Term2); } // The terminal lines. if (m_TermLine1 != null) { m_TermLine1.Render(view, style); } if (m_TermLine2 != null) { m_TermLine2.Render(view, style); } // Do the active dialog last so their stuff draws on top. if (m_ParDial != null) { m_ParDial.Draw(); } if (m_TermDial1 != null) { m_TermDial1.Draw(); } if (m_TermDial2 != null) { m_TermDial2.Draw(); } }