Games-Axmud

 view release on metacpan or  search on metacpan

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

            $entry->set_icon_from_stock('secondary', 'gtk-yes');

            # Change the button's image to mark this IV as being set to undef
            my $image2 = Gtk3::Image->new_from_stock('gtk-remove', 'menu');
            $button->set_image($image2);
            # Give the button a new tooltip
            $button->set_tooltip_text('This IV is already set to \'undef\'');
        });

        # Respond when the user types something in the box
        $entry->signal_connect('changed' => sub {

            my $text = $entry->get_text();
            $self->ivAdd('editHash', $iv, $text);

            if ($self->checkEntry($text, $mode, $min, $max)) {
                $entry->set_icon_from_stock('secondary', 'gtk-yes');
            } else {
                $entry->set_icon_from_stock('secondary', 'gtk-no');
            }

            # Contents of the entry can't possibly be 'undef' any more
            my $image3 = Gtk3::Image->new_from_stock('gtk-clear', 'menu');
            $button->set_image($image3);
            # Give the button a new tooltip
            $button->set_tooltip_text('Click to set this IV to \'undef\'');
        });

        # Add the button to the grid (the entry has already been added)
        $button->set_hexpand(FALSE);
        $button->set_vexpand(FALSE);
        $leftAttach = $rightAttach - 1;
        $grid->attach(
            $button,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $entry;
    }

    sub addComboBox {

        # Adds a Gtk3::ComboBox at the specified position in the window's Gtk3::Grid
        #
        # Example calls:
        #   my $comboBox = $self->addComboBox($grid, 'some_IV', \@comboList, 'some_title', TRUE,
        #       0, 6, 0, 1);
        #   my $comboBox = $self->addComboBox($grid, 'some_IV', \@comboList, '', FALSE,
        #       0, 6, 0, 1);
        #
        # Expected arguments
        #   $grid           - The tab's Gtk3::Grid object
        #   $iv             - A string naming the IV set when the user chooses an item in the combo
        #                       box. If 'undef', nothing happens when the user chooses an item in
        #                       the box; it's up to the calling function to check the box's state
        #   $listRef        - Reference to a list with initial values (can be an empty list)
        #   $title          - A string used as a title, e.g. 'Choose your favourite colour' - if an
        #                       empty string, the item at the top of the combobox list is the
        #                       current value of the IV
        #   $noUndefFlag    - If set to TRUE, the combo is populated only with the items in
        #                       $listRef. If set to FALSE (or 'undef'), the first item in the combo
        #                       is an empty value used to set the IV to 'undef'
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #                   - The position of the combo box in the grid
        #
        # Optional arguments
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::ComboBox created

        my (
            $self, $grid, $iv, $listRef, $title, $noUndefFlag, $leftAttach, $rightAttach,
            $topAttach, $bottomAttach, $check
        ) = @_;

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

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

            return undef;
        }

        # Create the combobox
        my $comboBox = Gtk3::ComboBoxText->new();

        # Populate the combobox
        if ($title) {

            # The first item in the combobox list is a title
            $comboBox->append_text($title);
            $comboBox->set_active(0);

        } elsif ($iv) {

            if ($noUndefFlag) {

                if (defined $self->editObj->$iv) {

                    # The first item is the current value of the IV, if there is one
                    $comboBox->append_text($self->editObj->$iv);
                    # Make this the active item
                    $comboBox->set_active(0);
                }

            } else {

                # The first item is an empty line, for setting the IV to 'undef'
                $comboBox->append_text('');

                if (defined $self->editObj->$iv) {

                    # The second item is the current value of the IV, if there is one
                    $comboBox->append_text($self->editObj->$iv);
                    # Make this the active item
                    $comboBox->set_active(1);

                } else {

                    # Make the 'undef' option the active item
                    $comboBox->set_active(0);
                }
            }

        } elsif (! $noUndefFlag) {

            # The first item is an empty line, for setting the IV to 'undef'
            $comboBox->append_text('');
            # Make the 'undef' option the active item
            $comboBox->set_active(0);
        }

        foreach my $item (@$listRef) {

            # Don't show the current value of the IV twice
            if (
                ! $iv
                || ! defined $self->editObj->$iv
                || $item ne $self->editObj->$iv
            ) {
                $comboBox->append_text($item);
            }
        }

        if (! $iv && $noUndefFlag) {

            # The active item hasn't been set yet
            $comboBox->set_active(0);
        }

        if ($iv) {

            $comboBox->signal_connect('changed' => sub {

                my $text = $comboBox->get_active_text();

                # If the user has selected the title, ignore it
                if (! $title || $text ne $title) {

                    # If the user has selected the empty line at the top, set the IV to 'undef'
                    if (! $text) {

                        $self->ivAdd('editHash', $iv, undef);

                    # Otherwise set the IV to the specified value
                    } else {

                        $self->ivAdd('editHash', $iv, $text);
                    }
                }
            });
        }

        # Add the combobox to the grid
        $comboBox->set_hexpand(TRUE);
        $comboBox->set_vexpand(FALSE);
        $grid->attach(
            $comboBox,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $comboBox;
    }

    sub addTextView {

        # Adds a Gtk3::TextView at the specified position in the window's Gtk3::Grid
        #
        # Example calls:
        #   my $textView = $self->addTextView($grid, 'some_IV', TRUE,
        #       0, 6, 0, 1);
        #   my $textView = $self->addTextView($grid, 'some_IV', FALSE,
        #       0, 6, 0, 1,
        #       TRUE, FALSE, TRUE,
        #       -1, 120);
        #
        # Expected arguments
        #   $grid       - The tab's Gtk3::Grid object
        #   $iv         - A string naming the IV set when the user modifies the contents of the
        #                   textview. If 'undef', nothing happens when the user modifies the
        #                   contents; it's up to the calling function to check the textview's state
        #   $editableFlag
        #               - Flag set to TRUE if the textView should be editable, FALSE if it shouldn't
        #                   be editable
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #               - The position of the textview in the grid
        #
        # Optional arguments
        #   $listFlag   - Flag set to TRUE if the contents of the textview should be treated as a
        #                   list, FALSE (or 'undef') if it should be treated as a single string
        #                   containing newline characters. Default value is TRUE (treat as a list)
        #   $removeEmptyFlag
        #               - Flag set to TRUE if empty lines should be removed when the IV is set,
        #                   FALSE (or 'undef') if they should be retained. Default value is TRUE
        #                   (remove lines)
        #   $removeSpaceFlag
        #               - Flag set to TRUE if lines should have leading/trailing whitespace removed
        #                   when the IV is set, FALSE (or 'undef') if not. Default value is TRUE
        #                   (remove leading/trailing whitespace)
        #   $noScrollFlag
        #               - Flag set to TRUE if word-wrap mode should be turned on, preventing a
        #                   horizontal scrollbar, FALSE (or 'undef') if the textview should scroll
        #                   in both dimensions. Default value is FALSE (scroll in both dimensions)
        #   $width, $height
        #               - The width and height (in pixels) of the frame containing the list. If
        #                   specified, values of -1 mean 'don't set this value'. The default values
        #                   are (-1, -1)
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::TextView created (inside a Gtk::ScrolledWindow)

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

            my $value = $entry->get_text();
            # Check whether $value is a valid value, or not
            if (! $self->checkEntry($value, $mode, $min, $max)) {

                # Can't use this value
                $self->ivDelete('attribHash', $attrib);
                $entry->set_icon_from_stock('secondary', 'gtk-no');

            } else {

                # This is a valid value, so use it
                $self->ivAdd('attribHash', $attrib, $value);
                $entry->set_icon_from_stock('secondary', 'gtk-yes');
            }
        });

        # Set the width, if specified
        if (defined $widthChars) {

            $entry->set_width_chars($widthChars);
        }

        # Set the maximum number of characters, if specified
        if (defined $maxChars) {

            $entry->set_max_length($maxChars);
        }

        # Add the entry to the grid
        $entry->set_hexpand(TRUE);
        $entry->set_vexpand(FALSE);
        $grid->attach(
            $entry,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $entry;
    }

    sub useComboBox {

        # Adapted from $self->addComboBox
        # Adds a Gtk3::ComboBox at the specified position in the window's Gtk3::Grid. Instead of
        #   setting an IV in $self->editHash, sets a key-value pair in $self->attribHash
        #
        # Example calls:
        #   my $comboBox = $self->useComboBox($grid, 'some_attribute', \@comboList, 'some_title',
        #       0, 6, 0, 1);
        #   my $comboBox = $self->useComboBox($grid, 'some_attribute', \@comboList, '',
        #       0, 6, 0, 1);
        #
        # Expected arguments
        #   $grid      - The tab's Gtk3::Grid object
        #   $attrib     - The name of the attribute set when the check button is toggled (matches
        #                   a key in $self->attribHash and GA::Interface::Trigger->attribHash)
        #   $listRef    - Reference to a list with initial values (can be an empty list)
        #   $title      - A string used as a title, e.g. 'Choose your favourite colour' - if an
        #                   empty string, the item at the top of the combobox list is the current
        #                   value of the attribute
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #               - The position of the combo box in the grid
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::ComboBox created

        my (
            $self, $grid, $attrib, $listRef, $title, $leftAttach, $rightAttach, $topAttach,
            $bottomAttach, $check
        ) = @_;

        # Local variables
        my $current;

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

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

            return undef;
        }

        # Create the combobox
        my $comboBox = Gtk3::ComboBoxText->new();

        # Populate the combobox
        if ($title) {

            # The first item in the combobox list is a title
            $comboBox->append_text($title);
            $comboBox->set_active(0);

        } else {

            $current = $self->editObj->ivShow('attribHash', $attrib);
            if ($current) {

                # The first item is the current value of the IV, if there is one
                $comboBox->append_text($current);
                # Make this the active item
                $comboBox->set_active(0);
            }
        }

        foreach my $item (@$listRef) {

            # Don't show the current value of the IV twice
            if (! $current || $item ne $current) {

                $comboBox->append_text($item);
            }
        }

        $comboBox->signal_connect('changed' => sub {

            my $text = $comboBox->get_active_text();

            # If the user has selected the title, ignore it
            if (! $title || $text ne $title) {

                # If the user has selected the empty line at the top, set the attribute to an
                #   empty string
                if (! $text) {

                    $self->ivAdd('attribHash', $attrib, '');

                # Otherwise set the attribute to the specified value
                } else {

                    $self->ivAdd('attribHash', $attrib, $text);
                }
            }
        });

        # Add the combobox to the grid
        $comboBox->set_hexpand(TRUE);
        $comboBox->set_vexpand(FALSE);
        $grid->attach(
            $comboBox,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $comboBox;
    }

    # Add widget support functions

    sub checkEntry {

        # Called by $self->addEntryWithIcon
        # Check whether the text entered in an entry box is a valid value for the IV, or not
        #
        # Expected arguments
        #   $value      - The value currently in the entry box
        #   $mode       - Set to 'int', 'odd', 'even', 'float', 'string' or a reference to a
        #                   function
        #               - If 'int', an integer is expected with the specified min/max values
        #               - If 'odd', an odd-numbered integer with the specified min/max value is
        #                   expected. If the minimum value is less than 1, 1 is used instead
        #               - If 'even', an even-numbered integer with the specified min/max value is
        #                   expected. If the minimum value is less than 0, 0 is used instead
        #               - If 'float', a floating point number is expected with the specified min/max
        #                   values
        #               - If 'string', a string is expected (which might be a number) with the
        #                   specified min/max length
        #               - If 'regex', a valid regex is expected with the specified min/max length
        #               - If a function reference, a function is called which should return 'undef'
        #                   or 1, depending on the value of the entry; the icon is set accordingly
        #   $min, $max  - The values described above (ignored when $mode is a function reference).
        #                   If $min is 'undef', there is no minimum; if $max is 'undef', there is no
        #                   maximum
        #
        # Return values
        #   'undef' on improper arguments or if $value is an invalid value for the IV
        #   1 if $value is a valid value for the IV

        my ($self, $value, $mode, $min, $max, $check) = @_;

        # Local variables
        my $result;

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

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

        # 'int' mode
        if ($mode eq 'int') {

            if (
                ! defined $value

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

        );

        # Check for improper arguments
        if (! defined $slWidget || ! defined $columns || ! defined $iv || defined $check) {

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

        # Import the hash being displayed
        if (defined $self->ivShow('editHash', $iv)) {

            # Use the current hash
            $hashRef = $self->ivShow('editHash', $iv);
            %ivHash = %$hashRef;

        } else {

            # Use the original hash
            %ivHash = $self->editObj->ivPeek($iv);
        }

        # Get a sorted list of keys, so they can be displayed in alphabetical order
        @sortedList = sort {lc($a) cmp lc($b)} (keys %ivHash);

        # Compile the simple list data
        foreach my $key (@sortedList) {

            push (@dataList, $key, $ivHash{$key});
        }

        # Reset the simple list
        $self->resetListData($slWidget, [@dataList], $columns);

        return 1;
    }

    sub resetComboBox {

        # Can be called by anything
        # Resets the contents of a combo box
        #
        # Expected arguments
        #   $combo      - The combo box to reset
        #
        # Optional arguments
        #   @comboList  - List of items to add to the combo box. If the list is empty, the combo
        #                   box is emptied
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $combo, @comboList) = @_;

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

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

        # Empty the combobox
        my $treeModel = $combo->get_model();
        $treeModel->clear();

        # Fill it with the new list of items
        if (@comboList) {

            foreach my $item (@comboList) {

                $combo->append_text($item);
            }

            $combo->set_active(0);
        }

        return 1;
    }

    # Data accessors

    sub getEditHash_scalarIV {

        # Can be called by anything
        # $self->editHash can contain scalar values, in the form
        #   $hash{'name_of_iv'} = scalar_value
        # This function can be called to return the scalar value. However, if the IV hasn't yet been
        #   added to $self->editHash, this function returns the contents of the IV in
        #   $self->editObj, instead
        #
        # Expected arguments
        #   $iv - The IV to be checked; a key in $self->editHash or an IV in $self->editObj
        #
        # Return values
        #   'undef' on improper arguments
        #   Otherwise, returns a scalar value (may be 'undef')

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

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

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

        # Check the specified IV actually exists in $self->editHash
        if (! $self->ivExists('editHash', $iv)) {

            # It doesn't, so return the contents of the list IV, instead
            return $self->editObj->$iv;

        } else {

            return $self->ivShow('editHash', $iv);
        }
    }

    sub getEditHash_listIV {

        # Can be called by anything
        # $self->editHash can contain lists, in the form
        #   $hash{'name_of_iv'} = reference_to_anonymous_list

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

        # Tab complete
        return 1;
    }

    sub triggerAttributesTab_addRadioButtons {

        # Called by $self->triggerAttributes2Tab to add radio buttons for setting an attribute
        #
        # Expected arguments
        #   $grid       - The Gtk3::Grid
        #   $labelText  - The label text to use (e.g. 'Italics')
        #   $attrib     - The attibute to set (e.g. 'style_italics')
        #   $row        - The Gtk3::Grid row on which the radio buttons are drawn
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $grid, $labelText, $attrib, $row, $check) = @_;

        # Check for improper arguments
        if (
            ! defined $grid || ! defined $labelText || ! defined $attrib || ! defined $row
            || defined $check
        ) {
            return $axmud::CLIENT->writeImproper(
                $self->_objClass . '->triggerAttributesTab_addRadioButtons',
                @_,
            );
        }

        $self->addLabel($grid, $labelText,
            1, 2, $row, ($row + 1));
        my ($group, $radioButton) = $self->useRadioButton(
            $grid, undef,
            'Do not change',        # Radio button name
            $attrib,                # Attribute to set
            0,                      # Attribute set to this value when toggled
            TRUE,                   # Sensitive widget
            2, 4, $row, ($row + 1));

        ($group, $radioButton) = $self->useRadioButton(
            $grid, $group, 'Yes', $attrib, 1, TRUE,
            4, 5, $row, ($row + 1));

        ($group, $radioButton) = $self->useRadioButton(
            $grid, $group, 'No', $attrib, 2, TRUE,
            5, 6, $row, ($row + 1));

        return 1;
    }

    sub triggerAttributesTab_setColours {

        # Called by $self->triggerAttributes2Tab to add radio buttons for setting a colour attribute
        #
        # Expected arguments
        #   $grid           - The Gtk3::Grid
        #   $labelText      - The label text to use (e.g. 'Text colour')
        #   $attrib         - The attibute to set (e.g. 'style_text')
        #   $comboListRef   - Reference to a list of standard colour tags to display in a combobox
        #   $row            - The Gtk3::Grid row on which the radio buttons are drawn
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $grid, $labelText, $attrib, $comboListRef, $row, $check) = @_;

        # Check for improper arguments
        if (
            ! defined $grid || ! defined $labelText || ! defined $attrib || ! defined $row
            || defined $check
        ) {
            return $axmud::CLIENT->writeImproper(
                $self->_objClass . '->triggerAttributesTab_setColours',
                @_,
            );
        }

        $self->addLabel($grid, $labelText,
            7, 9, $row, ($row + 1));
        my $entry = $self->addEntry($grid, undef, FALSE,
            9, 12, $row, ($row + 1));
        $entry->set_text($self->editObj->ivShow('attribHash', $attrib));

        my $comboBox = $self->addComboBox($grid, undef, $comboListRef, '',
            TRUE,               # No 'undef' value used
            7, 10, ($row + 1), ($row + 2));

        my $button = $self->addButton(
            $grid,
            'Set',
            'Set this standard colour tag as the ' . lc($labelText),
            undef,
            10, 12, ($row + 1), ($row + 2));
        $button->signal_connect('clicked' => sub {

            my $text = $comboBox->get_active_text();

            # If the user has selected the empty line at the top, set the attribute to an empty
            #   string
            if (! $text) {

                $self->ivAdd('attribHash', $attrib, '');

            # Otherwise set the attribute to the specified value
            } else {

                $self->ivAdd('attribHash', $attrib, $text);
                $comboBox->set_active(0);
            }

            $entry->set_text($self->ivShow('attribHash', $attrib));
        });

        $self->addLabel($grid, 'xterm tag',
            7, 8, ($row + 2), ($row + 3));
        my $entry2 = $self->addEntryWithIcon($grid, undef, \&triggerAttributesTab_checkXTerm, 0, 0,
            8, 10, ($row + 2), ($row + 3));
        $entry2->set_icon_from_stock('secondary', 'gtk-yes');   # (Empty box is valid)

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


            $entry3->set_max_length($maxChars);
        }

        # Obscure text in the entry boxes, if necessary
        if ($obscureMode) {

            if ($obscureMode == 1 || $obscureMode == 3 || $obscureMode == 5 || $obscureMode == 7) {

                $entry->set_visibility(FALSE);
            }

            if ($obscureMode == 2 || $obscureMode == 3 || $obscureMode >= 6) {

                $entry2->set_visibility(FALSE);
            }

            if ($obscureMode >= 4) {

                $entry3->set_visibility(FALSE);
            }
        }

        # 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 . '->showTripleComboDialogue');

        # Get the responses. If the user clicked 'cancel', $response will be 'reject'
        # Otherwise, user clicked 'ok', and we need to get the contents of the two boxes
        $response = $dialogueWin->run();
        if ($response eq 'accept') {

            $responseText = $entry->get_text();
            $responseText2 = $entry2->get_text();
            $responseText3 = $entry3->get_text();

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

            # 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,

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

                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(
                    $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
                    )
                ),
            );

        } else {

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

        my $comboBox = Gtk3::ComboBoxText->new();
        $vBox2->pack_start($comboBox, FALSE, FALSE, $spacing);
        # Fill the combobox with the specified lines, and display the first line
        foreach my $line (@$listRef) {

            $comboBox->append_text($line);
        }
        $comboBox->set_active(0);

        # 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 . '->showComboDialogue');

        # Prepare text-to-speech (TTS) code. Get a hash of the response buttons, in the form
        #   $buttonHash{'response'} = Gtk3::Button
        $buttonHash{'ok'} = $dialogueWin->get_widget_for_response('accept');
        if (@$listRef && ! $singleFlag) {

            $buttonHash{'cancel'} = $dialogueWin->get_widget_for_response('reject');
        }

        if ($axmud::CLIENT->systemAllowTTSFlag && $axmud::CLIENT->ttsDialogueFlag) {

            # Perform TTS for this window
            $axmud::CLIENT->ttsAddUrgentJob($title, 'dialogue');
            $axmud::CLIENT->ttsAddUrgentJob($text, 'dialogue');

            # Read out buttons, when in focus
            foreach my $response (keys %buttonHash) {

                my $button = $buttonHash{$response};

                $button->signal_connect('grab-focus' => sub {

                    my $label = $button->get_label();

                    if (! defined $lastThing || $lastThing ne $button) {

                        $axmud::CLIENT->ttsAddUrgentJob(
                            # ($label is in the form 'gtk-yes', 'gtk-no' etc)
                            substr($label, 4) . ' button',
                            'dialogue',
                            # Override other TTS urgent jobs, such as the $title and $text above
                            TRUE,
                        );
                    }

                    # Don't use TTS to read out the same button label consecutively
                    $lastThing = $button;
                });
            }

            # Intercept page up/page down, and make it skip 10 lines, rather than going to the
            #   top/bottom
            $comboBox->signal_connect('key-press-event' => sub {

                my ($widget, $event) = @_;

                # Local variables
                my ($keycode, $standard, $index);

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

                $standard = $axmud::CLIENT->reverseKeycode($keycode);

                if ($standard eq 'page_up' || $standard eq 'page_down') {

                    $index = $comboBox->get_active();
                    if ($index > -1) {

                        if ($standard eq 'page_up') {

                            $index -= 10;
                            if ($index < 0) {

                                $index = 0;
                            }

                        } else {

                            $index += 10;
                            if ($index >= (scalar @$listRef)) {

                                $index = (scalar @$listRef) - 1;
                            }
                        }

                        $comboBox->set_active($index);

                        # Return 1 to show that we have interfered with this keypress
                        return 1;
                    }
                }

                # Return 'undef' to show that we haven't interfered with this keypress
                return undef;
            });

            # Read out selected items
            $comboBox->signal_connect('key-release-event' => sub {

                my $text = $comboBox->get_active_text();

                # (Use tab/cursor keys to nagivate the widgets)
                if (! defined $lastThing || $lastThing ne $text) {

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

                # Don't use TTS to read out the same combo item consecutively
                $lastThing = $text;

                return undef;
            });

            $comboBox->signal_connect('changed' => sub {

                my $text = $comboBox->get_active_text();

                # (Use the mouse to focus on the combobox)
                if (! defined $lastThing || $lastThing ne $text) {

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

                # Don't use TTS to read out the same combo item consecutively
                $lastThing = $text;

                return undef;
            });

            # Make sure that the first item in the combobox has been read out
            if (! defined $lastThing || (@$listRef && $lastThing ne $$listRef[0])) {

                if (@$listRef) {

                    $axmud::CLIENT->ttsAddUrgentJob(
                        $$listRef[0] . ' selected',
                        'dialogue',
                    );

                } else {

                    $axmud::CLIENT->ttsAddUrgentJob(
                        'There is nothing to select',
                        'dialogue',
                    );
                }
            }

            # Don't use TTS to read out the same combo item consecutively
            if (@$listRef) {

                $lastThing = $$listRef[0];
            }
        }

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

            $responseText = $comboBox->get_active_text();

            if ($axmud::CLIENT->systemAllowTTSFlag && $axmud::CLIENT->ttsDialogueFlag) {

                $axmud::CLIENT->ttsAddUrgentJob(
                    $responseText . ' entered',
                    'dialogue',
                    TRUE,
                );
            }

        } else {

            if ($axmud::CLIENT->systemAllowTTSFlag && $axmud::CLIENT->ttsDialogueFlag) {

                $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 {

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

        if (! $stateFlag) {

            $entry->set_state('insensitive');
        }

        # Set the width, if specified
        if (defined $widthChars) {

            $entry->set_width_chars($widthChars);
        }

        # Set the maximum number of characters, if specified
        if (defined $maxChars) {

            $entry->set_max_length($maxChars);
        }

        # If a callback function was specified, apply it
        if ($funcRef) {

            $entry->signal_connect('activate' => sub {

                &$funcRef($self, $entry, $entry->get_text());
            });
        }

        # Add the entry to the grid
        $entry->set_hexpand(TRUE);
        $entry->set_vexpand(FALSE);
        $grid->attach(
            $entry,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $entry;
    }

    sub addComboBox {

        # Adds a Gtk3::ComboBox at the specified position in a Gtk3::Grid
        # NB This function does not contain a ->signal_connect method - the calling function must
        #   specify its own one
        #
        # Example calls:
        #   my $comboBox = $self->addComboBox(
        #       $grid, \&itemSelected, \@comboList, 'some_title', TRUE,
        #       0, 6, 0, 1);
        #   my $comboBox = $self->addComboBox(
        #       $grid, undef, \@comboList, '', FALSE,
        #       0, 6, 0, 1);
        #
        # The referenced function (if specified) receives an argument list in the form:
        #   ($self, combo_box_widget, selected_text)
        #
        # Expected arguments
        #   $grid           - The Gtk3::Grid itself
        #   $funcRef        - Reference to the function to call when the user selects something in
        #                       the combobox. If 'undef', it's up to the calling function to create
        #                       a ->signal_connect method
        #   $listRef        - Reference to a list with initial values (can be an empty list)
        #   $title          - A string used as a title, e.g. 'Choose your favourite colour' - if
        #                       'undef', a title isn't used (use an empty string for an initially-
        #                       empty combobox)
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #                   - The position of the combo box in the table
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::ComboBox created

        my (
            $self, $grid, $funcRef, $listRef, $title, $leftAttach, $rightAttach, $topAttach,
            $bottomAttach, $check,
        ) = @_;

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

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

            return undef;
        }

        # Create the combobox
        my $comboBox = Gtk3::ComboBoxText->new();

        # Populate the combobox
        if (defined $title) {

            # The first item in the combobox list is a title
            $comboBox->append_text($title);
        }

        foreach my $item (@$listRef) {

            $comboBox->append_text($item);
        }

        $comboBox->set_active(0);

        # If a callback function was specified, apply it
        if ($funcRef) {

            $comboBox->signal_connect('changed' => sub {

                my $text = $comboBox->get_active_text();

                # If the user has selected the title, ignore it
                if (! defined $title || $text ne $title) {

                    &$funcRef($self, $comboBox, $text);
                }
            });
        }

        # Add the combobox to the grid
        $comboBox->set_hexpand(TRUE);
        $comboBox->set_vexpand(FALSE);
        $grid->attach(
            $comboBox,
            $leftAttach,
            $topAttach,
            ($rightAttach - $leftAttach),
            ($bottomAttach - $topAttach),
        );

        return $comboBox;
    }

    sub addTextView {

        # Adds a Gtk3::TextView at the specified position in a Gtk3::Grid
        # NB This function does not contain a ->signal_connect method - the calling function must
        #   specify its own one
        #
        # Example calls:
        #   my $textView = $self->addTextView($grid, $self->winType, undef, undef, TRUE,
        #       0, 6, 0, 1);
        #   my $textView = $self->addTextView($grid, undef, undef, "Hello\nworld", FALSE,
        #       0, 6, 0, 1,
        #       -1, 120);
        #
        # The referenced function (if specified) receives an argument list in the form:
        #   ($self, textview_widget, buffer_widget, buffer_text)
        # ...where 'buffer_text' is a string containing one or more lines, separated by newline
        #   characters
        #
        # Expected arguments
        #   $grid           - The Gtk3::Grid itself
        #   $colourScheme   - The name of the colour scheme to use (matches a key in
        #                       GA::Client->colourSchemeHash; you should normally use the window
        #                       type, as in the example above). If 'undef', the system's
        #                       preferred colours/fonts are used. If the specified colour scheme
        #                       doesn't exist, the colour scheme matching the window type is used
        #   $funcRef        - Reference to the function to call when the user edits the contents of
        #                       the textview. If 'undef', it's up to the calling function to create
        #                       a ->signal_connect method
        #   $string         - String composed of one or lines separated by newline characters. If
        #                       'undef', the textview is initially empty
        #   $editableFlag   - Flag set to TRUE if the textView should be editable, FALSE if it
        #                       shouldn't be editable
        #   $leftAttach, $rightAttach, $topAttach, $bottomAttach
        #                   - The position of the textview in the table
        #
        # Optional arguments
        #   $width, $height
        #               - The width and height (in pixels) of the frame containing the list. If
        #                   specified, values of -1 mean 'don't set this value'. The default values
        #                   are (-1, -1)
        #
        # Return values
        #   'undef' on improper arguments or if the widget's position in the Gtk3::Grid is invalid
        #   Otherwise the Gtk3::TextView created (inside a Gtk::ScrolledWindow)

        my (
            $self, $grid, $colourScheme, $funcRef, $string, $editableFlag, $leftAttach,



( run in 1.033 second using v1.01-cache-2.11-cpan-8dfa8b56332 )