A state machine implementation of the various button policies used by the
dialogs. Only the policy is implemented here. Separate ButtonController
classes are needed for each GUI implementation.
+
+ Policy | ReadOnly | Apply Button | Repeated Apply
+ ========================================================================
+ OkCancel | N | N | -
+ OkCancelReadOnly | Y | N | -
+ OkApplyCancel | N | Y | Y
+ OkApplyCancelReadOnly | Y | Y | Y
+ NoRepeatedApply | N | Y | N
+ NoRepeatedApplyReadOnly | Y | Y | N
+ Preferences | N | Y | No (Ok-Close)
+ ========================================================================
+
+ Policy
+ The name of the policy
+ ReadOnly
+ Does the policy treat read-only docs differently to read-write docs?
+ This usually means that when an SMI_READ_ONLY input arrives then
+ all the buttons are disabled except Cancel/Close. The state
+ machine tracks the inputs (valid/invalid) and has states for all
+ combinations. When an SMI_READ_WRITE input arrives the appropriate
+ machine state is entered (just as if the document had always been
+ read-write).
+ NOTE: If a dialog doesn't care about the read-only status of a document
+ (and uses an appropriate policy) it can never get into a read-only state
+ so isReadOnly() can only ever return false even though the document may
+ be read-only.
+ Repeated Apply
+ Simply means that it is alright to use the Apply button multiple times
+ without requiring a change of the dialog contents. If no repeating is
+ allowed the Ok+Apply buttons are deactivated. The Preferences dialog
+ has its own special version of repeated apply handling because its Ok
+ button is actually a Save button -- its always reasonable to Save the
+ preferences if the dialog has changed since the last save.
*/
class ButtonPolicy : public noncopyable
{
//@{
/// Trigger a transition with this input.
virtual void input(SMInput) = 0;
- /// Activation status of OK
+ /// Activation status of a button
virtual bool buttonStatus(Button) = 0;
+ /// Are we in a read-only state?
+ virtual bool isReadOnly() = 0;
//@}
/**@name Typedefs */
};
-/** Defines the policy used by the Preferences dialog.
- Four buttons: Ok (Save), Apply, Cancel/Close, Restore.
+//--------------------- Actual Policy Classes ----------------------------------
+
+/** Ok and Cancel buttons for dialogs with read-only operation.
Note: This scheme supports the relabelling of Cancel to Close and vice versa.
This is based on the value of the bool state of the Button::CANCEL.
true == Cancel, false == Close
*/
-class PreferencesPolicy : public ButtonPolicy
+class OkCancelPolicy : public ButtonPolicy
{
public:
///
- PreferencesPolicy();
+ OkCancelPolicy();
///
- virtual ~PreferencesPolicy() {}
+ virtual ~OkCancelPolicy() {}
/**@name Access Functions */
//@{
*/
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
- //@}
-private:
- /**@name Private Data Members */
- //@{
- /// Current state.
- State state_;
- /// Which buttons are active for a given state.
- StateOutputs outputs_;
- ///
- StateMachine state_machine_;
- //@}
-};
-
-
-
-/** Ok and Cancel buttons for dialogs with read-only operation.
- Note: This scheme supports the relabelling of Cancel to Close and vice versa.
- This is based on the value of the bool state of the Button::CANCEL.
- true == Cancel, false == Close
- */
-class OkCancelPolicy : public ButtonPolicy
-{
-public:
- ///
- OkCancelPolicy();
- ///
- virtual ~OkCancelPolicy() {}
-
- /**@name Access Functions */
- //@{
- /// Trigger a transition with this input.
- virtual void input(SMInput);
- /// Activation status of a button.
- virtual bool buttonStatus(Button button)
- { return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ { return false; }
//@}
private:
/**@name Private Data Members */
/// Activation status of a button.
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ {
+ return RO_INITIAL == state_
+ || RO_VALID == state_
+ || RO_INVALID == state_
+ || RO_APPLIED == state_;
+ }
//@}
private:
/**@name Private Data Members */
/// Activation status of a button.
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ {
+ return RO_INITIAL == state_
+ || RO_VALID == state_
+ || RO_INVALID == state_
+ || RO_APPLIED == state_;
+ }
//@}
private:
/**@name Private Data Members */
/// Activation status of a button.
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ {
+ return RO_INITIAL == state_
+ || RO_VALID == state_
+ || RO_INVALID == state_
+ || RO_APPLIED == state_;
+ }
//@}
private:
/**@name Private Data Members */
/// Activation status of a button.
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ { return false; }
//@}
private:
/**@name Private Data Members */
/// Activation status of a button.
virtual bool buttonStatus(Button button)
{ return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ { return false; }
+ //@}
+private:
+ /**@name Private Data Members */
+ //@{
+ /// Current state.
+ State state_;
+ /// Which buttons are active for a given state.
+ StateOutputs outputs_;
+ ///
+ StateMachine state_machine_;
+ //@}
+};
+
+
+/** Defines the policy used by the Preferences dialog.
+ Four buttons: Ok (Save), Apply, Cancel/Close, Restore.
+ Note: This scheme supports the relabelling of Cancel to Close and vice versa.
+ This is based on the value of the bool state of the Button::CANCEL.
+ true == Cancel, false == Close
+ */
+class PreferencesPolicy : public ButtonPolicy
+{
+public:
+ ///
+ PreferencesPolicy();
+ ///
+ virtual ~PreferencesPolicy() {}
+
+ /**@name Access Functions */
+ //@{
+ /// Trigger a transition with this input.
+ virtual void input(SMInput);
+ /// Activation status of a button.
+ virtual bool buttonStatus(Button button)
+ { return button & outputs_[state_]; }
+ /// Are we in a read-only state?
+ virtual bool isReadOnly()
+ { return false; }
//@}
private:
/**@name Private Data Members */
#define BUTTONCONTROLLER_H
#include "ButtonPolicies.h"
+#include <list>
/** General purpose button controller for up to four buttons.
Controls the activation of the OK, Apply and Cancel buttons.
*/
ButtonController(char const * cancel, char const * close)
: bp_(), okay_(0), apply_(0), cancel_(0), undo_all_(0),
- cancel_label(cancel), close_label(close) {}
+ read_only_(), cancel_label(cancel), close_label(close) {}
/// Somebody else owns the FL_OBJECTs we just manipulate them.
~ButtonController() {}
//@}
///
void setCancelFalseLabel(char const * c)
{ close_label = c; }
+ ///
+ void addReadOnly(FL_OBJECT * obj)
+ { read_only_.push_front(obj); }
+ ///
+ void eraseReadOnly()
+ { read_only_.erase(read_only_.begin(), read_only_.end()); }
//@}
/**@name Action Functions */
close_label);
}
}
+ if (!read_only_.empty()) {
+ if (bp_.isReadOnly()) {
+ for (std::list<FL_OBJECT *>::iterator
+ iter = read_only_.begin();
+ iter != read_only_.end();
+ ++iter) {
+ fl_deactivate_object(*iter);
+ fl_set_object_lcol(undo_all_,
+ FL_INACTIVE);
+ }
+ } else {
+ for (std::list<FL_OBJECT *>::iterator
+ iter = read_only_.begin();
+ iter != read_only_.end();
+ ++iter) {
+ fl_activate_object(undo_all_);
+ fl_set_object_lcol(undo_all_,
+ FL_BLACK);
+ }
+ }
+ }
}
//@}
private:
FL_OBJECT * cancel_;
///
FL_OBJECT * undo_all_;
+ /// List of items to be deactivated when in one of the read-only states
+ std::list<FL_OBJECT *> read_only_;
//@}
/**@name Cancel/Close Button Labels */
//@{