/// <summary>Deletes the specified node.</summary> /// <param name="nodePath">The node path.</param> public void Delete(string nodePath) { TreeIter node = FindNode(nodePath); // We will typically be deleting the currently selected node. If this is the case, // Gtk will not automatically move the cursor for us. // We need to work out where we want selection to be after this node is deleted TreePath cursorPath; TreeViewColumn cursorCol; treeview1.GetCursor(out cursorPath, out cursorCol); TreeIter nextSel = node; TreePath pathToSelect = treemodel.GetPath(node); if (pathToSelect.Compare(cursorPath) != 0) { pathToSelect = null; } else if (!treemodel.IterNext(ref nextSel)) // If there's a "next" sibling, the current TreePath will do { // Otherwise if (!pathToSelect.Prev()) // If there's a "previous" sibling, use that { pathToSelect.Up(); // and if that didn't work, use the parent } } treemodel.Remove(ref node); if (pathToSelect != null) { treeview1.SetCursor(pathToSelect, treeview1.GetColumn(0), false); } }
public override bool PathIsSelected(TreePath path) { if (path != null && selected_path != null) { return(path.Compare(selected_path) == 0); } return(false); }
private void DrawCell(TreePath path, GridViewColumn col, Rectangle clip) { Widget w; Rectangle rect = CellRect(path, col, out w); if (!clip.Intersect(rect, out clip)) { return; } CellRendererState crs = 0; if (w != fda) { w.GdkWindow.DrawRectangle(w.Style.MidGC(w.State), true, rect); } else { TreePath spath; GridViewColumn scol; selection.GetSelected(out spath, out scol); if (spath != null && path.Compare(spath) == 0 && col == scol) { crs = CellRendererState.Selected; Style.PaintFlatBox(w.Style, w.GdkWindow, StateType.Selected, ShadowType.None, clip, this, "cell_odd", rect.X, rect.Y, rect.Width, rect.Height); } } w.GdkWindow.DrawLine(w.Style.BackgroundGC(w.State), rect.X, rect.Bottom - 1, rect.Right, rect.Bottom - 1); w.GdkWindow.DrawLine(w.Style.BackgroundGC(w.State), rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom); TreeIter i; bool header = path.Indices[0] < c_span; CellRenderer renderer = header && col.HeaderRenderer != null ? col.HeaderRenderer : col.FieldRenderer; model.GetIter(out i, path); col.CellSetCellData(model, i, header); renderer.Render(w.GdkWindow, this, rect, rect, clip, crs); }
/* private methods */ private bool SelectPointHelper(int x, int y, bool select) { TreeIter iter = TreeIter.Zero; if (!GetPointNear(x, y, out iter)) { return(false); } TreePath path = model.GetPath(iter); // always focus focused_path = path.Copy(); if (select) { // fire SelectionChanged if the // selection has actually // changed if (selected_path == null || path.Compare(selected_path) != 0) { selected_path = path.Copy(); if (SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } } } else { // deselect if we previously // had a selection if (selected_path != null) { selected_path = null; if (SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } } } // always fire PointActivated if (PointActivated != null) { PointActivated(this, model, iter); } return(true); }
/// <summary>Deletes the specified node.</summary> /// <param name="nodePath">The node path.</param> public void Delete(string nodePath) { TreeIter node = FindNode(nodePath); if (node.Equals(TreeIter.Zero)) { return; } // We will typically be deleting the currently selected node. If this is the case, // Gtk will not automatically move the cursor for us. // We need to work out where we want selection to be after this node is deleted TreePath cursorPath; TreeViewColumn cursorCol; treeview1.GetCursor(out cursorPath, out cursorCol); TreeIter nextSel = node; TreePath pathToSelect = treemodel.GetPath(node); if (pathToSelect.Compare(cursorPath) != 0) { pathToSelect = null; } else if (treemodel.IterNext(ref nextSel)) // If there's a "next" sibling, the current TreePath will do { pathToSelect = treemodel.GetPath(nextSel); } else { // Otherwise if (!pathToSelect.Prev()) // If there's a "previous" sibling, use that { pathToSelect.Up(); // and if that didn't work, use the parent } } // Note: gtk_tree_store_remove() seems quite slow if the node being // deleted is selected. Therefore, we select the next node *before* // deleting the specified node. if (pathToSelect != null) { treeview1.SetCursor(pathToSelect, treeview1.GetColumn(0), false); } treemodel.Remove(ref node); }
protected virtual int HandleSort(TreeModel model, TreeIter a, TreeIter b) { if (a.Equals(TreeIter.Zero) && b.Equals(TreeIter.Zero)) { return(0); } else if (a.Equals(TreeIter.Zero)) { return(-1); } else if (b.Equals(TreeIter.Zero)) { return(1); } TreePath pathA = model.GetPath(a); TreePath pathB = model.GetPath(b); return(pathA.Compare(pathB)); }
public override void FocusIter(TreeIter iter) { if (!CanFocus) { return; } TreePath path = model.GetPath(iter); if (focused_path != null && path.Compare(focused_path) == 0) { return; } focused_path = path; if (Changed != null) { Changed(this, new EventArgs()); } }
public override void SelectIter(TreeIter iter) { TreePath path = model.GetPath(iter); if (selected_path != null && path.Compare(selected_path) == 0) { return; } selected_path = path; if (Changed != null) { Changed(this, new EventArgs()); } if (SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } }
private void OnDataRowDeleted(object o, RowDeletedArgs args) { if (model == null || args.Path == null) { return; } bool sel_paths_changed = false; // Don't update the real n_cells, as doing this will // throw off ScrollToPath if called before SizeAllocate // is run int n_cells = model.IterNChildren(); for (int i = 0; i < selected_paths.Count; i++) { TreePath path = (TreePath)selected_paths[i]; int cmp = path.Compare(args.Path); if (cmp == 0) { selected_paths.RemoveAt(i); i--; sel_paths_changed = true; continue; } // decrement each path that follows the one we // just deleted if (cmp > 0) { path.Prev(); selected_paths[i] = path; continue; } } if (sel_paths_changed && SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } if (focused_path != null && focused_path.Equals(args.Path)) { focused_path = focused_path.Copy(); // try to advance the focus forward focused_path.Next(); if (!PathIsValid(focused_path, n_cells) && !focused_path.Prev()) { focused_path = null; } } if (selection_anchor != null && selection_anchor.Equals(args.Path)) { selection_anchor = null; } QueueResize(); }
/// <summary>Checks whether two path are equal. They are considered equal if they have the same indice.</summary> public static bool PathsAreEqual(TreePath path1, TreePath path2) { return(path1.Compare(path2) == 0); }
private void FocusHelper(bool move_next) { if (focused_path == null) { return; } TreeIter focused_iter; if (!model.GetIter(out focused_iter, focused_path)) { return; } int focus_x, focus_y; GetPlotPoint(focused_iter, out focus_x, out focus_y); // we can't just do focused_path.Prev () since there is // a disconnect between the order in the model and // where the axis has us place points. besides, we // need to clamp the focus region to the zoom rect. TreeIter iter; if (!model.GetIterFirst(out iter)) { return; } int total_height = (Allocation.Y + Allocation.Height); TreePath min_path = null; int min_x_delta = Int32.MaxValue; int min_y_delta = Int32.MaxValue; do { TreePath path = model.GetPath(iter); // don't try to focus the same point again if (path.Compare(focused_path) == 0) { continue; } int x, y; GetPlotPoint(iter, out x, out y); // if its out of bounds, throw it out if (IsBarOutOfBounds(x, y)) { continue; } int x_delta = 0, y_delta = 0; if (move_next) { // find the bar with the smallest positive x // delta, and smallest y, or if there // is a tie, the one that's larger on the y // axis x_delta = x - focus_x; y_delta = (focus_x != x) ? total_height - y : focus_y - y; } else { // find the bar with the smallest positive x // delta, and largest y, or if there // is a tie, the one that's larger on the y // axis x_delta = focus_x - x; y_delta = (focus_x != x) ? y : y - focus_y; } // don't go backward, and don't pick a bigger // delta than we already have if (x_delta < 0 || x_delta > min_x_delta) { continue; } if (x_delta == min_x_delta && y_delta >= min_y_delta) { continue; } // if we're at the same X value, make sure // we're moving forward in the y direction so // we don't get stuck in loops if (x_delta == 0 && y_delta < 0) { continue; } min_x_delta = x_delta; min_y_delta = y_delta; min_path = path; } while (model.IterNext(ref iter)); if (min_path != null) { focused_path = min_path; } else { if (move_next) { focused_path = TreePath.NewFirst(); } else { focused_path = new TreePath(new int[] { model.IterNChildren() - 1 }); } } if (Changed != null) { Changed(this, new EventArgs()); } }
public void FocusPrev() { if (!has_focus || focused_plots.Count == 0) { return; } // get the focused value for the first plot LinePlot focus_plot = (LinePlot)focused_plots[0]; TreeModel model; TreeIter focus_iter; if (!focus_plot.GetFocused(out model, out focus_iter)) { return; } if (x_axis == null || y_axis == null) { return; } int focus_x, focus_y; GetPlotPoint(focus_plot, focus_iter, out focus_x, out focus_y); // scour the rest of the plots, searching for values // with a small (negative) delta to min_x int min_delta = Int32.MaxValue; ArrayList min_delta_plots = new ArrayList(); ArrayList min_delta_iters = new ArrayList(); foreach (LinePlot plot in plots) { TreeIter iter; if (!plot.Model.GetIterFirst(out iter)) { break; } TreeModel plot_model; TreePath plot_focus_path = null; TreeIter plot_focus_iter = TreeIter.Zero; if (plot.HasFocus && plot.GetFocused(out plot_model, out plot_focus_iter)) { plot_focus_path = model.GetPath(plot_focus_iter); } TreeIter prev_iter = TreeIter.Zero; do { TreePath path = plot.Model.GetPath(iter); int x, y; if (!GetPlotPoint(plot, iter, out x, out y)) { continue; } // stop when we hit the currently // focused point, if we had focus if (plot_focus_path != null) { if (path.Compare(plot_focus_path) == 0) { break; } } else if (x >= focus_x) { // or stop when we've hit // focus_x, or the nearest // point to it break; } prev_iter = iter; } while (plot.Model.IterNext(ref iter)); // point must have been the first one if (prev_iter.Equals(TreeIter.Zero)) { continue; } // now, we're at the point right before the // last focused point, so find the minimal x // delta int prev_x, prev_y; GetPlotPoint(plot, prev_iter, out prev_x, out prev_y); int delta = focus_x - prev_x; if (delta > min_delta) { continue; } if (delta < min_delta) { min_delta_plots.Clear(); min_delta_iters.Clear(); } min_delta = delta; min_delta_plots.Add(plot); min_delta_iters.Add(prev_iter); } if (min_delta_plots.Count == 0) { FocusLast(); return; } FocusIters(min_delta_plots, min_delta_iters); }
// XXX: this code assumes that the model is sorted public void FocusNext() { if (!has_focus || focused_plots.Count == 0) { return; } // get the focused value for the first plot LinePlot focus_plot = (LinePlot)focused_plots[0]; TreeModel model; TreeIter focus_iter; if (!focus_plot.GetFocused(out model, out focus_iter)) { return; } if (x_axis == null || y_axis == null) { return; } int focus_x, focus_y; GetPlotPoint(focus_plot, focus_iter, out focus_x, out focus_y); // scour the rest of the plots, searching for values // with a small delta to min_x int min_delta = Int32.MaxValue; ArrayList min_delta_plots = new ArrayList(); ArrayList min_delta_iters = new ArrayList(); foreach (LinePlot plot in plots) { TreeIter iter; if (!plot.Model.GetIterFirst(out iter)) { break; } TreeModel plot_model; TreePath plot_focus_path = null; TreeIter plot_focus_iter = TreeIter.Zero; if (plot.HasFocus && plot.GetFocused(out plot_model, out plot_focus_iter)) { plot_focus_path = plot.Model.GetPath(plot_focus_iter); } do { TreePath path = plot.Model.GetPath(iter); int x, y; if (!GetPlotPoint(plot, iter, out x, out y)) { continue; } // ensure that we always pick points // after the previously focused point, // if this plot had focus if (plot_focus_path != null && path.Compare(plot_focus_path) != 1) { continue; } // continue walking until p_x >= x if (x < focus_x) { continue; } // now, we're at the point right of the // last focused point, so find the // minimal x delta int delta = x - focus_x; if (delta > min_delta) { continue; } if (delta < min_delta) { min_delta_plots.Clear(); min_delta_iters.Clear(); } min_delta = delta; min_delta_plots.Add(plot); min_delta_iters.Add(iter); break; } while (plot.Model.IterNext(ref iter)); } // we must be at the end if (min_delta_plots.Count == 0) { FocusFirst(); return; } FocusIters(min_delta_plots, min_delta_iters); }
private void FindPointsInRange(IAxis x_axis, IAxis y_axis, out Point[] points) { points = new Point[0]; if ((x_axis == null || !x_axis.HasValidRange) || (y_axis == null || !y_axis.HasValidRange)) { // we need both axes to be valid to draw anything return; } ArrayList points_list = new ArrayList(); TreeIter iter; if (!model.GetIterFirst(out iter)) { return; } Point prev_point = null; do { IComparable x_val, y_val; if (!GetValue(iter, 0, out x_val) || !GetValue(iter, 1, out y_val)) { continue; } // don't clip a gapped point if (PointGapFunc != null && PointGapFunc(model, iter)) { if (x_axis.IsInRange(x_val)) { Point p = new Point(x_axis.ValueToGridCoords(x_val), y_axis.ValueToGridCoords(y_val), x_val, y_val); p.IsAGap = true; points_list.Add(p); } continue; } // create a line segment between the previous // point and the current point and see if the // segment intersects the viewing plane Point b = new Point(x_axis.ValueToGridCoords(x_val), y_axis.ValueToGridCoords(y_val), x_val, y_val); Point a = new Point(b.X, b.Y, b.XValue, b.YValue); if (prev_point != null) { a = prev_point; } // copy b before it becomes clipped prev_point = b.Clone() as Point; TreePath path = model.GetPath(iter); if (selected_path != null && selected_path.Compare(path) == 0) { b.IsSelected = true; } if (focused_path != null && focused_path.Compare(path) == 0) { b.IsFocused = true; } if (ClipSegment(x_axis, y_axis, ref a, ref b)) { if (a != b && a.IsClipped) { points_list.Add(a); } points_list.Add(b); } } while (model.IterNext(ref iter)); // Sort this list on the x axis points_list.Sort(new PointXAxisIComparer()); points = (Point[])points_list.ToArray(typeof(Point)); }