company logo

Progress bar

A progress bar is used to give the user an indication of the progress of an operation. A progress bar might be placed in a status line or window. In contrast to other control styles, the progress bar required a ProgressData instance as data source. Progress information is set at run-time in the progress data structure, which is the data source for the progress bar. The ProgressData instance passes progress data to the progress bar and allows initializing progress settings as well as setting current progress states.

The data source in the field definition (ADK_Field) for a progress bar is defined as user-defined data source of type ProgressData (auto_initialize=true) or as integer field, when referring to fixed minimum and maximum value (see fixed and variable progress bar below).

Usually, nothing special has to be set in the progress bar style definition, except, when inverted display (from top to bottom or right to left) is required.

Typically, the progress bar is initialized when starting an operation. While running, progress data is passed to the progress bar in order to display the operation state.

The GUI framework supports different ways of using progress display.

Fixed progress bar

Fixhed progress bars are used in order to display progress within a fixed range. The data source for a fixed progress bar is an integer value. In order to display proper percentage in the progress bar, a minimum and a maximum value for the data source have to be defined in the data source for the progress bar (data format options).

In order to indicate an ongoing operation without detailed information about the current state, minimum and maximum might be set to 0, which results in a continuously moving progress bar. In this cas, no data source is required at all.

In addition, a text display might be set for the progress bar in the literal value of the format option. The literal may contain following place holders:

  • %p: Percentage
  • %v: Value
  • %m: total number of steps (value - minimum)

In order to display percentage, typically %p% is passed, where %p is replaced by the computed percentage for the current value.

The example above shows the data source definition for a fixed progress control accepting values between 0 and 100. The example refers to a transient automaic field, but it could also refer to a field in a data structure. When referring to transient field, data has to be set in the data source by the application, which is not necessary for attributes in persistent instances. The progress bar automatically updates when the value in the data source changes. When the value exceeds the maximum, the progress bar starts from the beginning.

// Context function to be called in order to update

// an automatic progress field

void cProgress::Update ( int32 count ) {

  value() = count;

  refresh();

}

Variable progress bar

In order to use a progress bar with variable borders and/or variable text to be displayed for the progress bar, a ProgressData instance has to be defined as data source:

Therefore, the data type (class) has to be set to ProgressData. The data reference type should be set to user-defined in order to create an internal (transient) data instance. for creating an instance automatically when required, auto-initialize should be switched on. Since progress bar settings will be controlled via the ProgressData instance, no data format specification is required.

In order to fill the progress bar, a context class has to be associated with the field or control. Since the progress has to be initialized, updated and uninitialized, the context class should implement three functions as in the example below. A more sophisticated example you will find in the context class for the ODE status line progress bar (adk/adk/toolsBase/Designer/qlib/cProgress.cpp).

// OSI example

// set minimum ans maximum for the progress bar

void cProgress :: Initialize (int32 max_count ) {

VARIABLES

  ProgressData    &pd = property(); // ProgressData instance

PROCESS

  pd.action  = 1;  // initialize

  pd.maximum = max_count;

  pd.minimum = 0;

  visible(true);   // show progress bar

  refresh();       // process data by progress control

}

// update state

void cProgress :: Display (int32 count)

{

VARIABLES

  ProgressData    &pd = property(); // ProgressData instance

PROCESS

  pd.action   = -1;  // initialize

  pd.position = count;

  refresh();         // process data by progress control

}

// uninitialize progress display

void cProgress :: Deinitialize ( )

{

VARIABLES

  ProgressData    &pd = property(); // ProgressData instance

PROCESS

  pd.action  = -1;  // initialize

  refresh();       // process data by progress control

  visible(false);  // hide progress bar

}

Display system progress data

ODABA supports progress data display, which can be used in console functions, but also in GUI applications referring to a progress bar. Similar to system input and output, progress data requests are directed to the context set as application context in the system input/output. This is done typically in the doBeforeOpen() or doAfterOpen() of the project context, but one may assign any other context as system context.

After making the context class to the system context, this class will receive progress messages besides input and output requests, which can be passed to an appropriate progress control in the application. There are three functions, which have to be overloaded in the context class assigned to the system context:

    startProgress ()

    stopProgress ()

    displayProgress ()

The example below demonstrates the simple use of displaying system progress in a progress control (progress) in the application status bar (statusbar). The example refers to the progress control context defined in the example above. A more sophisticated example one may find in adk/adk(ToolsBase/Designer/qlib/pODE.cpp (functions startProgress(), displayProgress() and stopProgress()).

In order to support system progress, the option SystemIO.Progress has to be set to a supported value (e.g. percent). Processes that are going to submit progress information have to call SystemClass functions StartProgress(), DisplayProgress() and StopProgress().

// process producong progress information (OSI function in ODC_ImpClass)

... fragment ODC_ImpClass::doForFunctions ( ) {

...  SystemClass::StartProgress("Generate source code file for " + sys_ident,pfunctions.count);

     while ( pfunctions.next ) {

       SystemClass::DisplayProgress(pfunctions.currentPosition);

       ... do something for function

     }

...  SystemClass::StopProgress();

}

// functiond to be implemented in the context assigned as system context

int32  cProject::doBeforeOpen {

  systemContext(self);

}

cProgress  &cProject::progressContext( ) {

  return field("statusbar.progress");

}

void cProject::startProgress (odaba::progressType ptype, string title, int64 max ) {

  progressContext().Initialize(max64);

  if ( title != '' ) // show progress title in status bar

    field("statusbar").setText(title);

}

void cProject::displayProgress (string title, string text, int64 max, int64 count,

                      Time elapsed, Time remaining) {

  progressContext().Display(count);

}

void cProject::stopProgress ( ) {

  progressContext().Deinitialize();

}

Related topics