Games-Axmud

 view release on metacpan or  search on metacpan

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

                return $self->error(
                    $session, $inputString,
                    'Invalid time \'' . $number . '\' (must be a positive number)',
                );
            }

            # Convert it to seconds, and create a partial confirmation message in advance
            if ($hoursFlag) {

                if ($number == 1) {
                    $string = '1 hour';
                } else {
                    $string = $number . ' hours';
                }

                $number *= 3600;

            } elsif ($minsFlag) {

                if ($number == 1) {
                    $string = '1 minute';
                } else {
                    $string = $number . ' minutes';
                }

                $number *= 60;

            } else {

                if ($number == 1) {
                    $string = '1 second';
                } else {
                    $string = $number . ' seconds';
                }
            }
        }

        # There can be multiple Countdown tasks running; find the most recent one
        $taskObj = $session->ivShow('currentTaskNameHash', 'countdown_task');
        if ($taskObj) {

            # Countdown task running. If it's already counting down/up, we need to start a new task
            #   (or use one of the others)
            if ($taskObj->countMode ne 'default') {

                OUTER: foreach my $otherTaskObj ($session->ivValues('currentTaskHash')) {

                    if (
                        $otherTaskObj->name eq 'countdown_task'
                        && $otherTaskObj->countMode eq 'default'
                    ) {
                        $taskObj = $otherTaskObj;
                        last OUTER;
                    }
                }
            }
        }

        if (! $taskObj) {

            # No countdown task running (or all existing tasks busy), so start a new one
            $taskObj = Games::Axmud::Task::Countdown->new($session, 'current');
            if (! $taskObj) {

                return $self->error(
                    $session, $inputString,
                    'General error creating a new Countdown task',
                );

            } elsif ($number) {

                # Give the task its initial settings
                $taskObj->initClock($type, $number);

                return $self->complete(
                    $session, $standardCmd,
                    'Countdown task initialised; counting ' . $type . ' from '. $string,
                );

            } else {

                return $self->complete($session, $standardCmd, 'Countdown task started');
            }

        } else {

            # Countdown task running and is available to start counting down/up
            $taskObj->startClock($type, $number);

            return $self->complete(
                $session, $standardCmd,
                'Countdown task updated; counting ' . $type . ' from '. $string,
            );
        }
    }

    sub findTask {

        # Called by GA::Cmd::HaltTask->do, KillTask->do, PauseTask->do, ResumeTask->do,
        #   ResetTask->do, OpenWindow->do and CloseWindow->do (or by any other code)
        # Searches for tasks in the current tasklist matching the string $taskName, and returns the
        #   blessed references of all matches in a list
        # $taskName can match a task label (stored in GA::Client->taskLabelHash), a task's formal
        #   name (stored in GA::Client->taskPackageHash), or the unique name of a task in the
        #   current tasklist (stored in GA::Session->currentTaskHash)
        # If $taskName is set to '-a', then all tasks in the current tasklist are returned
        #
        # Expected arguments
        #   $session    - The calling function's GA::Session
        #   $string     - The string to analyse (e.g. 'status'), or the switch '-a' to fetch all
        #                   current tasks
        #
        # Return values
        #   An empty list on improper arguments or if no matching tasks are found
        #   Otherwise returns a list of blessed references to matching tasks

        my ($self, $session, $string, $check) = @_;

        # Local variables
        my (
            $taskName,

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

        # Optional arguments
        #   $session        - The GA::Session from which this function was called. If 'undef',
        #                       the new window's ->session is the same as this window's session
        #                       (which might be 'undef', too)
        #   %configHash     - Hash containing any number of key-value pairs needed for this
        #                       particular 'free' window; for example, for example,
        #                       GA::PrefWin::TaskStart uses it to specify a task name and type.
        #                       Set to an empty hash if not required
        #
        # Return values
        #   'undef' on improper arguments or if the child 'free' window can't be created
        #   Otherwise returns the blessed reference to the child window

        my ($self, $packageName, $session, %configHash) = @_;

        # Check for improper arguments
        if (! defined $packageName) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->quickFreeWin', @_);
        }

        return $self->createFreeWin(
            $packageName,       # Compulsory
            undef,
            $session,           # May be 'undef'
            undef,
            undef,
            undef,
            %configHash,
        );
    }

    # 'dialogue' windows

    sub closeDialogueWin {

        # Can be called by anything to close a 'dialogue' window early (especially one that won't
        #   close itself)
        # For example, called by GA::Client->start and GA::Session->setupProfiles after an earlier
        #   call to the 'dialogue' window created by $self->showBusyWin
        #
        # Expected arguments
        #   $dialogueWin    - The 'dialogue' window to close
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $dialogueWin, $check) = @_;

        # Check for improper arguments
        if (! defined $dialogueWin || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->closeDialogueWin', @_);
        }

        # Close the window
        $dialogueWin->destroy();

        # For a 'dialogue' window created by $self->showBusyWin, we need to update a GA::Client IV
        if ($axmud::CLIENT->busyWin && $axmud::CLIENT->busyWin eq $dialogueWin) {

            $axmud::CLIENT->set_busyWin();
        }

        return 1;
    }

    sub addDialogueIcon {

        # Called by many of the following functions that open some kind of Gtk3::Dialogue
        # Takes the 'dialogue' window's main Gtk3::VBox, and splits it (using a Gtk3::HBox) into
        #   two, with a standard icon on the left, and a new Gtk3::VBox on the right
        # Makes a simple 'dialogue' window look a lot nicer (see $self->showEntryDialogue for an
        #   example of how it works)
        #
        # Expected arguments
        #   $vBox           - The 'dialogue' window's main Gtk3::VBox
        #
        # Optional arguments
        #   $path           - Full filepath to an image file to use; if 'undef' or the file doesn't
        #                       exist, the standard icon is used
        #   $noFrameFlag    - TRUE if the image should be drawn without an enclosing frame, FALSE
        #                       (or 'undef') otherwise. (Set to TRUE when called by
        #                       $self->showMsgDialogue)
        #
        # Return values
        #   'undef' on improper arguments
        #   Otherwise returns the new VBox, contained within the existing main one

        my ($self, $vBox, $path, $noFrameFlag, $check) = @_;

        # Local variables
        my $spacing;

        # Check for improper arguments
        if (! defined $vBox || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->addDialogueIcon', @_);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # Draw widgets
        my $hBox = Gtk3::HBox->new(FALSE, 0);
        $vBox->pack_start($hBox, TRUE, TRUE, 0);

        my $vBox2 = Gtk3::VBox->new(FALSE, 0);
        $hBox->pack_start($vBox2, TRUE, TRUE, $spacing);

        my $vBox3 = Gtk3::VBox->new(FALSE, 0);
        $hBox->pack_start($vBox3, TRUE, TRUE, $spacing);

        if (! $noFrameFlag) {

            # (This code block is designed for Axmud icons, sized 64x64 and above)
            my $frame = Gtk3::Frame->new(undef);
            $vBox2->pack_start($frame, FALSE, FALSE, $spacing);
            $frame->set_size_request(64, 64);
            $frame->set_shadow_type($axmud::CLIENT->constShadowType);

            if (! $path || ! -e $path) {

lib/Games/Axmud/Generic.pm  view on Meta::CPAN


            my $image = Gtk3::Image->new_from_file($path);
            $frame->add($image);

        } else {

            # (This code block is designed for the Gtk dialogue icon replacements, sized 32x32)
            $vBox2->set_size_request(48, 48);

            my $image = Gtk3::Image->new_from_file($path);
            $vBox2->pack_start($image, FALSE, FALSE, $spacing);
        }

        return $vBox3;
    }

    sub showMsgDialogue {

        # Can be called by any function
        # Creates a standard Gtk3::MessageDialog and returns the response (if any)
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #   $icon           - 'info', 'warning', 'error', 'question'
        #   $text           - The message to display. Can be pango markup text, or just plain text
        #   $buttonType     - 'none', 'ok', 'close', 'cancel', 'yes-no', 'ok-cancel'
        #
        # Optional arguments
        #   $defaultResponse
        #                   - If defined, the default button ('yes', 'no', etc)
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   'undef' on improper arguments, or if unrecognised values for $icon and/or $buttonType
        #       are specified
        #   Otherwise returns the user response (e.g. returns 'yes' if the user clicks on the 'yes'
        #       button)

        my ($self, $title, $icon, $text, $buttonType, $defaultResponse, $noSplitFlag, $check) = @_;

        # Local variables
        my (
            $spacing, $response,
            @argList, @list,
            %buttonHash,
        );

        # Check for improper arguments
        if (
            ! defined $title || ! defined $icon || ! defined $text || ! defined $buttonType
            || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->showMsgDialogue', @_);
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # Check that $icon and $buttonType are valid values
        if (
            $icon ne 'info' && $icon ne 'warning' && $icon ne 'error' && $icon ne 'question'
        ) {
            return $axmud::CLIENT->writeError(
                'Unrecognised value \'' . $icon . '\' for icon argument',
                $self->_objClass . '->showMsgDialogue',
            );
        }

        # Convert $buttonType into an argument list
        if ($buttonType eq 'ok') {
            @argList = ('gtk-ok', 'ok');
        } elsif ($buttonType eq 'close') {
            @argList = ('gtk-close', 'close');
        } elsif ($buttonType eq 'cancel') {
            @argList = ('gtk-cancel', 'cancel');
        } elsif ($buttonType eq 'yes-no') {
            @argList = ('gtk-no', 'no', 'gtk-yes', 'yes');
        } elsif ($buttonType eq 'ok-cancel') {
            @argList = ('gtk-cancel', 'cancel', 'gtk-ok', 'ok');
        } elsif ($buttonType ne 'none') {

            return $axmud::CLIENT->writeError(
                'Unrecognised value \'' . $icon . '\' for button type argument',
                $self->_objClass . '->showMsgDialogue',
            );
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            $title,
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            @argList,
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            # (In case TTS is being used and another 'dialogue' window is about to open, make sure
            #   the window is visibly closed)
            $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showMsgDialogue');
        });

        # Set the default response, if specified
        if (defined $defaultResponse) {

            $dialogueWin->set_default_response($defaultResponse);
        }

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

                $axmud::CLIENT->ttsAddUrgentJob(
                    $response . ' selected',
                    'dialogue',
                    TRUE,
                );

            } else {

                $axmud::CLIENT->ttsAddUrgentJob(
                    'Cancelled',
                    'dialogue',
                    TRUE,
                );
            }
        }

        # Destroy the window and return the response
        $dialogueWin->destroy();
        $self->restoreFocus();

        # (In case TTS is being used and another 'dialogue' window is about to open, make sure the
        #   window is visibly closed)
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showMsgDialogue');

        return $response;
    }

    sub showFileChooser {

        # Can be called by any function
        # Creates a standard Gtk3::FileChooserDialog and returns the response (if any)
        #
        # Expected arguments
        #   $title          - The title of the window, e.g. 'Select file to load'
        #   $type           - 'open', 'save', 'select-folder', 'create-folder'
        #
        # Optional arguments
        #   $arg            - If $type = 'open', set the current folder (this behaviour is
        #                       discouraged, but it's sometimes appropriate for Axmud code). If
        #                       $type = 'save', suggest a filename using $arg. Ignored if 'undef' or
        #                       if $type is not 'open' or 'save'
        #
        # Return values
        #   'undef' on improper arguments, if $type is invalid, if the file chooser window can't be
        #       opened or if no file is selected
        #   Otherwise returns a path to the selected file

        my ($self, $title, $type, $arg, $check) = @_;

        # Local variables
        my $fileName;

        # Check for improper arguments
        if (! defined $title || ! defined $type || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->showFileChooser', @_);
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Check that $type is a valid type
        if (
            $type ne 'open' && $type ne 'save' && $type ne 'select-folder'
            && $type ne 'create-folder'
        ) {
            return $self->writeError(
                'Unrecognised file choose type \'' . $type . '\'',
                $self->_objClass . '->showFileChooser',
            );
        }

        # Open the file chooser window
        my $dialogueWin = Gtk3::FileChooserDialog->new(
            $title,
            $self->winWidget,
            $type,
            'gtk-cancel' => 'cancel',
            'gtk-ok' => 'ok'
        );

        if (! $dialogueWin) {

            return undef;
        }

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();
        });

        if (defined $arg) {

            # If loading a file, set the current folder
            if ($type eq 'open') {

                $dialogueWin->set_current_folder($arg);

            # If saving a file, suggest a filename
            } elsif ($type eq 'save' && defined $arg) {

                $dialogueWin->set_current_name($arg);
            }
        }

        # Get the file
        if ($dialogueWin->run eq 'ok') {

            $fileName = $dialogueWin->get_filename();
        }

        # Close the window
        $dialogueWin->destroy();
        $self->restoreFocus();

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

            # Return the path of the selected file
            return $fileName;

        } else {

            # No file selected
            return undef;
        }
    }

    sub showEntryDialogue {

        # Can be called by any function
        # Prompts the user to enter some text into the entry box; returns the response if the 'ok'
        #   button is pressed, but 'undef' if either the cancel button is pressed or the window is
        #   closed
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #   $text           - The message to display. Can be pango markup text, or just plain text
        #
        # Optional arguments
        #   $maxChars       - The maximum number of chars allowed in the entry box (if 'undef', no
        #                       maximum)
        #   $entryText      - The initial text to put in the entry box (if 'undef', no initial text)
        #   $obscureModeFlag
        #                   - If set to TRUE, text in the entry box is obscured. If set to FALSE (or
        #                       'undef'), text is visible
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #   $singleFlag     - Set when called by GA::CLIENT->connectBlind (or by any other code that
        #                       might want to remove the 'Cancel' button). If TRUE, only an 'OK'
        #                       button is used. If FALSE (or 'undef'), both an 'OK' and 'Cancel'
        #                       buttons are used
        #
        # Return values
        #   'undef' on improper arguments or if the user doesn't enter some text
        #   Otherwise returns the user response (the contents of the entry box)

        my (
            $self, $title, $text, $maxChars, $entryText, $obscureModeFlag, $noSplitFlag,
            $singleFlag, $check
        ) = @_;

        # Local variables
        my (
            $spacing, $starText, $lastThing, $response, $responseText, $confirmMsg,
            %buttonHash,
        );

        # Check for improper arguments
        if (! defined $title || ! defined $text || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->showEntryDialogue', @_);
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # Show the dialogue window
        my $dialogueWin;
        if ($singleFlag) {

            $dialogueWin = Gtk3::Dialog->new(
                $title,
                $self->winWidget,
                Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
                'gtk-ok'     => 'accept',
            );

        } else {

            $dialogueWin = Gtk3::Dialog->new(
                $title,
                $self->winWidget,
                Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
                'gtk-cancel' => 'reject',
                'gtk-ok'     => 'accept',
            );
        }

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            # (In case TTS is being used and another 'dialogue' window is about to open, make sure
            #   the window is visibly closed)
            $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showEntryDialogue');
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);
        if (! $noSplitFlag) {

            $label->set_markup(
                Glib::Markup::escape_text(
                    $axmud::CLIENT->splitText(
                        $text,
                        0,                  # No maximum rows
                        $axmud::CLIENT->constDialogueLabelSize,
                                            # Maximum characters per line
                        FALSE,              # No ellipsis required
                        TRUE,               # Don't use hyphens when splitting words

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

        #   window is visibly closed)
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showEntryDialogue');

        # Return the response
        if ($obscureModeFlag && defined $starText) {

            # The obscured '********' text has not been modified, so we can return the original
            #   unmodified $entryText
            return $entryText;

        } else {

            # Otherwise, return the contents of the entry box
            return $responseText;
        }
    }

    sub showDoubleEntryDialogue {

        # Can be called by any function
        # Similar to $self->showEntryDialogue, but contains two entry boxes; returns the contents of
        #   both boxes
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #   $labelText      - The label above the first entry box. Can be pango markup text, or just
        #                       plain text
        #
        # Optional arguments
        #   $labelText2     - The label above the second entry box. If 'undef', no second label is
        #                       used (but the second entry box is still used)
        #   $maxChars       - The maximum number of chars allowed in both entry boxes (if 'undef',
        #                       no maximum)
        #   $obscureMode    - Sets which of the entry boxes has its text obscured
        #                       - 'default' (or 'undef') - no text is obscured
        #                       - 'first'                - first box is obscured
        #                       - 'second'               - second box is obscured
        #                       - 'both'                 - both boxes are obscured
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   An empty list on improper arguments or if the user doesn't enter some text in either
        #       entry box
        #   Otherwise a list of two elements, containing the text in both entry boxes

        my (
            $self, $title, $labelText, $labelText2, $maxChars, $obscureMode, $noSplitFlag, $check
        ) = @_;

        # Local variables
        my (
            $spacing, $response, $responseText, $responseText2,
            @emptyList,
        );

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # Check for improper arguments
        if (! defined $title || ! defined $labelText || defined $check) {

            $axmud::CLIENT->writeImproper($self->_objClass . '->showDoubleEntryDialogue', @_);
            return @emptyList;
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            $title,
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            'gtk-cancel' => 'reject',
            'gtk-ok'     => 'accept',
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @emptyList;
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        # First label and entry
        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);
        if (! $noSplitFlag) {

            $label->set_markup(
                Glib::Markup::escape_text(
                    $axmud::CLIENT->splitText(
                        $labelText,
                        0,                  # No maximum rows
                        $axmud::CLIENT->constDialogueLabelSize,
                                            # Maximum characters per line
                        FALSE,              # No ellipsis required
                        TRUE,               # Don't use hyphens when splitting words
                    )
                ),
            );

        } else {

            $label->set_markup(Glib::Markup::escape_text($labelText));

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

        }
    }

    sub showTripleEntryDialogue {

        # Can be called by any function
        # Similar to $self->showEntryDialogue, but contains three entry boxes; returns the contents
        #   of all three boxes
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #   $labelText      - The label above the first entry box. Can be pango markup text, or just
        #                       plain text
        #
        # Optional arguments
        #   $labelText2     - The label above the second entry box. If 'undef', no second label is
        #                       used (but the second entry box is still used)
        #   $labelText3     - The label above the third entry box. If 'undef', no third label is
        #                       used (but the third entry box is still used)
        #   $maxChars       - The maximum number of chars allowed in all entry boxes (if 'undef',
        #                       no maximum)
        #   $obscureMode    - Sets which of the entry boxes has its text obscured
        #                       - 0 (or 'undef')    - no text is obscured (000)
        #                       - 1                 - first box is obscured (001)
        #                       - 2                 - second box is obscured (010)
        #                       - 3                 - first/second boxes are obscured (011)
        #                       - 4                 - third box is obscured (100)
        #                       - 5                 - first/third boxes are obscured (101)
        #                       - 6                 - second/third boxes are obscured (110)
        #                       - 7                 - all boxes are obscured (111)
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   An empty list on improper arguments or if the user doesn't enter some text in either
        #       entry box
        #   Otherwise a list of three elements, containing the text in both entry boxes

        my (
            $self, $title, $labelText, $labelText2, $labelText3, $maxChars, $obscureMode,
            $noSplitFlag, $check,
        ) = @_;

        # Local variables
        my (
            $spacing, $response, $responseText, $responseText2, $responseText3,
            @emptyList,
        );

        # Check for improper arguments
        if (! defined $title || ! defined $labelText || defined $check) {

            $axmud::CLIENT->writeImproper($self->_objClass . '->showTripleEntryDialogue', @_);
            return @emptyList;
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            $title,
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            'gtk-cancel' => 'reject',
            'gtk-ok'     => 'accept',
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @emptyList;
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        # First label and entry
        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);
        if (! $noSplitFlag) {

            $label->set_markup(
                Glib::Markup::escape_text(
                    $axmud::CLIENT->splitText(
                        $labelText,
                        0,                  # No maximum rows
                        $axmud::CLIENT->constDialogueLabelSize,
                                            # Maximum characters per line
                        FALSE,              # No ellipsis required
                        TRUE,               # Don't use hyphens when splitting words
                    )
                ),
            );

        } else {

            $label->set_markup(Glib::Markup::escape_text($labelText));
        }

        my $entry = Gtk3::Entry->new();
        $vBox2->pack_start($entry, FALSE, FALSE, $spacing);
        if (defined $maxChars && $axmud::CLIENT->intCheck($maxChars, 1)) {

            $entry->set_max_length($maxChars);

lib/Games/Axmud/Generic.pm  view on Meta::CPAN


            # Return the response
            return ($responseText, $responseText2, $responseText3);

        } else {

            # Destroy the window
            $dialogueWin->destroy();
            $self->restoreFocus();

            # Return the response
            return @emptyList;
        }
    }

    sub showComboDialogue {

        # Can be called by any function
        # Shows a short message in a 'dialogue' window with the buttons 'ok' and 'cancel'
        # Prompts the user to choose a line from a combobox; returns the chosen line if the 'ok'
        #   button is pressed, but 'undef' if either the cancel button is pressed or the window is
        #   closed
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #   $text           - The message to display. Can be pango markup text, or just plain text
        #
        # Optional arguments
        #   $listRef        - Reference to a list of scalars to be used in the combo box. If
        #                       'undef', the combo box will be empty
        #   $singleFlag     - Set when called by GA::CLIENT->connectBlind (or by any other code that
        #                       might want to remove the 'Cancel' button). If TRUE, only an 'OK'
        #                       button is used. If FALSE (or 'undef'), both an 'OK' and 'Cancel'
        #                       buttons are used
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   'undef' on improper arguments, if the user doesn't choose a line or if @lineList is
        #       empty
        #   Otherwise returns the user response (the text of the selected line)

        my ($self, $title, $text, $listRef, $singleFlag, $noSplitFlag, $check) = @_;

        # Local variables
        my (
            $spacing, $lastThing, $response, $responseText,
            %buttonHash,
        );

        # Check for improper arguments
        if (! defined $title || ! defined $text || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->showComboDialogue', @_);
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # If $listRef was not specified, use an empty list
        if (! defined $listRef) {

            @$listRef = ();
        }

        # Show the 'dialogue' window. If $listRef is empty, don't show a 'cancel' button
        my $dialogueWin;
        if (! @$listRef || $singleFlag) {

            $dialogueWin = Gtk3::Dialog->new(
                $title,
                $self->winWidget,
                Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
                'gtk-ok'     => 'accept',
            );

        } else {

            $dialogueWin = Gtk3::Dialog->new(
                $title,
                $self->winWidget,
                Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
                'gtk-cancel' => 'reject',
                'gtk-ok'     => 'accept',
            );
        }

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            # (In case TTS is being used and another 'dialogue' window is about to open, make sure
            #   the window is visibly closed)
            $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showComboDialogue');
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);

        if (! $noSplitFlag) {

            $label->set_markup(
                Glib::Markup::escape_text(

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

                $axmud::CLIENT->ttsAddUrgentJob('Cancelled', 'dialogue', TRUE);
            }
        }

        # Destroy the window
        $dialogueWin->destroy();
        $self->restoreFocus();

        # (In case TTS is being used and another 'dialogue' window is about to open, make sure the
        #   window is visibly closed)
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showComboDialogue');

        return $responseText;
    }

    sub showDoubleComboDialogue {

        # Can be called by any function
        # Similar to $self->showDoubleEntryDialogue, but contains two combo boxes; returns the
        #   contents of both boxes
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #
        # Optional arguments
        #   $labelText      - The label above the first combo box. Can be pango markup text, or just
        #                       plain text. If 'undef', no first label is used (but the combo box is
        #                       still used)
        #   $labelText2     - The label above the second combo box. If 'undef', no second label is
        #                       used (but the combo box is still used)
        #   $listRef        - Reference to a list of scalars to be used in the first combo box. If
        #                       'undef', the first combo box will be empty
        #   $listRef2       - Reference to a list of scalars to be used in the second combo box. If
        #                       'undef', the second combo box will be empty
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   An empty list on improper arguments
        #   Otherwise a list of two elements, containing the contents of the two combo boxes

        my ($self, $title, $labelText, $labelText2, $listRef, $listRef2, $noSplitFlag, $check) = @_;

        # Local variables
        my (
            $spacing, $response, $responseText, $responseText2,
            @emptyList,
        );

        # Check for improper arguments
        if (! defined $title || defined $check) {

            $axmud::CLIENT->writeImproper($self->_objClass . '->showDoubleComboDialogue', @_);
            return @emptyList;
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # If $listRef/$listRef2 were not specified, use empty lists
        if (! defined $listRef) {

            @$listRef = ();
        }

        if (! defined $listRef2) {

            @$listRef2 = ();
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            $title,
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            'gtk-cancel' => 'reject',
            'gtk-ok'     => 'accept',
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @emptyList;
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        # First label (optional) and combo (not optional)
        my $label;
        if ($labelText) {

            $label = Gtk3::Label->new();
            $label->set_alignment(0, 0);

            if (! $noSplitFlag) {

                $label->set_markup(
                    Glib::Markup::escape_text(
                        $axmud::CLIENT->splitText(
                            $labelText,
                            0,                  # No maximum rows
                            $axmud::CLIENT->constDialogueLabelSize,
                                                # Maximum characters per line
                            FALSE,              # No ellipsis required
                            TRUE,               # Don't use hyphens when splitting words

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

    }

    sub showEntryComboDialogue {

        # Can be called by any function
        # Similar to $self->showDoubleEntryDialogue, but contains an entry box above a combo box;
        #   returns the contents of both boxes
        # Optionally displays a combo above an entry box, but note that the order of the arguments
        #   remains unchanged
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'File Save'
        #
        # Optional arguments
        #   $labelText      - The label above the entry box. Can be pango markup text, or just plain
        #                       text. If 'undef', no first label is used (but the entry box is still
        #                       used)
        #   $labelText2     - The label above the combo box. If 'undef', no second label is used
        #                       (but the combo box is still used)
        #   $listRef        - Reference to a list of scalars to be used in the combo box. If
        #                       'undef', the combo box will be empty
        #   $maxChars       - The maximum number of chars allowed in the entry box (if 'undef', no
        #                       maximum)
        #   $reverseFlag    - If set to TRUE, shows a combo above an entry box; if set to FALSE (or
        #                       'undef'), shows an entry above a combo box
        #   $quickFlag      - If set to TRUE, pressing the ENTER key while the cursor is in the
        #                       entry box closes the window; FALSE or 'undef' if the user must
        #                       actually click the 'OK' or 'Cancel' buttons
        #                       buttons are used
        #   $noSplitFlag    - If TRUE, the message $text is not automatically split into shorter
        #                       lines (because the calling function has already added newline
        #                       characters as it requires). If FALSE (or 'undef'), the message
        #                       $text is split into lines of no more than 40 characters
        #
        # Return values
        #   An empty list on improper arguments or if the user doesn't enter some text in the entry
        #       box
        #   Otherwise a list of two elements, containing the contents of the entry box and the
        #       active contents of the combo box

        my (
            $self, $title, $labelText, $labelText2, $listRef, $maxChars, $reverseFlag, $quickFlag,
            $noSplitFlag, $check,
        ) = @_;

        # Local variables
        my (
            $spacing, $response, $responseText, $responseText2,
            @emptyList,
        );

        # Check for improper arguments
        if (! defined $title || defined $check) {

            $axmud::CLIENT->writeImproper($self->_objClass . '->showEntryComboDialogue', @_);
            return @emptyList;
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the correct spacing size for 'dialogue' windows
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;

        # If $listRef was not specified, use an empty list
        if (! defined $listRef) {

            @$listRef = ();
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            $title,
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            'gtk-cancel' => 'reject',
            'gtk-ok'     => 'accept',
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @emptyList;
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        # First label (optional) and entry (not optional)
        my $label;
        if ($labelText) {

            $label = Gtk3::Label->new();
            $label->set_alignment(0, 0);

            if (! $noSplitFlag) {

                $label->set_markup(
                    Glib::Markup::escape_text(
                        $axmud::CLIENT->splitText(
                            $labelText,
                            0,                  # No maximum rows
                            $axmud::CLIENT->constDialogueLabelSize,
                                                # Maximum characters per line
                            FALSE,              # No ellipsis required
                            TRUE,               # Don't use hyphens when splitting words
                        )
                    ),
                );

            } else {

lib/Games/Axmud/Generic.pm  view on Meta::CPAN


            # Return the response
            return ($responseText, $responseText2);

        } elsif ($response eq 'accept' || defined $responseText) {

            $responseText = $entry->get_text();
            $responseText2 = $combo->get_active_text();

            # Destroy the window
            $dialogueWin->destroy();
            $self->restoreFocus();

            # Return the response
            return ($responseText, $responseText2);

        } else {

            # Destroy the window
            $dialogueWin->destroy();
            $self->restoreFocus();

            # Return the response
            return @emptyList;
        }
    }

    sub showColourSelectionDialogue {

        # Can be called by any function
        # Creates a standard Gtk3::ColorSelectionDialog and returns the response (if any)
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'Select colour'
        #
        # Optional arguments
        #   $initialColour  - The initial colour to use, in the form '#FFFFFF'. If not specified,
        #                       the dialogue's default colour ('#FFFFFF') is used
        #
        # Return values
        #   'undef' on expected arguments or if the user doesn't close the 'dialogue' window by
        #       clicking the 'ok' button
        #   Otherwise, returns the colour selected, in the form '#FFFFFF'

        my ($self, $title, $initialColour, $check) = @_;

        # Local variables
        my ($colorSelectionObj, $red, $green, $blue, $colorObj, $response, $hex);

        # Check for improper arguments
        if (! defined $title || defined $check) {

            return $axmud::CLIENT->writeImproper(
                $self->_objClass . '->showColourSelectionDialogue',
                @_,
            );
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::ColorSelectionDialog->new($title);
        $dialogueWin->set_transient_for($self->winWidget);

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $colorSelectionObj = $dialogueWin->get_color_selection();

        if ($initialColour) {

            # Split a string like '#FFFFFF' into three seperate colours (red, green and blue),
            #   convert them to decimals (in the range 0-255), and then convert that to a range of
            #   0-65535 - which is what Gtk3::Gdk::Color expects
            $red = hex(substr($initialColour, 1, 2)) * 257;
            $green = hex(substr($initialColour, 3, 2)) * 257;
            $blue = hex(substr($initialColour, 5, 2)) * 257;

            $colorObj = Gtk3::Gdk::Color->new($red, $green, $blue, 0);

            # Tell the Gtk3::ColorSelectionDialog to use this colour, initially
            $colorSelectionObj->set_current_color($colorObj);
        }

        # Get the response
        $response = $dialogueWin->run();
        if ($response eq 'ok') {

            # This is probably not the best way of converting #ffff25812581 to #FF2525, but it will
            #   have to do, for now
            $hex = '#' . uc(
                sprintf('%02x', int($colorSelectionObj->get_current_color->red() / 256))
                . sprintf('%02x', int($colorSelectionObj->get_current_color->green() / 256))
                . sprintf('%02x', int($colorSelectionObj->get_current_color->blue() / 256))
            );
        }

        # Destroy the window
        $dialogueWin->destroy();

        # Return the colour (or 'undef' if no colour was selected)
        return $hex;
    }

    sub showFontSelectionDialogue {

        # Can be called by any function
        # Creates a standard Gtk3::FontSelectionDialog and returns the response (if any)
        #
        # Expected arguments
        #   $title          - The title to display, e.g. 'Select font'
        #
        # Optional arguments
        #   $initialFont    - The initial font and size to use, a string in the form 'Monospace 10'
        #
        # Return values
        #   'undef' on expected arguments or if the user doesn't close the 'dialogue' window by
        #       clicking the 'ok' button
        #   Otherwise, returns the font selected as a string in the form 'Monospace 10'

        my ($self, $title, $initialFont, $check) = @_;

        # Local variables
        my ($response, $newFont);

        # Check for improper arguments
        if (! defined $title || defined $check) {

            return $axmud::CLIENT->writeImproper(
                $self->_objClass . '->showFontSelectionDialogue',
                @_,
            );
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::FontChooserDialog->new($title, $self->winWidget);
        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        if ($initialFont) {

            $dialogueWin->set_font($initialFont);
        }

        # Get the response
        $response = $dialogueWin->run();
        if ($response eq 'ok') {

            # Get the selected font
            $newFont = $dialogueWin->get_font();
        }

        # Close the 'dialogue' window
        $dialogueWin->destroy();

        # Return the font (or 'undef' if no font was selected)
        return $newFont;
    }

    sub promptRoomFlag {

        # Called by GA::EditWin::WorldModel->roomFlags1Tab
        # Prompts the user for the attributes of a new custom room flag
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   An empty list on improper arguments or if the user closes the window without clicking
        #       the 'OK' button
        #   Otherwise returns a list in the form
        #       (name, short_name, descrip, colour)
        #   ...roughly corresponding to IVs in the new GA::Obj::RoomFlag object

        my ($self, $check) = @_;

        # Local variables
        my (
            $colour, $response,
            @emptyList, @returnList,
        );

        # Check for improper arguments
        if (defined $check) {

            $axmud::CLIENT->writeImproper($self->_objClass . '->promptRoomFlag', @_);
            return @emptyList;
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Add custom room flag',

lib/Games/Axmud/Generic.pm  view on Meta::CPAN

                'Colour',
                $colour,
            );

            if ($choice) {

                $colour = $choice;
                $canvasObj = $self->fillSimpleCanvas($canvas, $canvasObj, $colour);
            }
        });

        # Display the dialogue window
        $vBox->show_all();

        # If the user clicked 'cancel', $response will be 'reject'
        $response = $dialogueWin->run();

        if ($response ne 'accept') {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @emptyList;

        # Otherwise, user clicked 'ok'
        } else {

            @returnList = ($entry->get_text(), $entry2->get_text(), $entry3->get_text(), $colour);

            $dialogueWin->destroy();
            $self->restoreFocus();

            return @returnList;
        }
    }

    sub showIrreversibleTest {

        # Called by GA::Cmd::ToggleIrreversible->do
        # Shows a 'dialogue' window with a non-functional button that contains both an icon and
        #   some text, to test whether the user's system allows both (some systems will show only
        #   the text)
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments or if the user closes the 'dialogue' window
        #   1 otherwise

        my ($self, $check) = @_;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->showIrreversibleTest', @_);
        }

        # If an earlier call to $self->showBusyWin created a popup window, close it (otherwise it'll
        #   be visible above the new dialogue window)
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Irreversible icon test',
            $self->winWidget,
            Gtk3::DialogFlags->new([qw/modal destroy-with-parent/]),
            'gtk-ok'     => 'accept',
        );

        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $self->restoreFocus();

            return undef;
        });

        # Add widgets to the 'dialogue' window
        my $vBox = $dialogueWin->get_content_area();
        # The call to ->addDialogueIcon splits $vBox in two, with an icon on the left, and a new
        #   Gtk3::VBox on the right, into which we put everything
        my $vBox2 = $self->addDialogueIcon($vBox);

        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $axmud::CLIENT->constFreeSpacingPixels);
        $label->set_alignment(0, 0);
        $label->set_markup(
            "<i>If button icons are available on your\nsystem, the button below contains\nboth an"
            . " icon and some text</i>"
        );

        my $button = Gtk3::Button->new('Hello world!');
        $vBox2->pack_start($button, FALSE, FALSE, $axmud::CLIENT->constFreeSpacingPixels);

        my $image = Gtk3::Image->new_from_file(
            $axmud::SHARE_DIR . '/icons/system/irreversible.png',
        );

        $button->set_image($image);

        my $label2 = Gtk3::Label->new();
        $vBox2->pack_start($label2, FALSE, FALSE, $axmud::CLIENT->constFreeSpacingPixels);
        $label2->set_alignment(0, 0);
        $label2->set_markup(
            "<i>Click 'OK' to end the test</i>"
        );

        # Display the 'dialogue' window. Without this combination of Gtk calls, the window is not
        #   consistently active (don't know why this works; it just does)
        $dialogueWin->show_all();
        $dialogueWin->present();
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showIrreversibleTest');

        # If the user clicked 'cancel', $response will be 'reject'
        # Otherwise, user clicked 'ok', and we might need to add initial tasks
        $dialogueWin->run();
        $dialogueWin->destroy();
        $self->restoreFocus();

        return 1;
    }

    sub showBusyWin {

        # Displays a temporary popup window (still an Axmud 'dialogue' window)
        # By default, displays the Axmud icon and the caption 'Loading...', but the calling function
        #   can specify a different logo and caption, if required
        # The popup window must be closed by the calling function, when no longer required (via a
        #   call to $self->closeDialogueWin)
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   $path       - Path of the file containing the image to show as an icon. If not
        #                   specified, the standard Axmud icon
        #   $caption    - A short piece of text to show next to the image. If not specified, the
        #                   caption 'Loading...' is used
        #
        # Return values
        #   'undef' on improper arguments or if the window is not opened
        #   1 otherwise

        my ($self, $path, $caption, $check) = @_;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->showBusyWin', @_);
        }

        # Don't show the popup window at all, if not allowed
        if (! $axmud::CLIENT->allowBusyWinFlag) {

            return undef;
        }

        # Only one of these temporary popup windows can exist at a time. If one already exists,
        #   close it
        if ($axmud::CLIENT->busyWin) {

            $self->closeDialogueWin($axmud::CLIENT->busyWin);
        }

        # Set the file path and caption text, if not specified
        if (! defined $path || ! (-e $path)) {

            $path = $axmud::CLIENT->getDialogueIcon('medium');
        }

        if (! $caption) {

            $caption = 'Loading...';
        }

        # Show the window widget
        my $dialogueWin = Gtk3::Window->new('popup');
        $dialogueWin->set_position('center-always');
        $dialogueWin->set_icon_list($axmud::CLIENT->desktopObj->{dialogueWinIconList});
        $dialogueWin->set_title($axmud::SCRIPT);
        $dialogueWin->set_border_width(0);
        $dialogueWin->set_transient_for($self->winWidget);

        $dialogueWin->signal_connect('delete-event' => sub {

            $dialogueWin->destroy();
            $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showBusyWin');
        });

        # Add widgets to the 'dialogue' window
        my $frame = Gtk3::Frame->new();
        $dialogueWin->add($frame);

        my $hBox = Gtk3::HBox->new(FALSE, 0);
        $frame->add($hBox);
        $hBox->set_border_width(10);

        my $image = Gtk3::Image->new_from_file($path);
        $hBox->pack_start($image, FALSE, FALSE, 5);

        my $label = Gtk3::Label->new();
        $hBox->pack_start($label, FALSE, FALSE, 5);
        $label->set_markup('<i><big>' . $caption . '</big></i>');
        $label->set_alignment(0.5, 0.5);

        $dialogueWin->show_all();

        # For some reason, during certain operations the icon and text are not shown in the
        #   window; the following lines make them appear
        $dialogueWin->present();
        # Update Gtk3's events queue
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->showBusyWin');
        # Update the Client IV
        $axmud::CLIENT->set_busyWin($dialogueWin);

        return $dialogueWin;
    }

    # Functions to add widgets to a Gtk3::Grid

    sub addLabel {

        # Adds a Gtk3::Label at the specified position in a Gtk3::Grid
        #
        # Example calls:
        #   my $label = $self->addLabel($grid, 'Some plain text',
        #       0, 6, 0, 1);
        #   my $label = $self->addLabel($grid, '<b>Some pango markup text</b>',
        #       0, 6, 0, 1,
        #       0, 0.5);
        #
        # Expected arguments
        #   $grid       - The Gtk3::Grid itself
        #   $text       - The text to display (plain text or pango markup text)
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #               - The position of the label in the table
        #
        # Optional arguments
        #   $alignLeft, $alignRight
        #               - Used in the call to ->set_alignment; two values in the range 0-1
        #               - If not specified, $alignLeft is set to 0, $alignRight to 0.5
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::Label created

        my (
            $self, $grid, $text, $leftAttach, $rightAttach, $topAttach, $bottomAttach, $alignLeft,
            $alignRight, $check
        ) = @_;

        # Check for improper arguments
        if (
            ! defined $grid || ! defined $text || ! defined $leftAttach || ! defined $rightAttach
            || ! defined $topAttach || ! defined $bottomAttach || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->addLabel', @_);
        }

        # Check that the position in the table makes sense
        if (! $self->checkPosn($leftAttach, $rightAttach, $topAttach, $bottomAttach)) {

            return undef;
        }

        # Set default alignment, if none specified
        if (! defined $alignLeft) {

            $alignLeft = 0;
        }

        if (! defined $alignRight) {

            $alignRight = 0.5;



( run in 2.682 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )