예제 #1
0
        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);
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
            }
        }