home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Gtk / ScrollingLabel.php < prev   
Encoding:
PHP Script  |  2005-12-02  |  31.2 KB  |  913 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 2004 The PHP Group                                     |
  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:$
  20. /**
  21.  * Gtk_ScrollingLabel
  22.  *
  23.  * This is a class to encapsulate the functionality
  24.  * needed for a scrolling gtk label. This class    
  25.  * provides a simple, easy to understand API for   
  26.  * setting up and controlling the label.  It allows
  27.  * for the ability to scroll in either direction,  
  28.  * start and stop the scroll, pause and unpause the
  29.  * scroll, get and set the text, and set display   
  30.  * properites of the text.                         
  31.  *                                                 
  32.  * @author    Scott Mattocks                          
  33.  * @category  Gtk
  34.  * @package   ScrollingLabel                     
  35.  * @license   http://www.php.net/license/3_0.txt PHP License 3.0
  36.  * @copyright Copyright © 2004 Scott Mattocks
  37.  *
  38.  * @todo Allow text to wrap the visible area.
  39.  */
  40.  
  41. /**
  42.  * A constant for representing srolls that move from left to right
  43.  * @const GTK_SCROLL_LEFT
  44.  */
  45. define('GTK_SCROLLINGLABEL_LEFT',  1);
  46. /**
  47.  * A constant for representing srolls that move from right to left
  48.  * @const GTK_SCROLLINGLABEL_RIGHT
  49.  */
  50. define('GTK_SCROLLINGLABEL_RIGHT', 2);
  51. /**
  52.  * A SrollingLabel error code.
  53.  * @const GTK_SCROLLINGLABEL_DEFAULT_ERROR
  54.  */
  55. define('GTK_SCROLLINGLABEL_DEFAULT_ERROR', 1);
  56.  
  57. /**
  58.  * Class for creating a label with the ability to scroll
  59.  * text.
  60.  */
  61. class Gtk_ScrollingLabel {
  62.     
  63.     /**
  64.      * The event box which will contain the label and listen for events.
  65.      * @var object
  66.      */
  67.     var $widget;
  68.     /**
  69.      * The label which will display the text.
  70.      * @var object
  71.      */
  72.     var $label;
  73.     /**
  74.      * The full text that will be displayed over time.
  75.      * @var string
  76.      */
  77.     var $labelText;
  78.     /**
  79.      * The tag returned to indicate the call to gtk timeout.
  80.      * @var integer
  81.      */
  82.     var $gtkTimeoutTag;
  83.     /**
  84.      * The number of characters that should be visible
  85.      * @var integer
  86.      */
  87.     var $visibleLength = 70;
  88.     /**
  89.      * The number of milliseconds between calls to the method passed
  90.      * to gtk timeout.
  91.      * @var integer
  92.      */
  93.     var $speed = 70;
  94.     /**
  95.      * The first character to show when direction is GTK_SCROLLINGLABEL_LEFT
  96.      * The last character to show when direction is GTK_SCROLLINGLABEL_RIGHT
  97.      * @var integer
  98.      */
  99.     var $currentCharPosition = 0;
  100.     /**
  101.      * The direction the text should be moving.
  102.      * @var integer
  103.      */
  104.     var $direction = GTK_SCROLLINGLABEL_LEFT;
  105.     /**
  106.      * Whether the text should change direction when it hits an edge.
  107.      * @var boolean
  108.      */
  109.     var $bounce = true;
  110.     
  111.     /**
  112.      * Constructor.
  113.      * Loads module if needed then builds needed widgets.
  114.      *
  115.      * @access private
  116.      * @param  string  $startingText The text to display uppon creation.
  117.      * @return void
  118.      */
  119.     function Gtk_ScrollingLabel($startingText = '') 
  120.     {        
  121.         // Create a GTK_eventbox.
  122.         // This is used to connect events to the label (Sort of).
  123.         $this->widget =& new GtkEventBox;
  124.         
  125.         // We need to add an event mask for the event box.
  126.         $this->widget->add_events(GDK_BUTTON_PRESS_MASK);
  127.         
  128.         // Next we need to create a label.
  129.         $this->label =& new GtkLabel($startingText);
  130.         $this->labelText = $startingText;
  131.         
  132.         // We need to set up some label stuff
  133.         $this->label->set_alignment(0, 1.0);
  134.         $this->label->set_usize(-1, 1);
  135.         $this->label->set_justify(GTK_JUSTIFY_LEFT);
  136.         
  137.         // We need to set the direction of the scroll.
  138.         $this->setDirection($this->direction);
  139.         
  140.         // Then we can cram the label into the event box.
  141.         $this->widget->add($this->label);
  142.     }
  143.     
  144.     /**
  145.      * Display the visible text and de/increment the current position.
  146.      * Needs to check if we are at the end of the string and which
  147.      * direction the text is moving.
  148.      *
  149.      * This is the brains of the class. _scrollLabel figures out what
  150.      * to do next.  If we are scrolling in one direction we need to 
  151.      * know when the text has all passed through the visible "window"
  152.      * so that we can start all over again.  If we are bouncing the
  153.      * text between the two edges of the visible window we need to 
  154.      * know when we have reached an edge so that the text can go in 
  155.      * the opposite direction next time.  
  156.      *
  157.      * Note: If the text is set to bounce and the text is larger than
  158.      * the visible window can display, the text will not bounce the 
  159.      * way one would expect. Larger than visible window text bouncing
  160.      * may be supported later but that is not guaranteed.
  161.      *
  162.      * @access private
  163.      * @param  none
  164.      * @return boolean False if the scrolling should stop.
  165.      */
  166.     function _scrollLabel()
  167.     {
  168.         // If the timeout is dead we return false.
  169.         if (!isset($this->gtkTimeoutTag)) {
  170.             return false;
  171.         }
  172.         
  173.         // Get the visible text.
  174.         $visible = $this->getVisibleText();
  175.         
  176.         // Set the text.
  177.         $this->label->set_text($visible);
  178.         
  179.         // We need to figure out which way to move the text.
  180.         if ($this->direction == GTK_SCROLLINGLABEL_LEFT) {
  181.             ++$this->currentCharPosition;
  182.         } else {
  183.             --$this->currentCharPosition;
  184.         }
  185.         
  186.         // Check to see if we need to do change direction.
  187.         if ($this->bounce) {
  188.             // We are going to change direction eventually.
  189.             if ($this->direction == GTK_SCROLLINGLABEL_LEFT &&
  190.                 $visible == $this->labelText) {
  191.                 
  192.                 // If we are scrolling right to left and displaying the last character,
  193.                 // we need to turn around and move left to right next time.
  194.                 $this->setDirection(GTK_SCROLLINGLABEL_RIGHT);
  195.                 
  196.                 // We need to set the current position to the end.
  197.                 $this->currentCharPosition = strlen($this->padText()) - strlen($this->labelText);
  198.                 
  199.             } elseif ($this->direction == GTK_SCROLLINGLABEL_RIGHT &&
  200.                       $this->currentCharPosition <= 0) {
  201.                 
  202.                 // If we are scrolling left to right and we are showing the first
  203.                 // character, we need to turn around and go right to left next time.
  204.                 $this->setDirection(GTK_SCROLLINGLABEL_LEFT);
  205.                 
  206.                 // We need to start the scroll back at the begining.
  207.                 $this->currentCharPosition = 0;
  208.             }
  209.         }
  210.         
  211.         // Check to see if we need to start over.
  212.         if ($this->direction == GTK_SCROLLINGLABEL_LEFT &&
  213.             $this->currentCharPosition >= strlen($this->padText())) {
  214.             // We need to start back at the beginning.
  215.             $this->currentCharPosition = 0;
  216.         } elseif ($this->direction == GTK_SCROLLINGLABEL_RIGHT &&
  217.                   $this->currentCharPosition < 0) {
  218.             // We need to start back at the end.
  219.             $this->currentCharPosition = strlen($this->labelText) + $this->visibleLength - 1;
  220.         }
  221.         
  222.         return true;
  223.     }
  224.     
  225.     /**
  226.      * Begin scrolling the text from the start of the string.
  227.      * Usually connected to an event.
  228.      *
  229.      * startScroll() will make the text begin scrolling in the
  230.      * direction given by calling setDirection().  If the text
  231.      * is scrolling left to right (GTK_SCROLLINGLABEL_RIGHT), the 
  232.      * current character position is set to the end of the text.
  233.      * This means that the last character of the label will be
  234.      * the first character shown.  If the text is scrolling
  235.      * right to left (GTK_SCROLLINGLABEL_LEFT), the current character
  236.      * position is set to zero.  This means that first character
  237.      * shown will be a blank space.
  238.      *
  239.      * This method is best used when connected to an event.
  240.      *
  241.      * @access public
  242.      * @param  none
  243.      * @return boolean true if the scrolling has started.
  244.      * @uses   unPause
  245.      * @see    setStartSignal
  246.      */
  247.     function startScroll()
  248.     {
  249.         // First reset the current character position.
  250.         $this->currentCharPosition = 0;
  251.         
  252.         // Then return the value of a call to the unpuase method.
  253.         return $this->unPause();
  254.     }
  255.     
  256.     /**
  257.      * Begin scrolling the text from the current character position.
  258.      * Work horse for startScroll.  Usually connected to an event.
  259.      *
  260.      * unPause() does pretty much the same thing as startScroll 
  261.      * except that it does not manipulate the current character
  262.      * position.  When you unpause the scroll, the text continues
  263.      * from where it left off when it was paused.
  264.      *
  265.      * This method is best used when conneted to an event.
  266.      *
  267.      * @access public
  268.      * @param  none
  269.      * @return boolean true if the scrolling has started.
  270.      * @see    setUnPauseSignal
  271.      */
  272.     function unPause()
  273.     {
  274.         // Pretty much just like start but without resetting the postion.
  275.         
  276.         // First check to see if there is a timeout already started.
  277.         if (isset($this->gtkTimeoutTag)) {
  278.             // Throw error about scroll already started.
  279.             $this->_error('Cannot unpause. Text not scrolling.', GTK_SCROLLINGLABEL_DEFAULT_ERROR, PEAR_ERROR_PRINT);
  280.             return false;
  281.             
  282.         } elseif (!isset($this->speed)) {
  283.             // Throw error about no value for speed.
  284.             return $this->_error('Cannot unpause. No speed set.');
  285.             
  286.         } else {
  287.             // Start the scrolling.
  288.             $this->gtkTimeoutTag =& gtk::timeout_add($this->speed, array(&$this, '_scrollLabel'));
  289.         }
  290.         
  291.         // Give back the timeout tag.
  292.         return $this->gtkTimeoutTag;
  293.     }
  294.     
  295.     /**
  296.      * Stop scrolling the text and return the string to the beginning.
  297.      * Usually connected to an event.
  298.      *
  299.      * stopScroll will stop the text from scrolling and set the 
  300.      * current character position to zero.  When the text is 
  301.      * started in motion again, it will be shown as it would if
  302.      * it had been started for the first time.
  303.      *
  304.      * This method is best used when connected to an event.
  305.      *
  306.      * @access public
  307.      * @param  none
  308.      * @return boolean true if the scrolling has stopped.
  309.      * @uses   pause
  310.      * @see    setStopSignal
  311.      */
  312.     function stopScroll()
  313.     {
  314.         // First pause the scroll.
  315.         if ($this->pause()) {
  316.             // Then, if that worked, reset the current position.
  317.             $this->currentCharPosition = 0;
  318.             // Finally call the method to change the display returning
  319.             // the value from that method to indicate success.
  320.             return $this->_scrollLabel();
  321.         }
  322.         return false;
  323.     }
  324.     
  325.     /**
  326.      * Stop the scroll where it is and do not change the current position.
  327.      * Usually connected to an event.
  328.      *
  329.      * pause() will stop the text in its tracks.  The scrolling
  330.      * will stop but the visible text will not change.  This is
  331.      * different from stopScroll() in that stopScroll() will 
  332.      * clear the display back to its starting state.
  333.      *
  334.      * This method is best used when connected to an event.
  335.      *
  336.      * @access public
  337.      * @param  none
  338.      * @return boolean true if the scrolling has stopped.
  339.      * @see    setPauseSignal
  340.      */
  341.     function pause()
  342.     {
  343.         // Pretty much like stop but without reseting the position.
  344.         if (empty ($this->gtkTimeoutTag)) {
  345.             // Throw an error about no scroll in progress.
  346.             $this->_error('Cannot pause. No timeout found.', 
  347.                           GTK_SCROLLINGLABEL_DEFAULT_ERROR, PEAR_ERROR_PRINT);
  348.             return false;
  349.             
  350.         } else {
  351.             
  352.             // All we need todo is unset the tag member because it is a reference.
  353.             unset ($this->gtkTimeoutTag);
  354.             
  355.             // Indicate success by returning true.
  356.             return true;
  357.         }
  358.     }
  359.     
  360.     /**
  361.      * Connect a signal to a method.
  362.      *
  363.      * This private method will connect the event $signal to the
  364.      * method $methodName.  If the optional parameter $after is
  365.      * set to true, the event will be connected using connect
  366.      * after.  All methods connected to an event with connect
  367.      * after will be called after methods connected with plain
  368.      * old connect.  The GTK label does not listen for signals so
  369.      * all events must be connected to the event box.
  370.      * 
  371.      * @access private
  372.      * @param  object  $signal     The GTK_Signal to listen for.
  373.      * @param  string  $methodName The method to connect.
  374.      * @param  boolean $after      Should we make this one of the last calls.
  375.      * @return boolean
  376.      */
  377.     function _connectSignal($signal, $methodName, $after = false)
  378.     {
  379.         // Check that signal is accepted by eventbox.
  380.         /**
  381.          * @todo Check the above
  382.          **/
  383.         
  384.         // Check to see if we are using connect after
  385.         if ($after) {
  386.             $method = 'connect_after';
  387.         } else {
  388.             $method = 'connect';
  389.         }
  390.         
  391.         // Connect the event box to the signal with the method.
  392.         $this->widget->$method($signal, array(&$this, $methodName));
  393.         
  394.         return true;
  395.     }
  396.     
  397.     /**
  398.      * Connect a signal to a method and act on another widget.
  399.      *
  400.      * This private method connects an event to a method and
  401.      * passes that method a widget from which to get data or
  402.      * to act on in some way. If the optional parameter $after
  403.      * is set to true, the event will be connected using connect
  404.      * after.  All methods connected to an event with connect
  405.      * after will be called after methods connected with plain
  406.      * old connect.  The GTK label does not listen for signals
  407.      * so all events must be connected to the event box.
  408.      *
  409.      * @access private
  410.      * @param  object  $signal     The GTK_Signal to listen for.
  411.      * @param  string  $methodName The method to connect.
  412.      * @param  &object $object     The widget to act on.
  413.      * @param  boolean $after      Should we make this one of the last calls.
  414.      * @return boolean
  415.      */
  416.     function _connectObjectSignal($signal, $methodName, &$object, $after = false)
  417.     {
  418.         // Check that signal is accepted by eventbox.
  419.         /**
  420.          * @todo Check the above
  421.          **/
  422.         
  423.         // Check to see if we are using connect after
  424.         if ($after) {
  425.             $method = 'connect_object_after';
  426.         } else {
  427.             $method = 'connect_object';
  428.         }
  429.         
  430.         // Connect the event box to the signal with the method.
  431.         $this->widget->$method($signal, array(&$this, $methodName), $object);
  432.     }
  433.     
  434.     /**
  435.      * Connect the pause method to an event.
  436.      *
  437.      * setPauseSignal() will make the event box listen for the
  438.      * signal $signal and will envoke pause() when ever it is
  439.      * heard.  The signal should be a signal that GTKEventBox
  440.      * listens for normally or a button press event.
  441.      *
  442.      * @access public
  443.      * @param  string $signal The GTK signal to connect to the method.
  444.      * @return integer
  445.      * @uses   _connectSignal
  446.      */
  447.     function setPauseSignal($signal)
  448.     {
  449.         // Call the private connectSignal method.
  450.         return $this->_connectSignal($signal, 'pause');
  451.     }
  452.     
  453.     /**
  454.      * Connect the unpause method to an event.
  455.      *
  456.      * setUnPauseSignal() will make the event box listen for the
  457.      * signal $signal and will envoke unPause() when ever it is
  458.      * heard.  The signal should be a signal that GTKEventBox
  459.      * listens for normally or a button press event.
  460.      *
  461.      * @access public
  462.      * @param  string $signal The GTK signal to connect to the method.
  463.      * @return integer
  464.      * @uses   _connectSignal
  465.      */
  466.     function setUnPauseSignal($signal)
  467.     {
  468.         // Call the private connectSignal method.
  469.         return $this->_connectSignal($signal, 'unPause');
  470.     }
  471.     
  472.     /**
  473.      * Connect the start method to an event.
  474.      *
  475.      * setStartSignal() will make the event box listen for the
  476.      * signal $signal and will envoke startScroll() when ever it is
  477.      * heard.  The signal should be a signal that GTKEventBox
  478.      * listens for normally or a button press event.
  479.      *
  480.      * 
  481.      * @access public
  482.      * @param  string $signal The GTK signal to connect to the method.
  483.      * @return integer
  484.      * @uses   _connectSignal
  485.      */
  486.     
  487.     function setStartSignal($signal)
  488.     {
  489.         // Call the private connectSignal method.
  490.         return $this->_connectSignal($signal, 'startScroll');
  491.     }
  492.     
  493.     /**
  494.      * Connect the stop method to an event.
  495.      *
  496.      * setStopSignal() will make the event box listen for the
  497.      * signal $signal and will envoke stopScroll() when ever it is
  498.      * heard.  The signal should be a signal that GTKEventBox
  499.      * listens for normally or a button press event.
  500.      *
  501.      *
  502.      * @access public
  503.      * @param  string $signal The GTK signal to connect to the method.
  504.      * @return integer
  505.      * @uses   _connectSignal
  506.      */
  507.     function setStopSignal($signal)
  508.     {
  509.         // Call the private connectSignal method.
  510.         return $this->_connectSignal($signal, 'stopScroll');
  511.     }
  512.     
  513.     /**
  514.      * Set the speed of the scrolling text.
  515.      *
  516.      * setSpeed() will change how quickly the text scrolls
  517.      * across the visible label area. $speed is the number
  518.      * of milliseconds to wait between calls to _scrollLabel.
  519.      * $speed is passes to gtk::timeout_add().  If $restart
  520.      * is set to true, the speed of the text will be changed
  521.      * immediately. Otherwise the speed will not be changed
  522.      * until _scrollLabel is called again. This effectively
  523.      * means that the speed changes one letter after you set
  524.      * the new speed if $restart is false.
  525.      *
  526.      * @access public
  527.      * @param  string  $speed   The speed the text should scroll.
  528.      * @param  boolean $restart Whether or not the speed should be changed before the next call to _scrollLabel
  529.      * @return integer
  530.      */
  531.     function setSpeed($speed, $restart = false)
  532.     {
  533.         // Check the speed.
  534.         if (!is_numeric($speed) || $speed < 1 || $speed > 1000) {
  535.             // Throw an error about illegal speed value
  536.             $this->_error('Cannot set speed. Invalid value: ' . $speed, 
  537.                           GTK_SCROLLINGLABEL_DEFAULT_ERROR, PEAR_ERROR_PRINT);
  538.         } else {
  539.             // Speed is the number of milliseconds between timeouts.
  540.             $this->speed = $speed;
  541.         }
  542.         
  543.         // If the scroll is currently moving we may need to 
  544.         // pause and unpause the scroll.
  545.         if ($restart && isset ($this->gtkTimeoutTag)) {
  546.             // Pausing and unpausing the scroll will affectively change the speed.
  547.             $this->pause();
  548.             $this->unPause();
  549.         }
  550.         
  551.         return $this->speed;
  552.     }
  553.     
  554.     /**
  555.      * Set the diretion that the text should scroll.
  556.      *
  557.      * Set the direction that the text will move across the visible
  558.      * area of the label. The only accepted directions are the two
  559.      * constants GTK_SCROLLINGLABEL_LEFT and GTK_SCROLLINGLABEL_RIGHT which move the
  560.      * from right to left and left to right respectively. The return
  561.      * value is the diretion the text will move on the next call to 
  562.      * _scrollLabel().
  563.      *
  564.      * @access public
  565.      * @param  integer $direction (GTK_SCROLLINGLABEL_LEFT|GTK_SCROLLINGLABEL_RIGHT)
  566.      * @return integer
  567.      */
  568.     function setDirection($direction)
  569.     {
  570.         // Check direction.
  571.         if ($direction != GTK_SCROLLINGLABEL_LEFT && $direction != GTK_SCROLLINGLABEL_RIGHT) {
  572.             // Throw an error about illegal direction choice.
  573.             $this->_error('Cannot set direction. Illegal value: ' . $direction,
  574.                           GTK_SCROLLINGLABEL_DEFAULT_ERROR, PEAR_ERROR_PRINT);
  575.         } else {
  576.             $this->direction = $direction;
  577.         }
  578.         
  579.         return $this->direction;
  580.     }
  581.     
  582.     /**
  583.      * Set whether or not the text should change directions when it hits an edge
  584.      *
  585.      * If bounce is true, the text will scroll to the left until the
  586.      * first character hits the left edge of the visible window then
  587.      * it will scroll to the right. When the last character hits the
  588.      * right edge of the visible window the text will scroll back to
  589.      * the left.
  590.      *
  591.      * Note: I don't know what will happen if bounce is true and the
  592.      * text is larger than what can be viewed at one time in the
  593.      * window. Therefore it is suggested that the length of the text
  594.      * always be at least one less than the size of the window.
  595.      *
  596.      * @access public
  597.      * @param  boolean $bounce true means change directions.
  598.      * @return boolean         The current state of $this->bounce
  599.      */
  600.     function setBounce($bounce)
  601.     {
  602.         $this->bounce = $bounce;
  603.         return $this->bounce;
  604.     }
  605.     
  606.     /**
  607.      * Deprecated method to set bouncing.
  608.      *
  609.      * @deprecated
  610.      * @access public
  611.      * @param  boolean $bounce true means change directions.
  612.      * @return boolean         The current state of $this->bounce
  613.      * @see    setBounce
  614.      */
  615.     function bounce($bounce)
  616.     {
  617.         return $this->setBounce($bounce);
  618.     }
  619.     
  620.     /**
  621.      * Set the style in which the text will be displayed.
  622.      *
  623.      * setStyle() lets you define the look of the text that is
  624.      * scrolling as well as the background of the widget.  
  625.      *
  626.      * This method has not been implemented yet.
  627.      *
  628.      * @access public
  629.      * @param  &object $style The GTK_Style object to use.
  630.      * @return &object
  631.      */
  632.     function setStyle(&$style)
  633.     {
  634.         $this->label->set_style($style);
  635.     }
  636.     
  637.     /**
  638.      * Get the label's style widget.
  639.      *
  640.      * getStyle() returns the label's style widget. This lets you
  641.      * make changes to the style to alter the look and feel of the 
  642.      * widget. You can change the font of the display, the color of
  643.      * the background, etc.
  644.      * 
  645.      * @access public
  646.      * @param  none
  647.      * @return &object
  648.      */
  649.     function &getStyle()
  650.     {
  651.         return $this->label->get_style();
  652.     }
  653.     
  654.     /**
  655.      * Return the portion of the label text that should be visible
  656.      *
  657.      * getVisibleText() is used internally to get the text that 
  658.      * should be shown everytime the text scrolls.  It can also
  659.      * be called publically to get the text that is currently
  660.      * displayed in the visible window area. The part of the text
  661.      * that is visible depends on the current character position
  662.      * and the direction the text is moving.
  663.      *
  664.      * @access public
  665.      * @param  none
  666.      * @return string  The visible text.
  667.      * @uses   padText()
  668.      */
  669.     function getVisibleText()
  670.     {
  671.         // Pad the text.
  672.         $text = $this->padText();
  673.         
  674.         // We need to show from the current character position to 
  675.         // the character at currentCharPosition + visibleLength.
  676.         if ($this->direction == GTK_SCROLLINGLABEL_LEFT) {
  677.             $text = substr($text, $this->currentCharPosition, $this->visibleLength);
  678.         } else {
  679.             // I want to start at the end and get the text 
  680.             // $visibleLength in front of that.
  681.             $text = substr($text, $this->currentCharPosition - $this->visibleLength, $this->visibleLength);
  682.         }
  683.         
  684.         return $text;
  685.     }
  686.     
  687.     /**
  688.      * Pad the text with enough space to fill the visible area.
  689.      *
  690.      * padText adds the needed amount of white space to the
  691.      * text so that it can scroll properly.  When the text is
  692.      * set to bounce the padding should only be what is needed
  693.      * to make the string as long as the visible window area.
  694.      * If the text is not bouncing, the text must be padded with 
  695.      * as many spaces as the length of the visible area.
  696.      *
  697.      * @access public
  698.      * @param  none
  699.      * @return string   The padded text.
  700.      */
  701.     function padText()
  702.     {
  703.         // Get the full label text.
  704.         $text = $this->labelText;
  705.         
  706.         // We need to pad the text on the left unless we are bouncing the text.
  707.         if (!$this->bounce) {
  708.             $text = str_pad($text, strlen($text) + $this->visibleLength, ' ', STR_PAD_LEFT);
  709.         } elseif (strlen($this->labelText) < $this->visibleLength) {
  710.             $text = str_pad($text, $this->visibleLength, ' ', STR_PAD_LEFT);
  711.         }
  712.         
  713.         return $text;
  714.     }
  715.     
  716.     /**
  717.      * Return all of the text that can ever be shown by this label.
  718.      *
  719.      * @access public
  720.      * @param  none
  721.      * @return string
  722.      */
  723.     function getFullText()
  724.     {
  725.         return $this->labelText;
  726.     }
  727.     
  728.     /**
  729.      * Return all of the text that is not currently visible.
  730.      * 
  731.      * @access public
  732.      * @param  none
  733.      * @return string
  734.      */
  735.     function getHiddenText()
  736.     {
  737.         // Pad the text.
  738.         $text = $this->padText();
  739.         
  740.         // We need to get the text minus the visible portion.
  741.         // I don't know if this will ever be useful.
  742.         $firstPart  = substr($text, 0, $this->currentCharPosition);
  743.         $secondPart = substr($text, $this->currentCharPosition + $this->visibleLength);
  744.         
  745.         return $firstPart . $secondPart;
  746.     }
  747.     
  748.     /**
  749.      * Set the full text of the label.
  750.      *
  751.      * setFullText() will change the text of the scrolling label.
  752.      * The return value is what the text of the label will be
  753.      * when _scrollLabel is next called.  
  754.      *
  755.      * @access public
  756.      * @param  string $text The new text for the label.
  757.      * @return string       The label's text.
  758.      */
  759.     function setFullText($text)
  760.     {
  761.         // Set the label text to the supplied text.
  762.         $this->labelText = $text;
  763.         
  764.         return $this->labelText;
  765.     }
  766.     
  767.     /**
  768.      * Change the current character position.
  769.      *
  770.      * jumpToChar() allows you to go directly to a character
  771.      * position on the next call to _scrollLabel.  The new
  772.      * position must be between zero (the first character) 
  773.      * and the length of the label minus one. The character
  774.      * position should be calculated using the string from
  775.      * padText(). When the text is scrolling to the left the
  776.      * $charPosition should be the left-most character to 
  777.      * display. When text is scrolling to the right, 
  778.      * $charPosition should be the right-most character to
  779.      * display.
  780.      *
  781.      * The visible label will not change until _scrollLabel
  782.      * is called again.
  783.      *
  784.      * @access public
  785.      * @param  integer $charPosition Depending on the direction either the left or right most character to display.
  786.      * @return integer               The new current character position. (PEAR_Error when there is a problem.)
  787.      */
  788.     function jumpToChar($charPosition)
  789.     {
  790.         // Check that the charPosition exists.
  791.         if (!is_numeric ($charPosition) || $charPosition < 0 || $charPosition >= strlen($this->labelText)) {
  792.             // Throw an error about illegal char position.
  793.             $this->_error('Cannot jump to character. Invalid value. Character position must be a number between zero and the length of the string (' . strlen($this->padText()) . ')');
  794.         } else {
  795.             // Set the current character position.
  796.             $this->currentCharPosition = $charPosition;
  797.         }
  798.         
  799.         return $this->currentCharPosition;
  800.     }
  801.     
  802.     /**
  803.      * Change how many characters should be visible at any given time.
  804.      *
  805.      * setVisibleLength() will set the number of characters that are
  806.      * visible at any given time.  While it is ik to set the visible
  807.      * length smaller than the width of the displaying widget, you 
  808.      * probably don't want to make it larger then the width of the
  809.      * displaying widget.  It will make the padded lenght longer and
  810.      * add additional time before the text begins to appear on screen.
  811.      *
  812.      * @access public
  813.      * @param  integer $length The new size of the visible area in characters.
  814.      * @return integer         The new size of the visible area in characters.
  815.      */
  816.     function setVisibleLength($length)
  817.     {
  818.         // First check the length.
  819.         if (!is_numeric($length) || $length < 0) {
  820.             // Throw an error about illegal visible length.
  821.             $this->_error('Cannot set visible length. Invalid value. Length must be a number greater than zero.');
  822.         } else {
  823.             $this->visibleLength = $length;
  824.         }
  825.         
  826.         return $this->visibleLength;
  827.     }
  828.     
  829.     /**
  830.      * Return the visible area length in characters
  831.      *
  832.      * @access public
  833.      * @param  none
  834.      * @return integer
  835.      */
  836.     function getVisibleLength()
  837.     {
  838.         return $this->visibleLength;
  839.     }
  840.     
  841.     /**
  842.      * Show the GTK components.
  843.      *
  844.      * @access public
  845.      * @param  none
  846.      * @return void
  847.      */
  848.     function show()
  849.     {
  850.         // Show the eventbox and the label.
  851.         $this->widget->show_all();
  852.     }
  853.     
  854.     /**
  855.      * Hide the GTK components.
  856.      * 
  857.      * @access public
  858.      * @param  none
  859.      * @return void
  860.      */
  861.     function hide()
  862.     {
  863.         // Hide the label and the eventbox.
  864.         $this->widget->hide_all();
  865.     }
  866.     
  867.     /**
  868.      * Return the GTKEventBox with the GTKLabel inside.
  869.      *
  870.      * @access public
  871.      * @param  none
  872.      * @return &object
  873.      */
  874.     function &getScrollingLabel()
  875.     {
  876.         return $this->widget;
  877.     }
  878.     
  879.     /**
  880.      * Raise a pear error.
  881.      *
  882.      * _error will raise a PEAR error with $msg as the message.  
  883.      * If the optional parameter $code is set, that error code
  884.      * will be used. Otherwise the default error code will be
  885.      * used. If the optional $pearMode is passed that mode will
  886.      * be used to display/return the error.
  887.      *
  888.      * @access private
  889.      * @param  string  $msg      The human readable error message.
  890.      * @param  integer $code     The error code.
  891.      * @param  integer $pearMode The PEAR mode for the error.
  892.      * @return mixed             A PEAR_Error or void.
  893.      */
  894.     function _error($msg, $code = GTK_SCROLLINGLABEL_DEFAULT_ERROR, $pearMode = PEAR_ERROR_RETURN)
  895.     {    
  896.         // Require the pear class so that we can use its error functionality.
  897.         require_once ('PEAR.php');
  898.         
  899.         // Check whether or not we should print the error.
  900.         if ($pearMode == PEAR_ERROR_PRINT) {
  901.             PEAR::setErrorHandling(PEAR_ERROR_PRINT, "Gtk_ScrollingLabel error: %s<BR />\n");
  902.         }
  903.         
  904.         PEAR::raiseError($msg, $code, $pearMode);
  905.     }
  906. }
  907. /*
  908.  * Local variables:
  909.  * tab-width: 4
  910.  * c-basic-offset: 4
  911.  * End:
  912.  */
  913. ?>