private bool SelectPointsNear(LinePlot selected_plot, int x, int y, bool fuzzy_x) { freeze_selection = true; if (selected_plot == null) { selected_plots.Clear(); freeze_selection = false; if (SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } return(false); } selected_plots.Clear(); selected_plots.Add(selected_plot); // select the rest of the points along the x axis foreach (LinePlot plot in plots) { if (plot == selected_plot) { continue; } TreeIter iter; if (!plot.Model.GetIterFirst(out iter)) { continue; } // select the closest point to y that has the // same x value int min_y_delta = Int32.MaxValue; TreeIter min_y_iter = TreeIter.Zero; do { int plot_x, plot_y; if (!GetPlotPoint(plot, iter, out plot_x, out plot_y)) { // reject if it's not visible continue; } // x and y come back with reference to // the allocation, so transform our // plot point to that origin plot_x -= Allocation.X; plot_y -= Allocation.Y; if (fuzzy_x) { int half_size = style.PointHalfSize; if (x > plot_x + half_size || x < plot_x - half_size) { continue; } } else { if (x != plot_x) { continue; } } int delta = Math.Abs(plot_y - y); if (delta < min_y_delta) { min_y_delta = delta; min_y_iter = iter; } } while (plot.Model.IterNext(ref iter)); if (min_y_delta == Int32.MaxValue) { continue; } plot.SelectIter(min_y_iter); plot.FocusIter(min_y_iter); selected_plots.Add(plot); } has_selection = true; has_focus = true; if (Changed != null) { Changed(this, new EventArgs()); } freeze_selection = false; if (SelectionChanged != null) { SelectionChanged(this, new EventArgs()); } return(true); }
// 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); }
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); }
public void Draw(Cairo.Context cr) { if (Allocation.Width == 0 && Allocation.Height == 0) { return; } if (x_axis == null || y_axis == null) { return; } int selection_x = -1; if (has_selection && selected_plots.Count > 0) { // get the x of the first focused point, and // then draw a line from top to bottom // connecting all focused points LinePlot first_plot = (LinePlot)selected_plots[0]; TreeIter iter; TreeModel model; first_plot.GetSelected(out model, out iter); int x, y; GetPlotPoint(first_plot, iter, out x, out y); style.DrawLinkedSelectionLine(cr, x, Allocation.Y, x, Allocation.Y + Allocation.Height); selection_x = x; } if (has_focus && focused_plots.Count > 0) { // get the x of the first focused point, and // then draw a line from top to bottom // connecting all focused points LinePlot first_plot = (LinePlot)focused_plots[0]; TreeIter iter; TreeModel model; first_plot.GetFocused(out model, out iter); int x, y; GetPlotPoint(first_plot, iter, out x, out y); if (x != selection_x) { style.DrawLinkedFocusLine(cr, x, Allocation.Y, x, Allocation.Y + Allocation.Height); } } foreach (LinePlot plot in plots) { plot.SizeAllocate(Allocation); plot.SetAxes(axes); plot.Draw(cr); } }