Gtk_Styled
[ class tree: Gtk_Styled ] [ index: Gtk_Styled ] [ all elements ]

Source for file ScrollBar.php

Documentation is available at ScrollBar.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 2005 Scott Mattocks                                    |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at the following url:           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Scott Mattocks <scottmattocks@php.net>                       |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: ScrollBar.php,v 1.2 2005/01/11 13:55:04 scottmattocks Exp $
  20.  
  21. // Define the error code if it isn't already.
  22. if (!defined('GTK_STYLED_ERROR')) {
  23.     define('GTK_STYLED_ERROR'1);
  24. }
  25.  
  26. /**
  27.  * Class for creating a pseudo-scrollbar whose style can be controlled
  28.  * more easily than a regular scrollbar.
  29.  *
  30.  * While it is possible to control some style elements of a GtkScrollBar,
  31.  * other elements cannot be controlled so easily. Items such as the images
  32.  * at the begining and end (usually arrows) and the scroll bar that is
  33.  * dragged to scroll the element cannot be changed. This leads to
  34.  * applications that either must conform to the windowing systems look
  35.  * and feel or appear incomplete. The goal of this family of PHP-GTK
  36.  * classes is to provide all the same functionality as a normal scroll
  37.  * bar but allow the user to have better control over the look and feel.
  38.  *
  39.  * There are several steps to undertake inorder to make this family of
  40.  * classes mimic a GtkScrollBar:
  41.  * Done: Define what needs to be done.
  42.  * Done: Create a pseudo widget that looks like a scroll bar.
  43.  * Done: Make the pseudo widget act like a scroll bar (move up and down)
  44.  * Done: Make the pseudo widget control another widget
  45.  * Done: Make the bar dragable within the track only.
  46.  * Done: Make the pseudo widget "styleable"
  47.  *
  48.  * @author     Scott Mattocks <scottmattocks@php.net>
  49.  * @version    @VER@
  50.  * @category   Gtk
  51.  * @package    Gtk_Styled
  52.  * @license    PHP version 3.0
  53.  * @copyright  Copyright &copy; 2005 Scott Mattocks
  54.  */
  55.   
  56.     /**
  57.      * The useable widget
  58.      * @var object 
  59.      */
  60.     var $widget;
  61.     /**
  62.      * The widget that the scroll bar will control.
  63.      * @var object 
  64.      */
  65.     var $widgetToScroll;
  66.     /**
  67.      * The pseudo widget that defines the basic properties of the scroll bar.
  68.      * @var object 
  69.      */
  70.     var $styleAdjustment;
  71.     /**
  72.      * The the button that makes the value of the scroll less.
  73.      * @var object 
  74.      */
  75.     var $lessButton;
  76.     /**
  77.      * The the button that makes the value of the scroll more.
  78.      * @var object 
  79.      */
  80.     var $moreButton;
  81.     /**
  82.      * The time out tag that indicates the user is pressing and holding
  83.      * a part of the scroll bar.
  84.      * @var integer 
  85.      */
  86.     var $pressing;
  87.     /**
  88.      * The number of microseconds to wait before incrementing the value
  89.      * again while the user is holding a button.
  90.      * @var integer 
  91.      */
  92.     var $delay = 200;
  93.     /**
  94.      * The width of a button.
  95.      * @var integer 
  96.      */
  97.     var $width = 15;
  98.     /**
  99.      * The height of a button.
  100.      * @var integer 
  101.      */
  102.     var $height = 15;
  103.  
  104.     /**
  105.      * Constructor. Check parameters an call helper methods.
  106.      * 
  107.      * A Gtk_Styled_ScrollBar requires a Gtk_StyleAdjustment on construction.
  108.      * The style adjustment can be either an H or V style adjustment but
  109.      * Whichever is passed controls the look and behavior of the scroll
  110.      * bar.
  111.      *
  112.      * The widget to be scrolled is added later.
  113.      *
  114.      * @access public
  115.      * @param  object &$styleAdjustment 
  116.      * @return void 
  117.      */
  118.     function Gtk_Styled_ScrollBar(&$styleAdjustment)
  119.     {
  120.         // Check that a StyleAdjustment was passed.
  121.         if (!is_a($styleAdjustment'Gtk_Styled_Adjustment')) {
  122.             $this->_handleError('Gtk_Styled_ScrollBar expects a Gtk_Styled_Adjustment. Given a ' get_class($styleAdjustment'.');
  123.         }
  124.         
  125.         $this->styleAdjustment =$styleAdjustment;
  126.  
  127.         // Create the scroll bar look and feel.
  128.         $this->_createScrollBar();
  129.     }
  130.  
  131.     /**
  132.      * Create the scroll bar parts and put them together.
  133.      *
  134.      * A scroll bar consists of the adjustment and two buttons that
  135.      * control the value of the adjustment. Depending on what type of
  136.      * adjustment is passed, the scroll bar will be either a
  137.      * horizontal or vertical scoll bar.
  138.      *
  139.      * @access private
  140.      * @param  none 
  141.      * @return void 
  142.      */
  143.     function _createScrollBar()
  144.     {
  145.         // Create a container to hold the scroll.
  146.         if (is_a($this->styleAdjustment'Gtk_Styled_HAdjustment')) {
  147.             $this->widget =new GtkHBox;
  148.         else {
  149.             $this->widget =new GtkVBox;
  150.         }
  151.  
  152.         // Create the controls.
  153.         $this->lessButton =new GtkButton(NULL);
  154.         $this->moreButton =new GtkButton(NULL);
  155.  
  156.         $this->lessButton->set_usize($this->width$this->height);
  157.         $this->moreButton->set_usize($this->width$this->height);
  158.         
  159.         // Add the default images to the buttons.
  160.         require 'data/Gtk_Styled/Buttons.php';
  161.         if (is_a($this->styleAdjustment'Gtk_Styled_HAdjustment')) {
  162.             $this->setButtonContents($this->lessButton$this->_createPixmap($buttons['horizontal_less']));
  163.             $this->setButtonContents($this->moreButton$this->_createPixmap($buttons['horizontal_more']));
  164.         else {
  165.             $this->setButtonContents($this->lessButton$this->_createPixmap($buttons['vertical_less']));
  166.             $this->setButtonContents($this->moreButton$this->_createPixmap($buttons['vertical_more']));
  167.         }
  168.  
  169.         // Add everything to the container.
  170.         $this->widget->pack_start($this->lessButtonfalsefalse0);
  171.         $this->widget->pack_start($this->styleAdjustment->getWidget()truetrue0);
  172.         $this->widget->pack_start($this->moreButtonfalsefalse0);
  173.     }
  174.  
  175.     /**
  176.      * Create a pixmap from an array.
  177.      *
  178.      * Turn an array into a pixmap. This method is used to turn the arrays
  179.      * in the buttons data file into images. The images are then used for
  180.      * the scroll buttons.
  181.      *
  182.      * @access private
  183.      * @param  array   &$imgArray The image array.
  184.      * @return &array             The new GtkPixmap.
  185.      */    
  186.     function &_createPixmap(&$imgArray)
  187.     {
  188.         $tmpWindow =new GtkWindow;
  189.         $tmpWindow->realize();
  190.         $transparentColor = new GdkColor('#FFFFFF');
  191.         $pieces =gdk::pixmap_create_from_xpm_d($tmpWindow->window$transparentColor$imgArray);
  192.         $pxm =new GtkPixmap($pieces[0]$pieces[1]);
  193.         unset($tmpWindow);
  194.  
  195.         return $pxm;
  196.     }
  197.  
  198.     /**
  199.      * Set the pixmap image of a button.
  200.      *
  201.      * The method allows the user to set the contents of the button.
  202.      * Each button should have an image visually indicating what
  203.      * affect it will have on the value of the adjustment. By default
  204.      * these image are triangles pointing in the direction that they
  205.      * will move the scroll bar. The user may supply any image they
  206.      * desire and may also change the shape of the button using the
  207.      * setButtonMask() method.
  208.      *
  209.      * @access public
  210.      * @param  object &$button The button to set the image for.
  211.      * @param  object &$widget The new contents of the button.
  212.      * @return widget          The previous widget in the button.
  213.      */    
  214.     function setButtonContents(&$button&$widget)
  215.     {
  216.         $prevChild $button->child;
  217.         $button->remove($prevChild);
  218.         $button->add($widget);
  219.  
  220.         return $prevChild;
  221.     }
  222.  
  223.     /**
  224.      * Set the style of one of the buttons.
  225.      *
  226.      * The whole purpose of this class is to allow you to set the
  227.      * style of a the widget. The track and bar styles are set in
  228.      * the Adjustment. The button styles can be set here.
  229.      *
  230.      * @access public
  231.      * @param  object &$button 
  232.      * @param  object &$style 
  233.      * @return void 
  234.      */
  235.     function setButtonStyle(&$button&$style)
  236.     {
  237.         $button->set_style($style);
  238.     }
  239.  
  240.     /**
  241.      * Set the pix mask of one of the buttons.
  242.      *
  243.      * The user may control the shape of the scrollbar buttons by
  244.      * adding a pix mask. By default the buttons are grey squares
  245.      * but by using this method and setButtonContents it is possible
  246.      * to make the button any shape and/or color desired.
  247.      *
  248.      * The button that passed to this method should be the return
  249.      * value from one of getLessButton() or getMoreButton().The x
  250.      * and y parameters will offset the mask from the upper left
  251.      * corner.
  252.      *
  253.      * @access public
  254.      * @param  object  &$button The button whose shape is to be changed.
  255.      * @param  object  &$mask   The mask to apply to the button.
  256.      * @param  integer $x       The offset from the left edge.
  257.      * @param  integer $y       The offset from the top edge.
  258.      */
  259.     function setButtonMask(&$button&$mask$x = 0$y = 0)
  260.     {
  261.         $button->shape_combine_mask($mask$x$y);
  262.     }
  263.  
  264.     /**
  265.      * Return the 'more' button.
  266.      *
  267.      * @access public
  268.      * @param  none 
  269.      * @return &object 
  270.      */
  271.     function &getMoreButton()
  272.     {
  273.         return $this->moreButton;
  274.     }
  275.  
  276.     /**
  277.      * Return the 'less' button.
  278.      *
  279.      * @access public
  280.      * @param  none 
  281.      * @return &object 
  282.      */
  283.     function &getLessButton()
  284.     {
  285.         return $this->lessButton;
  286.     }
  287.  
  288.     /**
  289.      * Add a widget to be controlled by the Gtk_Styled_ScrollBar.
  290.      *
  291.      * It doesn't make much sense to have a scroll bar with nothing to
  292.      * scroll. This method puts the Gtk_Styled_ScrollBar incharge of the
  293.      * $widgetToScroll. The widget to scroll should obviously be
  294.      * scrollable. The Gtk_Styled_ScrollBar will only control scrolling in
  295.      * one direction. Which direction depends on what type of
  296.      * Gtk_StyleAdjustment was passed on construction. To fully control
  297.      * all directions of scrolling, you must add the widget to scroll
  298.      * to two different Gtk_Styled_ScrollBars.
  299.      *
  300.      * @access public
  301.      * @param  object  &$widgetToScroll 
  302.      * @return void 
  303.      */
  304.     function addWidgetToScroll(&$widgetToScroll)
  305.     {
  306.         // Set the member variable.
  307.         $this->widgetToScroll = $widgetToScroll;
  308.  
  309.         // Set the values for the adjustment based off of the
  310.         // widget to scroll.
  311.         $this->setAdjFromAdj($this->widgetToScroll);
  312.         
  313.         // Connect the style adjustment pieces to the right signals.
  314.         $this->_connectStyleAdjustment();
  315.  
  316.         // We need to keep the styleAdjustment values current with
  317.         // the "real" adjustment values. The values can be changed
  318.         // by the scrollable widget or other objects. It is important
  319.         // to keep things consistent and up-to-date.
  320.         $this->widgetToScroll->connect('value-changed'array(&$this'setAdjValueFromAdj'));
  321.         $this->widgetToScroll->connect('changed'array(&$this'setAdjFromAdj'));
  322.     }
  323.  
  324.     /**
  325.      * Connect the styleAdjustment pieces to value setting methods.
  326.      *
  327.      * To have control over the scrollable widget, the user must be
  328.      * able to change the value of the styleAdjustment. The track
  329.      * and the buttons must be clickable.
  330.      * 
  331.      * Eventually, the bar must also be dragable.
  332.      *
  333.      * @access private
  334.      * @param  none 
  335.      * @return void 
  336.      */
  337.     function _connectStyleAdjustment()
  338.     {
  339.         // Connect the pre and post tracks to change the value by one page.
  340.         $this->styleAdjustment->preTrack->connect_object('button-press-event',
  341.                                                          array(&$this'setAdjValue'),
  342.                                                          (0 - $this->styleAdjustment->pageSize)true);
  343.         $this->styleAdjustment->preTrack->connect_object('button-release-event',
  344.                                                          array(&$this'stopValue'));
  345.         $this->styleAdjustment->preTrack->connect_object('leave-notify-event',
  346.                                                          array(&$this'stopValue'));
  347.  
  348.         $this->styleAdjustment->bar->connect_object('pressed'
  349.                                                     array(&$this'setAdjValueMouse'));
  350.         $this->styleAdjustment->bar->connect_object('released',
  351.                                                     array(&$this'stopValue'));
  352.  
  353.         $this->styleAdjustment->postTrack->connect_object('button-press-event',
  354.                                                           array(&$this'setAdjValue'),
  355.                                                           $this->styleAdjustment->pageSizetrue);
  356.         $this->styleAdjustment->postTrack->connect_object('button-release-event',
  357.                                                           array(&$this'stopValue'));
  358.         $this->styleAdjustment->postTrack->connect_object('leave-notify-event',
  359.                                                           array(&$this'stopValue'));
  360.  
  361.         // Make the controls have an effect on the adjustment value.
  362.         $this->lessButton->connect_object('pressed'
  363.                                           array(&$this'setAdjValue'),
  364.                                           (0 - $this->styleAdjustment->stepIncrement)true);
  365.         $this->lessButton->connect_object('released'
  366.                                           array(&$this'stopValue'));
  367.  
  368.         $this->moreButton->connect_object('pressed',
  369.                                           array(&$this'setAdjValue'),
  370.                                           $this->styleAdjustment->stepIncrementtrue);
  371.         $this->moreButton->connect_object('released'
  372.                                           array(&$this'stopValue'));
  373.     }
  374.  
  375.     /**
  376.      * Set the adjustment value based on the mouse position.
  377.      *
  378.      * When the scrollbar is being dragged to change its value
  379.      * the change in mouse position should influence an equal
  380.      * change in bar position. In other words one pixel change
  381.      * in mouse position does not necessarily translate to one
  382.      * pixel change in bar position.
  383.      *
  384.      * @access public
  385.      * @param  none 
  386.      * @return void 
  387.      */
  388.     function setAdjValueMouse()
  389.     {
  390.         // Figure out which coordinate to use.
  391.         if (is_a($this->styleAdjustment'Gtk_Styled_HAdjustment')) {
  392.             $coord = 0;
  393.         else {
  394.             $coord = 1;
  395.         }
  396.  
  397.         // Get the current mouse position.
  398.         $newPos $this->styleAdjustment->widget->window->pointer[$coord];
  399.  
  400.         // Make sure the mouse is still within the bar.
  401.         if(!$this->styleAdjustment->checkMouseBounds()) {
  402.             return true;
  403.         }
  404.  
  405.  
  406.         // Set the adjustment value based on the difference between the
  407.         // old and new mouse position.
  408.         if (isset($this->mPosition)) {
  409.             if (isset($this->widgetToScroll)) {
  410.                 $this->widgetToScroll->set_value($this->styleAdjustment->setValue($this->styleAdjustment->getValueFromPosition($newPos $this->mPosition)));
  411.             else {
  412.                 $this->styleAdjustment->setValue($this->styleAdjustment->getValueFromPosition($newPos $this->mPosition));
  413.             }
  414.             //$this->setAdjValue($this->styleAdjustment->value + ($newPos - $this->mPosition), false);
  415.         }
  416.  
  417.         // Make the current position the old position for next time.
  418.         $this->mPosition $newPos;
  419.  
  420.         // Keep calling the method to update the value.
  421.         $this->delay = 50;
  422.         $this->pressing = gtk::timeout_add($this->delayarray(&$this'setAdjValueMouse'));
  423.     }
  424.  
  425.     /**
  426.      * Set the value of the adjustment and styleAdjustment.
  427.      *
  428.      * Sets the value of the "real" adjustment and the style adjustment.
  429.      * By setting the value of the adjustment, the scrolling widget will
  430.      * move as if it has been scrolled. This makes it easier to fake the
  431.      * scrolling action as if it were done by the style adjustment.
  432.      *
  433.      * @access public
  434.      * @param  object $event The GdkEvent that occured to make the value change
  435.      * @param  double $value The new value for the adjustments.
  436.      * @return void 
  437.      */
  438.     function setAdjValue($event$value$continue = false)
  439.     {
  440.         // Adjust for the fact that some events pass the event also.
  441.         if (is_numeric($event)) {
  442.             $continue $value;
  443.             $value    $event;
  444.         }
  445.  
  446.         // Set the value of the widget to scroll also.
  447.         // This is a cheat for making the scrollable widget scroll.
  448.         if (isset($this->widgetToScroll)) {
  449.             // Because the widget to scroll is connected to other methods,
  450.             // it will change the value of the style adjustment when its
  451.             // value is changed.
  452.             $this->widgetToScroll->set_value($this->styleAdjustment->setValue($this->styleAdjustment->value + $value));
  453.         else {
  454.             $this->styleAdjustment->setValue($this->styleAdjustment->value + $value);
  455.         }
  456.  
  457.         // Keep going if the user is holding down the button.
  458.         if ($continue{
  459.             $this->pressing = gtk::timeout_add($this->delayarray(&$this'setAdjValue')$value$continue);
  460.             // Reduce the delay.
  461.             $this->delay = 100;
  462.         }
  463.     }
  464.  
  465.     /**
  466.      * Stop incrementing the value.
  467.      *
  468.      * This method kills the timeout that is calling the setAdjValue
  469.      * method. This will stop the scrollbar from moving after the
  470.      * user has released the button or moved the mouse outside of the
  471.      * track.
  472.      * 
  473.      * @access public
  474.      * @param  none 
  475.      * @return void 
  476.      */
  477.     function stopValue()
  478.     {
  479.         // Kill the timeout.
  480.         if (isset($this->pressing)) {
  481.             gtk::timeout_remove($this->pressing);
  482.         }
  483.         // The user must hold down the button for a little while
  484.         // before the scrolling starts.
  485.         $this->delay = 200;
  486.  
  487.         if (isset($this->mPosition)) {
  488.             unset($this->mPosition);
  489.         }
  490.     }
  491.  
  492.     /**
  493.      * Set the styleAdjustment value based on the value of a
  494.      * GtkAdjustment object.
  495.      *
  496.      * In order to keep the styleAdjustment in sync with the scrolling
  497.      * widget, the value must be taken from the GtkAdjustment that
  498.      * controls the GtkScrollbar.
  499.      *
  500.      * @access public
  501.      * @param  object &$adj The GtkAdjustment to get the value from.
  502.      * @return void 
  503.      */
  504.     function setAdjValueFromAdj(&$adj)
  505.     {
  506.         $this->styleAdjustment->setValue($adj->value);
  507.     }
  508.  
  509.     /**
  510.      * Set the styleAdjustment values based off of a GtkAdjustment.
  511.      *
  512.      * @access public
  513.      * @param  object &$adj The GtkAdjustment to get the values from.
  514.      * @return void 
  515.      */
  516.     function setAdjFromAdj(&$adj)
  517.     {
  518.         $this->styleAdjustment->setUpper($adj->upper);
  519.         $this->styleAdjustment->setLower($adj->lower);
  520.         $this->styleAdjustment->setPageSize($adj->page_size);
  521.         $this->styleAdjustment->setPageIncrement($adj->page_increment);
  522.         $this->styleAdjustment->setStepIncrement($adj->step_increment);        
  523.         $this->styleAdjustment->setValue($adj->value);
  524.     }
  525.  
  526.     /**
  527.      * Get the final product that the user can use.
  528.      *
  529.      * To make things easier for the user, and to keep some
  530.      * consistency with other PEAR Gtk classes, the final usable
  531.      * object is called widget and is returned from the getWidget
  532.      * method.
  533.      * 
  534.      * @access public
  535.      * @param  none 
  536.      * @return &object 
  537.      */
  538.     function &getWidget()
  539.     {
  540.         return $this->widget;
  541.     }
  542.  
  543.     /**
  544.      * Error handling method.
  545.      *
  546.      * Errors should be handled with PEAR::Error_Stack
  547.      *
  548.      * @access private
  549.      * @param  string  $message 
  550.      * @param  integer $level 
  551.      * @return mixed 
  552.      */
  553.     function _handleError($msg$code = GTK_STYLED_ERROR$pearMode = PEAR_ERROR_PRINT)
  554.     {
  555.         // Require the pear class so that we can use its error functionality.
  556.         require_once ('PEAR.php');
  557.         
  558.         // Check whether or not we should print the error.
  559.         PEAR::raiseError($msg "\n"$code$pearMode);
  560.     }
  561. }
  562. /*
  563.  * Local variables:
  564.  * tab-width: 4
  565.  * c-basic-offset: 4
  566.  * End:
  567.  */
  568. ?>

Documentation generated on Mon, 11 Mar 2019 14:48:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.