home *** CD-ROM | disk | FTP | other *** search
- <refentry id="{@id}">
- <refnamediv>
- <refname>Using Indeterminate Mode</refname>
- <refpurpose>how to animate a progress bar to show unknown length-task activity</refpurpose>
- </refnamediv>
- <refsynopsisdiv>
- <refsynopsisdivinfo>
- <author>
- by Laurent Laville
- <authorblurb>{@link mailto:pear@laurent-laville.org}</authorblurb>
- </author>
- <copyright>November 2003, Laurent Laville</copyright>
- <releaseinfo>HTML_Progress 1.0+</releaseinfo>
- </refsynopsisdivinfo>
- </refsynopsisdiv>
- {@toc}
- <refsect1 id="{@id intro}">
- <title>Introduction</title>
- <para>
- Sometimes you can't immediately determine the length of a long-running task,
- or the task might stay stuck at the same state of completion for a long time.
- You can show work without measurable progress by putting the progress bar in
- indeterminate mode. A progress bar in indeterminate mode displays animation
- to indicate that work is occurring. As soon as the progress bar can display
- more meaningful information, you should switch it back into its default,
- determinate mode. The look and feel of indeterminate progress bars look like this:
- <para><graphic fileref="../media/screenshots/indeterminate.png"></graphic></para>
- </para>
- </refsect1>
- <refsect1 id="{@id useit}">
- <title>Using Indeterminate Mode</title>
- <para>
- In example that follow, we have created a Task Class that extends the default monitoring
- {@link HTML_Progress_Monitor} class.
- </para>
- <para>
- The most important code additions are calls to the {@link HTML_Progress::setIndeterminate()}
- method. When the user clicks the Start button, <important>setIndeterminate(true)</important>
- is invoked ({@tutorial indeterminate.pkg#useit.ex-listing line 143}) so that the user can tell
- that the task as started, even before any meaningful information about the task's progress
- can be conveyed. Once the progress bar has some concrete status to display, a call to
- <important>setIndeterminate(false)</important> ({@tutorial indeterminate.pkg#useit.ex-listing line 76})
- switches the progress bar back into its normal mode. The {@link HTML_Progress::isIndeterminate()}
- method ({@tutorial indeterminate.pkg#useit.ex-listing line 75}) is used to test the
- progress bar's current state.
- </para>
- <para>
- The other changes in the code are related to string display. A progress bar that displays
- a string is likely to be taller than one that doesn't, and, as the demo designers,
- we've arbitarily decided that this progress bar should display a string only when
- it's in the default, determinate mode. However, we want to avoid the layout ugliness
- that might result if the progress bar changed height when it changed modes.
- Thus, the code leaves in the call to {@link HTML_Progress::setStringPainted()} method
- with <emphasis>true</emphasis> value ({@tutorial indeterminate.pkg#useit.ex-listing line 39}),
- but adds a call to {@link HTML_Progress::setString()} method
- ({@tutorial indeterminate.pkg#useit.ex-listing line 40}) with <emphasis>empty string</emphasis>
- value, so that no text will be displayed. Later, when the progress bar switches from
- indeterminate to determinate mode, invoking <important>setString(null)</important>
- ({@tutorial indeterminate.pkg#useit.ex-listing line 77}) makes the progress bar display
- its default string.
- </para>
- <para>
- One change we did not make was removing the call to {@link HTML_Progress::setValue()} from
- the timer's action handler (notify method). The call doesn't do any harm because an
- indeterminate progress bar doesn't use its value property, except perharps to display it in
- the status string. In fact, keeping the progress bar's data as up-to-date as possible is a
- good practice, since some look and feels might not support indeterminate mode.
- </para>
- <refsect2 id="{@id ex-listing}">
- <title>Full example listing</title>
- <programlisting role="php">
- <![CDATA[
- <?php
- require_once ('HTML/Progress/monitor.php');
-
- class Task extends HTML_Progress_Monitor
- {
- var $_current;
-
- function Task()
- {
- $this->_current = 0;
- $this->_id = md5(microtime());
-
- $this->_form = new HTML_QuickForm('ProgressBarDialog');
-
- $renderer =& $this->_form->defaultRenderer();
- $renderer->setFormTemplate('
- <table width="450" border="0" cellpadding="3" cellspacing="2" bgcolor="#CCCC99">
- <form{attributes}>{content}
- </form>
- </table>
- ');
- $renderer->setHeaderTemplate('
- <tr>
- <td style="white-space:nowrap;background:#996;color:#ffc;" align="left" colspan="2"><b>{header}</b></td>
- </tr>
- ');
-
- $this->_form->addElement('header', 'windowsname', 'Progress...');
- $this->_form->addElement('static', 'progress');
- $this->_form->addElement('static', 'status');
-
- $buttons[] = &HTML_QuickForm::createElement('submit', 'start', 'Start', 'style="width:80px;"');
- $buttons[] = &HTML_QuickForm::createElement('submit', 'cancel', 'Cancel', 'style="width:80px;"');
- $this->_form->addGroup($buttons);
-
-
- $this->_progress = new HTML_Progress();
- $this->_progress->setIncrement(10);
- $this->_progress->setStringPainted(true); // get space for the string
- $this->_progress->setString(""); // but don't paint it
-
- $ui = & $this->_progress->getUI();
- $ui->setProgressAttributes(array(
- 'background-color' => '#e0e0e0'
- ));
- $ui->setStringAttributes(array(
- 'color' => '#996',
- 'background-color' => '#CCCC99'
- ));
- $ui->setCellAttributes(array(
- 'active-color' => '#996'
- ));
-
- $bar =& $this->_form->getElement('progress');
- $bar->setText( $this->_progress->toHtml() );
-
- $str =& $this->_form->getElement('status');
- $str->setText('<div id="status" style="color:#000000; font-size:10px;"> </div>');
-
- $this->_progress->addListener($this);
- }
-
- function notify($event)
- {
- if (is_array($event)) {
- $log = strtolower($event['log']);
- $val = $event['value'];
-
- switch (strtolower($log)) {
- case 'incvalue':
- case 'setvalue':
- $this->_current = $this->getCurrent() + 16;
- $s = $this->getMessage();
- if (!is_null($s)) {
- if ($this->_progress->isIndeterminate()) {
- $this->_progress->setIndeterminate(false);
- $this->_progress->setString(null); // display % string
- $this->_progress->setValue(0);
- }
- if ($this->isDone()) {
- $this->_progress->removeListener($this);
- $this->_progress->setString(""); // hide % string
- }
- }
- $this->_progress->display();
-
- if ($this->_progress->getPercentComplete() == 1) {
- if ($this->_progress->isIndeterminate()) {
- $this->_progress->setValue(0);
- }
- } else {
- $this->_progress->incValue();
- }
- break;
- default:
- }
- }
- }
-
- function getCurrent()
- {
- return $this->_current;
- }
-
- function getMessage()
- {
- $c = $this->getCurrent();
- $s = "completed $c out of 416";
-
- if (function_exists('ob_get_clean')) {
- $status = ob_get_clean(); // use for PHP 4.3+
- } else {
- $status = ob_get_contents(); // use for PHP 4.2+
- ob_end_clean();
- }
- $status = '<script type="text/javascript">self.setStatus("'.$s.'"); </script>';
- echo $status;
- ob_start();
-
- if ($c >= 240 ) {
- return $s;
- } else {
- return null;
- }
- }
-
- function isDone()
- {
- return ( ($this->_progress->getPercentComplete() == 1) &&
- ($this->_progress->isIndeterminate() == false) );
- }
-
-
- function isStarted()
- {
- $action = $this->_form->getSubmitValues();
-
- if (isset($action['start'])) {
- return true;
- }
-
- return false;
- }
-
- function run()
- {
- if ($this->isStarted()) {
- $this->_progress->setIndeterminate(true);
- $this->_progress->incValue();
-
- } else {
- $abort = $this->isCanceled();
- }
- }
-
- }
-
- $task = new Task();
-
- ?>
- <!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
- <head>
- <title>Indeterminate Mode Progress example</title>
- <style type="text/css">
- <!--
- <?php echo $task->getStyle(); ?>
-
- body {
- background-color: #444444;
- color: #EEEEEE;
- font-family: Verdana, Arial;
- }
-
- a:visited, a:active, a:link {
- color: yellow;
- }
- // -->
- </style>
- <script type="text/javascript">
- <!--
- <?php echo $task->getScript(); ?>
-
- function setStatus(pString)
- {
- if (isDom)
- prog = document.getElementById('status');
- if (isIE)
- prog = document.all['status'];
- if (isNS4)
- prog = document.layers['status'];
- if (prog != null)
- prog.innerHTML = pString;
- }
- //-->
- </script>
- </head>
- <body>
-
- <?php
- echo $task->toHtml();
-
- $task->run();
- ?>
-
- </body>
- </html>
- ]]>
- </programlisting>
- </refsect2>
- </refsect1>
- </refentry>
-