Logo Search packages:      
Sourcecode: ardour version File versions  Download package

spinner.cc

/*
    Copyright (C) 2000 Paul Barton-Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: spinner.cc,v 1.2 2004/02/22 23:04:01 taybin Exp $
*/

#include <cstdio> /* for sprintf, sigh */
#include <gtk--.h>
#include <gtkmmext/spinner.h>
#include <cmath>

using namespace Gtkmmext;

/*---------------------------------------------------------------
  These are a set of "private" objects that serve no other purpose
  than to group one or more Gtk::Arrows together in certain ways.
  ---------------------------------------------------------------*/

namespace Gtkmmext {
  
class DoubleArrow 
{
public:
    DoubleArrow (GtkArrowType at1, GtkArrowType at2, GtkShadowType t) :
          arrow1 (at1, t), arrow2 (at2, t) {
          arrow1.set_name ("DoubleArrow");
          arrow2.set_name ("DoubleArrow");
    };
protected:
    Gtk::Arrow arrow1;
    Gtk::Arrow arrow2;
};

class DoubleArrowHorizontal : public Gtk::HBox, public DoubleArrow

{
public:
    DoubleArrowHorizontal (GtkArrowType at1,
                         GtkArrowType at2,
                         GtkShadowType t) :
          DoubleArrow (at1, at2, t) {
          pack_start (arrow1, true, true);
          pack_start (arrow2, true, true);
    }
};

class DoubleArrowVertical : public Gtk::VBox, public DoubleArrow

{
public:
    DoubleArrowVertical (GtkArrowType at1,
                       GtkArrowType at2,
                       GtkShadowType t) :
          DoubleArrow (at1, at2, t) {
          pack_start (arrow1, true, true);
          pack_start (arrow2, true, true);
    }
};

class DoubleLeftArrow : public DoubleArrowHorizontal

{
public:
    DoubleLeftArrow (GtkShadowType t) :
          DoubleArrowHorizontal (GTK_ARROW_LEFT, GTK_ARROW_LEFT, t) {}
};

class DoubleRightArrow : public DoubleArrowHorizontal

{
public:
    DoubleRightArrow (GtkShadowType t) :
          DoubleArrowHorizontal (GTK_ARROW_RIGHT, GTK_ARROW_RIGHT, t) {}
};

class LeftRightArrow : public DoubleArrowHorizontal

{
public:
    LeftRightArrow (GtkShadowType t) :
          DoubleArrowHorizontal (GTK_ARROW_LEFT, GTK_ARROW_RIGHT, t) {}
};

class DoubleUpArrow : public DoubleArrowVertical

{
public:
    DoubleUpArrow (GtkShadowType t) :
          DoubleArrowVertical (GTK_ARROW_UP, GTK_ARROW_UP, t) {}
};

class DoubleDownArrow : public DoubleArrowVertical

{
public:
    DoubleDownArrow (GtkShadowType t) :
          DoubleArrowVertical (GTK_ARROW_DOWN, GTK_ARROW_DOWN, t) {}
};

class UpDownArrow : public DoubleArrowVertical

{
public:
    UpDownArrow (GtkShadowType t) :
          DoubleArrowVertical (GTK_ARROW_UP, GTK_ARROW_DOWN, t) {}
};

typedef UpDownArrow DoubleUpDownArrow;
typedef LeftRightArrow DoubleLeftRightArrow;

} /* namespace */


/*---------------------------------------------------------------*/

Spinner::Spinner (Spinner_Layout layout,
              Gtk::Adjustment &adj,
              gfloat cr,
              bool show_step,
              bool show_page,
              bool show_up,
              bool show_down,
              gint row_pack_options,
              gint col_pack_options,
              bool all_arrows_horizontal)

      : Gtk::Table (6, 6),
        AutoSpin (adj, cr)
      
{
      with_step = show_step;
      with_page = show_page;
      with_up = show_up;
      with_down = show_down;
      filter = default_filter;
      filter_arg = 0;

      step_up = 0;
      step_down = 0;
      page_up = 0;
      page_down = 0;

      if (with_step) {
            if (with_up) {
                  step_up = new Gtk::Button;

                  step_up->button_press_event.connect(SigC::bind(SigC::slot(this,&Spinner::button_press),StepUp));
                  step_up->button_release_event.connect(SigC::slot(this,&Spinner::button_release));
            }

            if (with_down) {
                  step_down = new Gtk::Button;
                  
                  step_down->button_press_event.connect(SigC::bind(SigC::slot(this,&Spinner::button_press),StepDown));
                  step_down->button_release_event.connect(SigC::slot(this,&Spinner::button_release));
            }
      }
      if (with_page) {
            if (with_up) {
                  page_up = new Gtk::Button;

                  page_up->button_press_event.connect(SigC::bind(SigC::slot(this,&Spinner::button_press),PageUp));
                  page_up->button_release_event.connect(SigC::slot(this,&Spinner::button_release));
            }

            if (with_down) {
                  page_down = new Gtk::Button;
                  
                  page_down->button_press_event.connect(SigC::bind(SigC::slot(this,&Spinner::button_press),PageDown));
                  
                  page_down->button_release_event.connect(SigC::slot(this,&Spinner::button_release));
            }
      }

      attach (entry, 2,3,2,3, row_pack_options, col_pack_options);

      switch (layout) {
      case LeftAndRight:
            if (with_page) {
                  if (with_up) {
                        attach (*page_up, 0,1,2,3);
                        if (with_down) {
                              page_up->add 
                                    (*(new DoubleRightArrow
                                     (GTK_SHADOW_OUT)));
                        } else {
                              page_up->add 
                                    (*(new LeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
                  if (with_down) {
                        attach (*page_down, 4,5,2,3);
                        if (with_up) {
                              page_down->add 
                                    (*(new DoubleLeftArrow
                                     (GTK_SHADOW_OUT)));
                        } else {
                              page_down->add 
                                    (*(new DoubleLeftRightArrow
                                     (GTK_SHADOW_OUT)));
                        }
                  }
            } 
            if (with_step) {
                  if (with_up) {
                        attach (*step_up, 1,2,2,3);
                        if (with_down) {
                              step_up->add 
                                    (*(new Gtk::Arrow
                                       (GTK_ARROW_RIGHT, GTK_SHADOW_OUT)));
                        } else {
                              step_up->add 
                                    (*(new LeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
                  if (with_down) {
                        attach (*step_down, 3,4,2,3);
                        if (with_up) {
                              step_down->add 
                                    (*(new Gtk::Arrow
                                     (GTK_ARROW_LEFT, GTK_SHADOW_OUT)));
                        } else {
                              step_down->add 
                                    (*(new LeftRightArrow
                                     (GTK_SHADOW_OUT)));
                        }
                  }
            }
            break;

      case TopAndBottom:
            if (with_page) {
                  if (with_up) {
                        attach (*page_up, 2,3,0,1);
                        if (with_down) {
                              if (all_arrows_horizontal) {
                                    page_up->add 
                                          (*(new DoubleRightArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    page_up->add 
                                          (*(new DoubleUpArrow
                                           (GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    page_up->add 
                                          (*(new DoubleLeftRightArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    page_up->add 
                                          (*(new DoubleUpDownArrow
                                           (GTK_SHADOW_OUT)));
                              }
                        }
                  }
                  if (with_down) {
                        attach (*page_down, 2,3,4,5);
                        if (with_up) {
                              if (all_arrows_horizontal) {
                                    page_down->add 
                                          (*(new DoubleLeftArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    page_down->add 
                                          (*(new DoubleDownArrow
                                           (GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    page_down->add 
                                          (*(new DoubleLeftRightArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    page_down->add 
                                          (*(new DoubleUpDownArrow
                                           (GTK_SHADOW_OUT)));
                              }
                        }
                  }
            }
            if (with_step) {
                  if (with_up) {
                        attach (*step_up, 2,3,1,2);
                        if (with_down) {
                              if (all_arrows_horizontal) {
                                    step_up->add 
                                          (*(new Gtk::Arrow
                                           (GTK_ARROW_RIGHT, GTK_SHADOW_OUT)));
                              } else {
                                    step_up->add 
                                          (*(new Gtk::Arrow
                                           (GTK_ARROW_UP, GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    step_up->add 
                                          (*(new LeftRightArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    step_up->add 
                                          (*(new UpDownArrow
                                           (GTK_SHADOW_OUT)));
                              }
                        }
                  }
                  if (with_down) {
                        attach (*step_down, 2,3,3,4);
                        if (with_up) {
                              if (all_arrows_horizontal) {
                                    step_down->add 
                                          (*(new Gtk::Arrow
                                           (GTK_ARROW_LEFT, GTK_SHADOW_OUT)));
                              } else {
                                    step_down->add 
                                          (*(new Gtk::Arrow
                                             (GTK_ARROW_DOWN, GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    step_down->add 
                                          (*(new LeftRightArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    step_down->add 
                                          (*(new UpDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        }
                  }
            }
            break;
            
      case StepLR_PageTB:
            if (with_page) {
                  if (with_up) {
                        attach (*page_up, 2,3,1,2);
                        if (with_down) {
                              if (all_arrows_horizontal) {
                                    page_up->add 
                                          (*(new DoubleRightArrow
                                           (GTK_SHADOW_OUT)));
                              } else {
                                    page_up->add 
                                          (*(new DoubleUpArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    page_up->add 
                                          (*(new DoubleLeftRightArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    page_up->add 
                                          (*(new DoubleUpDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        }
                  }
                  if (with_down) {
                        attach (*page_down, 2,3,3,4);
                        if (with_up) {
                              if (all_arrows_horizontal) {
                                    page_down->add 
                                          (*(new DoubleLeftArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    page_down->add 
                                          (*(new DoubleDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    page_down->add 
                                          (*(new DoubleLeftRightArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    page_down->add 
                                          (*(new DoubleUpDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        }
                  }
            } 
            if (with_step) {
                  if (with_up) {
                        attach (*step_up, 1,2,2,3);
                        if (with_down) {
                              step_up->add 
                                    (*(new Gtk::Arrow
                                     (GTK_ARROW_RIGHT, GTK_SHADOW_OUT)));
                        } else {
                              step_up->add 
                                    (*(new LeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
                  if (with_down) {
                        attach (*step_down, 3,4,2,3);
                        if (with_up) {
                              step_down->add 
                                    (*(new Gtk::Arrow
                                       (GTK_ARROW_LEFT, GTK_SHADOW_OUT)));
                        } else {
                              step_down->add 
                                    (*(new LeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
            }
            break;
            
      case PageLR_StepTB:
            if (with_page) {
                  if (with_up) {
                        attach (*page_up, 1,2,2,3);
                        if (with_down) {
                              page_up->add 
                                    (*(new DoubleRightArrow
                                       (GTK_SHADOW_OUT)));
                        } else {
                              page_up->add 
                                    (*(new DoubleLeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
                  if (with_down) {
                        attach (*page_down, 3,4,2,3);
                        if (with_up) {
                              page_down->add 
                                    (*(new DoubleLeftArrow
                                       (GTK_SHADOW_OUT)));
                        } else {
                              page_down->add 
                                    (*(new DoubleLeftRightArrow
                                       (GTK_SHADOW_OUT)));
                        }
                  }
            }
            
            if (with_step) {
                  if (with_up) {
                        attach (*step_up, 2,3,1,2);
                        if (with_down) {
                              if (all_arrows_horizontal) {
                                    step_up->add 
                                          (*(new Gtk::Arrow
                                             (GTK_ARROW_RIGHT, GTK_SHADOW_OUT)));
                              } else {
                                    step_up->add 
                                          (*(new Gtk::Arrow
                                             (GTK_ARROW_UP, GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    step_up->add 
                                          (*(new LeftRightArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    step_up->add 
                                          (*(new UpDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        }
                  }
            
                  if (with_down) {
                        attach (*step_down, 2,3,3,4);
                        if (with_up) {
                              if (all_arrows_horizontal) {
                                    step_down->add 
                                          (*(new Gtk::Arrow
                                             (GTK_ARROW_LEFT, GTK_SHADOW_OUT)));
                              } else {
                                    step_down->add 
                                          (*(new Gtk::Arrow
                                             (GTK_ARROW_DOWN, GTK_SHADOW_OUT)));
                              }
                        } else {
                              if (all_arrows_horizontal) {
                                    step_down->add 
                                          (*(new LeftRightArrow
                                             (GTK_SHADOW_OUT)));
                              } else {
                                    step_down->add 
                                          (*(new UpDownArrow
                                             (GTK_SHADOW_OUT)));
                              }
                        }
                  }
            }
            break;
      }

      get_adjustment().value_changed.connect(SigC::slot(this,&Spinner::value_changed));

      if (step_up)   step_up->show_all ();
      if (step_down) step_down->show_all ();
      if (page_up)   page_up->show_all ();
      if (page_down) page_down->show_all ();

      filter (*this, get_adjustment().get_value(), filter_arg);
}

gint
Spinner::button_release (GdkEventButton *ev)

{
      stop_spinning (ev);
      clicked (ev);
      return FALSE;
}

gint
Spinner::button_press (GdkEventButton *ev, ButtonType bt)

{
      AutoSpin::button_press (ev);
      return FALSE;
}

void
Spinner::default_filter (Spinner &spinner, gfloat val, void *arg)

{
      char buf[32];
      sprintf (buf, "%.2f", val);
      spinner.get_entry ().set_text (buf);
}

void
Spinner::value_changed ()

{
      filter (*this, get_adjustment().get_value(), filter_arg);
}

void
Spinner::set_filter (SpinnerFilterFunction func, void *arg)

{
      filter = func;
      filter_arg = arg;

      /* change display, potentially */

      filter (*this, get_adjustment().get_value (), filter_arg);
}


Gtk::Button *
Spinner::get_button (ButtonType bt)

{
      switch (bt) {
      case StepUp:
            return step_up;

      case StepDown:
            return step_down;

      case PageUp:
            return page_up;

      case PageDown:
            return page_down;

      }

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index