Games-Axmud

 view release on metacpan or  search on metacpan

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

        $self->frame->add($image);
        $self->ivPoke('image', $image);

        # (A repeat of those calls eliminates it entirely)
        $self->winShowAll($self->_objClass . '->updateGridWidgets');
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->updateGridWidgets');

        # The entry box for the world's name must not be changed
        $self->entry->set_editable(FALSE);
        # The 'add' button must be sensitive
        $self->addCharButton->set_sensitive(TRUE);
        # The 'pwd'/'account' buttons start sensitised if there's a selected character, but
        #   desensitised if not
        if ($self->miniWorldObj->selectChar) {

            $self->editPwdButton->set_sensitive(TRUE);
            $self->editAccButton->set_sensitive(TRUE);

        } else {

            $self->editPwdButton->set_sensitive(FALSE);
            $self->editAccButton->set_sensitive(FALSE);
        }

        # The 'reset world' button must be sensitive
        $self->resetWorldButton->set_sensitive(TRUE);
        # If the world profile doesn't have a ->dns, ->ipv4 or ->ipv6 value, Axmud obviously won't
        #   be able to connect to the world. Make the connect buttons desensitised until the user
        #   types something in the 'host address' entry box
        if (! $host) {

            $self->offlineButton->set_sensitive(FALSE);
            $self->connectButton->set_sensitive(FALSE);

        } else {

            # Otherwise, these two buttons start sensitised
            $self->offlineButton->set_sensitive(TRUE);
            $self->connectButton->set_sensitive(TRUE);
        }

        # Update complete
        $self->ivPoke('updateFlag', FALSE);

        # The call to ->show_all() causes the image to appear
        $self->winShowAll($self->_objClass . '->updateGridWidgets');

        return 1;
    }

    sub resetComboBox {

        # Called by $self->createGridWidgets, ->resetGridWidgets and ->updateGridWidgets
        # Not sure how to empty a Gtk3::ComboBox, so we'll just destroy the old one, and replace it
        #   with a new one
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   $destroyFlag    - If TRUE, a combobox already exists, and must be deleted. If FALSE (or
        #                       'undef'), the combobox is being drawn for the first time
        #   @charList       - A list of characters to display in the combobpx. If empty, the
        #                       combobox will contain only the '<no character>' string. If not
        #                       empty, the '<no character>' is added to @charList as the first item
        #
        # Return values
        #   'undef' on improper arguments
        #   Otherwise returns the Gtk3::ComboBox created

        my ($self, $destroyFlag, @charList) = @_;

        # Local variables
        my ($count, $index);

        # (No improper arguments to check)

        # If a Gtk3::ComboBox already exists, destroy it
        if ($destroyFlag) {

            $axmud::CLIENT->desktopObj->removeWidget($self->grid, $self->comboBox);
       }

        # Create a new combobox
        unshift (@charList, $self->noCharString);
        my $comboBox = $self->addComboBox($self->grid, undef, \@charList, undef,
            4, 8, 7, 8);

        # If the current mini-world object specifies a character, make that the combobox's active
        #   item. Otherwise, make the '<no character>' string the active item
        $index = 0;
        if ($self->miniWorldObj && $self->miniWorldObj->selectChar) {

            $count = -1;
            OUTER: foreach my $string (@charList) {

                $count++;

                if ($string eq $self->miniWorldObj->selectChar) {

                    $index = $count;
                    last OUTER;
                }
            }
        }

        $comboBox->set_active($index);
        # Also, the 'pwd'/'account' buttons should only be sensitised when there's a selected
        #   character
        if ($self->miniWorldObj) {

            if ($self->miniWorldObj->selectChar) {

                $self->editPwdButton->set_sensitive(TRUE);
                $self->editAccButton->set_sensitive(TRUE);

            } else {

                $self->editPwdButton->set_sensitive(FALSE);
                $self->editAccButton->set_sensitive(FALSE);
            }
        }

        # Now we can add the combobox's ->signal_connect, which updates the mini-world object when
        #   a character is selected
        $comboBox->signal_connect('changed' => sub {

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

            if ($char eq $self->noCharString) {

                $self->miniWorldObj->ivUndef('selectChar');
                # When no character is selected, the 'pwd'/'account' buttons must be desensitised
                $self->editPwdButton->set_sensitive(FALSE);
                $self->editAccButton->set_sensitive(FALSE);

            } else {

                $self->miniWorldObj->ivPoke('selectChar', $char);
                # When no character is selected, the 'pwd'/'account' buttons must be desensitised
                $self->editPwdButton->set_sensitive(TRUE);
                $self->editAccButton->set_sensitive(TRUE);
            }
        });

        # The call to ->show_all() makes the new combobox visible
        $self->winShowAll($self->_objClass . '->resetComboBox');

        return $comboBox;
    }

    sub updateProfile {

        # Called by $self->applyChangesCallback and ->connectWorldCallback
        # Copies changes to values, stored in the specified mini-world object, to the corresponding
        #   world profile (if it exists)
        #
        # Expected arguments
        #   $miniWorldObj   - A GA::Obj::MiniWorld
        #
        # Return values
        #   'undef' on improper arguments or if there is no world profile to update
        #   1 otherwise

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

        # Local variables
        my (
            $worldObj, $profFlag, $host, $port, $descrip,
            %newHash,
        );

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

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

        # Import the equivalent world profile object, for convenience
        $worldObj = $miniWorldObj->worldObj;
        # Is it actually a world profile, or is it a basic world object (GA::Obj::BasicWorld), which
        #   has different IVs?
        if (! $worldObj->isa('Games::Axmud::Profile::World')) {

            # It's a basic world object; nothing for this function to do
            return undef;
        }

        # (We can't change the profile's ->name)

        # ->host and ->port
        # If the host address is in the form 'deathmud.com:8888', then extract the port. Although
        #   it technically possible to use ports with only one digit, don't recognise it
        # If, at the same time, the port was specified in the other entry box, ignore the other
        $host = $miniWorldObj->ivShow('propHash', 'host');
        if ($host && $host =~ m/^(.*)\:(\d{2,5})\s*$/) {
            $host = $1;
            $port = $2;
        } else {
            $port = $miniWorldObj->ivShow('propHash', 'port');
        }

        if ($host && $host =~ m/\w/) {

            $host = $axmud::CLIENT->trimWhitespace($host);

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

            'Enter a password (optional)',
            $string,
            undef,              # No maximum chars
            2,                  # Obscure password text (only)
        );

        if ($char) {

            # Trim leading/trailing whitespace from the name, password and account name
            $char = $axmud::CLIENT->trimWhitespace($char);
            if ($pass) {

                $pass = $axmud::CLIENT->trimWhitespace($pass);
            }

            if ($account) {

                $account = $axmud::CLIENT->trimWhitespace($account);
            }

            # Check that the name is be a valid profile name
            if (
                ! $axmud::CLIENT->nameCheck($char, 16)
                || $axmud::CLIENT->ivExists('worldProfHash', $char)
            ) {
                $self->showMsgDialogue(
                    'Add character',
                    'error',
                    '\'' . $char . '\' is not a valid character profile name',
                    'ok',
                );

                return undef;
            }

            # Update the current mini-world object
            if ($pass) {

                $self->miniWorldObj->ivAdd('passwordHash', $char, $pass);
                $self->miniWorldObj->ivAdd('newPasswordHash', $char, $pass);

            } else {

                $self->miniWorldObj->ivAdd('passwordHash', $char, undef);
                $self->miniWorldObj->ivAdd('newPasswordHash', $char, undef);
            }

            if ($account) {

                $self->miniWorldObj->ivAdd('accountHash', $char, $account);
                $self->miniWorldObj->ivAdd('newAccountHash', $char, $account);

            } else {

                $self->miniWorldObj->ivAdd('accountHash', $char, undef);
                $self->miniWorldObj->ivAdd('newAccountHash', $char, undef);
            }

            $self->miniWorldObj->ivPoke('selectChar', $char);

            # Redraw the combobox
            @charList = sort {lc($a) cmp lc($b)} ($self->miniWorldObj->ivKeys('passwordHash'));
            my $comboBox = $self->resetComboBox(TRUE, @charList);
            $self->ivPoke('comboBox', $comboBox);
        }

        return 1;
    }

    sub editPasswordCallback {

        # Callback, called by anonymous subroutine in $self->createGridWidgets when the user clicks
        #   on the 'pwd' button
        # Edits the password of an existing character, storing the changes in the current mini-world
        #   object's ->passwordHash and ->newPasswordHash
        #
        # Expected arguments
        #   $widget     - The Gtk3::Button clicked
        #
        # Return values
        #   'undef' on improper arguments or if no character is selected
        #   1 otherwise

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

        # Local variables
        my ($char, $currentPass, $newPass);

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

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

        # Get the character displayed in the combobox
        $char = $self->comboBox->get_active_text();
        if (! $char || $char eq $self->noCharString) {

            # No character to edit
            return undef;
        }

        # Get the current password for this character (if any)
        $currentPass = $self->miniWorldObj->ivShow('passwordHash', $char);

        # Prompt the user to enter a new password
        $newPass = $self->showEntryDialogue(
            'Edit password',
            'Enter a new password for the \'' . $char . '\' character',
            undef,              # No maximum chars
            $currentPass,
            TRUE,               # Obscure text in the entry box
        );

        # If the user didn't close the window manually...
        if (defined $newPass) {

            if ($newPass) {

                $self->miniWorldObj->ivAdd('passwordHash', $char, $newPass);
                $self->miniWorldObj->ivAdd('newPasswordHash', $char, $newPass);

            } else {

                $self->miniWorldObj->ivAdd('passwordHash', $char, undef);
                $self->miniWorldObj->ivAdd('newPasswordHash', $char, undef);
            }
        }

        return 1;
    }

    sub editAccountCallback {

        # Callback, called by anonymous subroutine in $self->createGridWidgets when the user clicks
        #   on the 'account' button
        # Edits the associated account for an existing character, storing the changes in the current
        #   mini-world object's ->accountHash and ->newAccountHash
        #
        # Expected arguments
        #   $widget     - The Gtk3::Button clicked
        #
        # Return values
        #   'undef' on improper arguments or if no character is selected
        #   1 otherwise

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

        # Local variables
        my ($string, $char, $currentAccount, $newAccount);

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

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

        # Get the character displayed in the combobox
        $char = $self->comboBox->get_active_text();
        if (! $char || $char eq $self->noCharString) {

            # No character to edit
            return undef;
        }

        # Get the current account for this character (if any)
        $currentAccount = $self->miniWorldObj->ivShow('accountHash', $char);

        # Prompt the user to enter a new password
        $string = 'Enter the new account name associated with the \'' . $char . '\' character';
        if ($self->miniWorldObj->loginAccountMode eq 'not_required') {
            $string .= ' (not required for this world)';
        } elsif ($self->miniWorldObj->loginAccountMode eq 'required') {
            $string .= ' (recommended for this world)';
        } else {
            $string .= ' (if required for this world)';
        }

        $newAccount = $self->showEntryDialogue(
            'Edit account',
            $string,
            undef,              # No maximum chars
            $currentAccount,
        );

        # If the user didn't close the window manually...
        if (defined $newAccount) {

            if ($newAccount) {

                $self->miniWorldObj->ivAdd('accountHash', $char, $newAccount);
                $self->miniWorldObj->ivAdd('newAccountHash', $char, $newAccount);

            } else {

                $self->miniWorldObj->ivAdd('accountHash', $char, undef);
                $self->miniWorldObj->ivAdd('newAccountHash', $char, undef);
            }
        }

        return 1;
    }

    sub createWorldCallback {

        # Callback, called by anonymous subroutine in $self->createGridWidgets when the user clicks
        #   the 'create world' button (only visible when 'Create new world' is selected in the list
        #   of worlds)
        # When the currently-selected treeview item is 'create new world', creates a new world
        #   profile, and updates it with the data stored in $self->miniWorldObj
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments or if there is an error
        #   1 otherwise

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

        #
        # Expected arguments
        #   $testButton     - The Gtk3::Button that was clicked
        #
        # Return values
        #   'undef' on improper arguments or if there is an error
        #   1 otherwise

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

        # Local variables
        my (
            $worldObj,
            @testList, @charList,
        );

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

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

        # Import the global variable (for convenience)
        @testList = @axmud::TEST_MODE_LOGIN_LIST;

        # If the global variable refers to a world, for which a world profile already exists,
        #   update grid widgets as if the user had entered the global variable's value manually
        if (defined $testList[0]) {

            $worldObj = $axmud::CLIENT->ivShow('worldProfHash', $testList[0]);
            if ($worldObj) {

                # Update grid widgets for this world, unless that world is already the visible one
                if (! $self->worldObj || $worldObj ne $self->worldObj) {

                    $self->updateGridWidgets($worldObj, $worldObj->longName);
                }

                # Update grid widgets again, using the values stored in @TEST_MODE_LOGIN_LIST

                # World DNS/IP address
                if (defined $testList[1]) {

                    $self->entry2->set_text($testList[1]);
                }

                # World port
                if (defined $testList[2]) {

                    $self->entry3->set_text($testList[2]);
                }

                # Character name and password
                if (defined $testList[3] && defined $testList[4]) {

                    $self->miniWorldObj->ivAdd('passwordHash', $testList[3], $testList[4]);
                    $self->miniWorldObj->ivAdd('newPasswordHash', $testList[3], $testList[4]);

                    $self->miniWorldObj->ivPoke('selectChar', $testList[3]);

                    # Redraw the combobox
                    @charList
                        = sort {lc($a) cmp lc($b)} ($self->miniWorldObj->ivKeys('passwordHash'));

                    my $comboBox = $self->resetComboBox(TRUE, @charList);
                    $self->ivPoke('comboBox', $comboBox);
                }

                # Mark the number of connections to be set to at least 1
                $self->miniWorldObj->ivPoke('testModeFlag', TRUE);
            }
        }

        return 1;
    }

    ##################
    # Accessors - set

    sub set_consoleButton {

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

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

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

        if (! $flag) {

            # No system messages to display in the Client Console window
            $self->consoleButton->set_image(
                Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/connect/icon_console.png'),
            );

        } else {

            # At least one system message to display in the Client Console window
            $self->consoleButton->set_image(
                Gtk3::Image->new_from_file(
                    $axmud::SHARE_DIR . '/icons/connect/icon_console_alert.png',
                ),
            );
        }

        return 1;
    }

    ##################
    # Accessors - get

    sub hPaned
        { $_[0]->{hPaned} }
    sub vBox
        { $_[0]->{vBox} }
    sub frame
        { $_[0]->{frame} }
    sub image
        { $_[0]->{image} }
    sub hBox

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

            # A string to use as the window title
            title                       => $title,
            # Hash containing any number of key-value pairs needed for this particular 'config'
            #   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
            configHash                  => {%configHash},
        };

        # Bless the object into existence
        bless $self, $class;

        return $self;
    }

    ##################
    # Methods

    # Standard window object functions

#   sub winSetup {}         # Inherited from GA::Generic::FreeWin

#   sub winEnable {}        # Inherited from GA::Generic::FreeWin

#   sub winDesengage {}     # Inherited from GA::Generic::FreeWin

#   sub winDestroy {}       # Inherited from GA::Generic::FreeWin

#   sub winShowAll {}       # Inherited from GA::Generic::Win

    sub drawWidgets {

        # Called by $self->winSetup
        # Sets up the Gtk3::Window by drawing the window's widgets
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

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

        # Local variables
        my (
            $spacing, $dictObj, $comboBoxCount,
            @currentRoomList, @typeList,
        );

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

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

        # Standard spacing
        $spacing = $axmud::CLIENT->constFreeSpacingPixels;
        # Import the current Locator task (if any) and current dictionary
        $dictObj = $self->session->currentDict;

        # A list of word types in the order they'll appear in their combobox
        @typeList = (
            'sentient',
            'creature',
            'portable',
            'decoration',
            'race',
            'guild',
            'weapon',
            'armour',
            'garment',
            'adjective',
            'pseudo-noun',
            'pseudo-adjective',
            'pseudo-object',
        );

        # Create a packing box
        my $packingBox = Gtk3::VBox->new(FALSE, 0);
        $self->winBox->add($packingBox);
        $packingBox->set_border_width(0);

        # Create an image on the left
        my $hBox = Gtk3::HBox->new(FALSE, $spacing);
        $packingBox->pack_start($hBox, FALSE, FALSE, 0);

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

        my $frame = Gtk3::Frame->new(undef);
        $vBox->pack_start($frame, FALSE, FALSE, 0);
        $frame->set_size_request(64, 64);
        $frame->set_shadow_type($axmud::CLIENT->constShadowType);

        my $image = Gtk3::Image->new_from_file($axmud::CLIENT->getDialogueIcon());
        $frame->add($image);

        # Create a VBox on the right, full of editing widgets
        my $vBox2 = Gtk3::VBox->new(FALSE, $spacing);
        $hBox->pack_start($vBox2, FALSE, FALSE, 0);

        # Add three radio buttons and an entry box/combo for each (->signal_connects follow)
        my $radioButton = Gtk3::RadioButton->new_with_label(undef, 'Enter a word...');
        my $radioGroup = $radioButton->get_group();
        $vBox2->pack_start($radioButton, FALSE, FALSE, 0);

        my $entry = Gtk3::Entry->new();
        $vBox2->pack_start($entry, FALSE, FALSE, 0);

        my $radioButton2 = Gtk3::RadioButton->new_with_label(
            $radioGroup,
            '...or select a word from the current room...',
        );
        $vBox2->pack_start($radioButton2, FALSE, FALSE, 0);

        my $comboBox = Gtk3::ComboBoxText->new();
        $vBox2->pack_start($comboBox, FALSE, FALSE, 0);
        $comboBox->set_active(0);
        # Starts desensitised
        $comboBox->set_sensitive(FALSE);

        my $radioButton3 = Gtk3::RadioButton->new_with_label(
            $radioGroup,
            '...or select an unknown word',
        );
        $vBox2->pack_start($radioButton3, FALSE, FALSE, 0);

        my $comboBox2 = Gtk3::ComboBoxText->new();
        $vBox2->pack_start($comboBox2, FALSE, FALSE, 0);
        $comboBox2->set_active(0);
        # Starts desensitised
        $comboBox2->set_sensitive(FALSE);

        my $separator = Gtk3::HSeparator->new();
        $vBox2->pack_start($separator, FALSE, FALSE, 0);

        # Add a fourth widget group, comboboxes to select the types of word
        my $label = Gtk3::Label->new('What kind of word is this?');
        $vBox2->pack_start($label, FALSE, FALSE, 0);
        $label->set_alignment(0, 0.5);

        my $hBox2 = Gtk3::HBox->new(FALSE, 0);
        $vBox2->pack_start($hBox2, FALSE, FALSE, 5);

        my $comboBox3 = Gtk3::ComboBoxText->new();
        $hBox2->pack_start($comboBox3, TRUE, TRUE, 0);
        foreach my $type (@typeList) {

            $comboBox3->append_text($type);
        }
        $comboBox3->set_active(0);

        my $comboBox4 = Gtk3::ComboBoxText->new();
        $hBox2->pack_end($comboBox4, TRUE, TRUE, 0);
        $comboBox4->set_active(0);
        $comboBox4->set_sensitive(FALSE);

        # And a fifth group to specify replacement strings for pseudo nouns, adjectives and objects
        my $label2 = Gtk3::Label->new('Replacement string (if any)');
        $vBox2->pack_start($label2, FALSE, FALSE, 0);
        $label2->set_alignment(0, 0.5);

        my $entry2 = Gtk3::Entry->new();
        $vBox2->pack_start($entry2, FALSE, FALSE, 0);
        # Entry starts insensitive
        $entry2->set_sensitive(FALSE);

        my $separator2 = Gtk3::HSeparator->new();
        $vBox2->pack_start($separator2, FALSE, FALSE, 0);

        # Finally, at buttons at the bottom of the window
        my $label3 = Gtk3::Label->new('');
        $vBox2->pack_start($label3, FALSE, FALSE, 0);
        $label3->set_alignment(0, 0.5);

        my $hBox3 = Gtk3::HBox->new(FALSE, 0);
        $vBox2->pack_start($hBox3, FALSE, FALSE, $self->spacingPixels);

        my $button = Gtk3::Button->new('Add word');
        $hBox3->pack_start($button, TRUE, TRUE, 0);
        $button->set_tooltip_text('Add this word');

        my $button2 = Gtk3::Button->new('Ignore word');
        $hBox3->pack_start($button2, TRUE, TRUE, 0);
        $button2->set_sensitive(FALSE);     # Starts desensitised
        $button2->set_tooltip_text('Ignore (don\'t use) this word');

        my $button3 = Gtk3::Button->new('Refresh');
        $hBox3->pack_start($button3, TRUE, TRUE, 0);
        $button3->signal_connect('clicked' => sub {

            $self->refreshCombos($dictObj, $comboBox, $comboBox2);
        });

        my $button4 = Gtk3::Button->new('Close');
        $hBox3->pack_end($button4, TRUE, TRUE, 0);
        $button4->signal_connect('clicked' => sub {

            $self->winDestroy();
        });
        $button4->set_tooltip_text('Close the window');

        # Set the initial contents of the first two comboboxes
        $self->refreshCombos($dictObj, $comboBox, $comboBox2);

        # ->signal_connects

        # Radio buttons. Toggling them sensitises/desensitises the first three widgets
        $radioButton->signal_connect('toggled' => sub {

            if ($radioButton->get_active()) {

                $entry->set_sensitive(TRUE);
                $comboBox->set_sensitive(FALSE);
                $comboBox2->set_sensitive(FALSE);
                $button2->set_sensitive(FALSE);
            }
        });

        $radioButton2->signal_connect('toggled' => sub {

            if ($radioButton2->get_active()) {

                $entry->set_sensitive(FALSE);
                $comboBox->set_sensitive(TRUE);
                $comboBox2->set_sensitive(FALSE);
                $button2->set_sensitive(FALSE);
            }
        });

        $radioButton3->signal_connect('toggled' => sub {

            if ($radioButton3->get_active()) {

                $entry->set_sensitive(FALSE);
                $comboBox->set_sensitive(FALSE);
                $comboBox2->set_sensitive(TRUE);
                $button2->set_sensitive(TRUE);
            }
        });

        # Fourth group
        $comboBox3->signal_connect('changed' => sub {

            my $type = $comboBox3->get_active_text();
            if ($type) {

                # Empty the 'type of portable/decoration' combobox, in case we need to refill it
                if ($comboBoxCount) {

                    for (my $count = ($comboBoxCount - 1); $count >= 0; $count--) {

                        $comboBox4->remove_text($count);
                    }
                }

                # Refill the lower combobox, if necessary
                if ($type eq 'portable') {

                    foreach my $custom ($dictObj->portableTypeList) {

                        $comboBox4->append_text($custom);
                    }

                    $comboBox4->set_active(0);
                    $comboBox4->set_sensitive(TRUE);
                    $comboBoxCount = scalar $dictObj->portableTypeList;

                } elsif ($type eq 'decoration') {

                    foreach my $custom ($dictObj->decorationTypeList) {

                        $comboBox4->append_text($custom);
                    }

                    $comboBox4->set_active(0);
                    $comboBox4->set_sensitive(TRUE);
                    $comboBoxCount = scalar $dictObj->decorationTypeList;

                } else {

                    # If it's not a portable or decoration, the lower combobox must be insensitive
                    $comboBox4->set_sensitive(FALSE);
                    $comboBoxCount = 0;
                }

                if (
                    $type eq 'pseudo-noun'
                    || $type eq 'pseudo-adjective'
                    || $type eq 'pseudo-object'
                ) {
                    # Make the replacement string entry sensitive
                    $entry2->set_sensitive(TRUE);

                } else {

                    # Empty the box and make it insensitive
                    $entry2->set_text('');
                    $entry2->set_sensitive(FALSE);
                }
            }
        });

        # 'Add word' button
        $button->signal_connect('clicked' => sub {

            my (
                $word, $wordType, $category, $replace, $cmd, $result, $msg,
                @newList,
            );

            # Get the word to add
            if ($radioButton->get_active()) {
                $word = $entry->get_text();
            } elsif ($radioButton2->get_active()) {
                $word = $comboBox->get_active_text();
            } elsif ($radioButton3->get_active()) {
                $word = $comboBox2->get_active_text();
            }

            # Get the type of word, and the category (for portables/decorations)
            $wordType = $comboBox3->get_active_text();
            $category = $comboBox4->get_active_text();

            # Get the replacement string for pseudos
            $replace = $entry2->get_text();

            if ($word && $wordType) {

                # Prepare the client command to use
                $cmd = 'addword ';

                if ($wordType eq 'sentient') {
                    $cmd .= '-s <' . $word . '>';
                } elsif ($wordType eq 'creature') {
                    $cmd .= '-k <' . $word . '>';
                } elsif ($wordType eq 'race') {
                    $cmd .= '-r <' . $word . '>';
                } elsif ($wordType eq 'guild') {
                    $cmd .= '-g <' . $word . '>';
                } elsif ($wordType eq 'weapon') {
                    $cmd .= '-w <' . $word . '>';

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


                } else {

                    $msg = '<i>Failed to add ' . $wordType . ' \'' . $word . '\'</i>';
                }

            } else {

                # Clear the confirmation label
                $msg = '';
            }

            # Show the confirmation message
            $label3->set_markup($msg);

            if ($result) {

                # If we've just added a word from the room, it should be removed from the combo
                # If we've just added an unknown word, the dictionary's list of unknown words will
                #   have changed. Update the combo
                if (
                    $radioButton2->get_active()
                    || $radioButton3->get_active()
                ) {
                    $self->refreshCombos($dictObj, $comboBox, $comboBox2);
                }
            }
        });

        # 'Ignore word' button
        $button2->signal_connect('clicked' => sub {

            my $word = $comboBox2->get_active_text();
            if ($word) {

                $label3->set_markup('Ignoring \'' . $word . '\'');

                # Remove this word from the current dictionary's unknown word collection
                $self->session->currentDict->ivDelete('unknownWordHash', $word);

                # Update the combos
                $self->refreshCombos($dictObj, $comboBox, $comboBox2);
            }
        });

        # Update IVs (not worth storing widgets other than the main packing box)
        $self->ivPoke('packingBox', $packingBox);

        return 1;
    }

#   sub redrawWidgets {}    # Inherited from GA::Generic::Win

    # ->signal_connects

    # Other functions

    sub refreshCombos {

        # Called by $self->drawWidgets
        # Refreshes the contents of the first two comboboxes
        #
        # Expected arguments
        #   $dictObj    - The current dictionary
        #   $comboBox, $comboBox2
        #               - The comboboxes to refresh
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $dictObj, $comboBox, $comboBox2, $check) = @_;

        # Local variables
        my (
            $taskObj,
            @unknownList, @collectedList,
            %wordHash,
        );

        # Check for improper arguments
        if (! defined $dictObj || ! defined $comboBox || ! defined $comboBox2 || defined $check) {

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

        # Import the current Locator task (if any)
        $taskObj = $self->session->locatorTask;

        # Compile a list of words (which aren't already in the dictionary) from objects in the
        #   Locator task's current room
        if (
            $taskObj
            && $taskObj->roomObj
            && $taskObj->roomObj->tempObjList
        ) {
            OUTER: foreach my $obj ($taskObj->roomObj->tempObjList) {

                my @wordList;

                push (@wordList,
                    $obj->noun,
                    $obj->otherNounList,
                    $obj->adjList,
                    $obj->pseudoAdjList,
                    $obj->unknownWordList,
                );

                foreach my $word (@wordList) {

                    # If the word isn't in the current dictionary, mark it to be added to the
                    #   combobox. Use a hash to eliminate duplicates
                    if (
                        ! $dictObj->ivExists('combNounHash', $word)
                        && ! $dictObj->ivExists('combAdjHash', $word)
                    ) {
                        $wordHash{$word} = undef;
                    }
                }
            }

            # Convert the hash to a sorted list
            @unknownList = sort {lc($a) cmp lc($b)} (keys %wordHash);
        }

        # Import the list of unknown words collected by the Locator task and stored in the current
        #   dictionary
        @collectedList = sort {lc($a) cmp lc($b)} ($dictObj->ivKeys('unknownWordHash'));

        # Refresh the combos
        my $treeModel = $comboBox->get_model();
        $treeModel->clear();

        foreach my $item (@unknownList) {

            $comboBox->append_text($item);
        }

        $comboBox->set_active(0);

        my $treeModel2 = $comboBox2->get_model();
        $treeModel2->clear();

        foreach my $item (@collectedList) {

            $comboBox2->append_text($item);
        }

        $comboBox2->set_active(0);

        return 1;
    }

    ##################
    # Accessors - set

    ##################
    # Accessors - get
}

{ package Games::Axmud::OtherWin::SessionConsole;

    use strict;
    use warnings;
#   use diagnostics;

    use Glib qw(TRUE FALSE);

    our @ISA = qw(
        Games::Axmud::OtherWin::ClientConsole Games::Axmud::Generic::OtherWin
        Games::Axmud::Generic::FreeWin Games::Axmud::Generic::Win Games::Axmud
    );

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

            #   name and type. Set to an empty hash if not required
            configHash                  => {%configHash},
        };

        # Bless the object into existence
        bless $self, $class;

        return $self;
    }

    ##################
    # Methods

    # Standard window object functions

#   sub winSetup {}         # Inherited from GA::Generic::FreeWin

#   sub winEnable {}        # Inherited from GA::Generic::FreeWin

#   sub winDesengage {}     # Inherited from GA::Generic::FreeWin

#   sub winDestroy {}       # Inherited from GA::Generic::FreeWin

#   sub winShowAll {}       # Inherited from GA::Generic::Win

    sub drawWidgets {

        # Called by $self->winSetup
        # Sets up the Gtk3::Window by drawing the window's widgets
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

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

        # Local variables
        my (
            $width, $height, $title, $sampleText, $sampleUnderlay,
            @tagList,
            %prettyHash, %reversePrettyHash, %ansiHash,
        );

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

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

        # Import the list of Axmud standard colour/style tags (which also includes the dummy tags
        #   like 'bold', 'reverse_off' and 'attribs_off')
        @tagList = $axmud::CLIENT->constColourStyleList;
        # (For convenience, add 'attribs_off' to both the beginning and end of the list)
        unshift(@tagList, 'attribs_off');
        # Also import the hash of pretty names for each standard tag, in which the keys are the
        #   items in @tagList
        %prettyHash = $axmud::CLIENT->constPrettyTagHash;
        # Use a reverse hash too, so we can work out which combobox item was selected
        %reversePrettyHash = reverse %prettyHash;

        # Prepare a hash of ANSI escape sequences which the user can insert at any place in the
        #   textview, in the form
        #       $ansiHash{tag} = number_of_ANSI_escape_sequence
        %ansiHash = (
            (reverse $axmud::CLIENT->constANSIColourHash),
            (reverse $axmud::CLIENT->constANSIStyleHash),
        );

        $ansiHash{'bold'} = 1;
        $ansiHash{'bold_off'} = 22;
        $ansiHash{'reverse'} = 7;
        $ansiHash{'reverse_off'} = 27;
        $ansiHash{'conceal'} = 8;
        $ansiHash{'conceal_off'} = 28;
        $ansiHash{'attribs_off'} = 0;

        # Create a packing box
        my $packingBox = Gtk3::VBox->new(FALSE, 0);
        $self->winBox->add($packingBox);
        $packingBox->set_border_width(0);

        # At the top, create a textview
        my $scroller = Gtk3::ScrolledWindow->new(undef, undef);
        $packingBox->pack_start($scroller, TRUE, TRUE, 0);
        $scroller->set_shadow_type($axmud::CLIENT->constShadowType);
        $scroller->set_policy('automatic', 'automatic');
        $scroller->set_border_width(0);

        # Create a textview with default colours/fonts
        my $textView = Gtk3::TextView->new();
        $scroller->add($textView);
        my $buffer = Gtk3::TextBuffer->new();
        $textView->set_buffer($buffer);
        $textView->set_editable(TRUE);
        $textView->set_cursor_visible(TRUE);
        $axmud::CLIENT->desktopObj->setTextViewStyle($self->winType, $textView);

        # At the bottom, create a button strip in a horizontal packing box
        my $hBox = Gtk3::HBox->new(FALSE, 0);
        $packingBox->pack_end($hBox, FALSE, FALSE, $self->spacingPixels);

        # Create a combo
        my $comboBox = Gtk3::ComboBoxText->new();
        $hBox->pack_start($comboBox, FALSE, FALSE, $self->borderPixels);
        $title = 'Add an ANSI escape sequence:';
        $sampleText = 'Sample xterm-256 text colour';
        $sampleUnderlay = 'Sample xterm-256 underlay colour';
        $comboBox->append_text($title);
        foreach my $tag (@tagList) {

            $comboBox->append_text($prettyHash{$tag});

            # GA::Client->constColourStyleList doesn't include xterm colour tags, so we'll insert
            #   a sample text and a sample underlay colour right just before the style tags
            if ($tag eq 'ul_white') {

                $comboBox->append_text($sampleText);
                $comboBox->append_text($sampleUnderlay);



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