Games-Axmud

 view release on metacpan or  search on metacpan

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN


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

        # Local variables
        my $iv;

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

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

        # Don't create a new window, if it already exists
        if ($self->enabledFlag) {

            return undef;
        }

        # Create the Gtk3::Window
        my $winWidget = Gtk3::Window->new('toplevel');
        if (! $winWidget) {

            return undef;

        } else {

            # Store the IV now, as subsequent code needs it
            $self->ivPoke('winWidget', $winWidget);
            $self->ivPoke('winBox', $winWidget);
        }

        # Set up ->signal_connects (other ->signal_connects are set up in the call to
        #   $self->winEnable() )
        $self->setDeleteEvent();            # 'delete-event'
        $self->setKeyPressEvent();          # 'key-press-event'
        $self->setKeyReleaseEvent();        # 'key-release-event'
        $self->setFocusOutEvent();          # 'focus-out-event'
        # Set up ->signal_connects specified by the calling function, if any
        if ($listRef) {

            foreach my $func (@$listRef) {

                $self->$func();
            }
        }

        # Set the window title. If $title wasn't specified, use a suitable default title
        $self->setWinTitle();

        # Set the window's default size and position (this will almost certainly be changed before
        #   the call to $self->winEnable() )
        $winWidget->set_default_size(
            $axmud::CLIENT->customGridWinWidth,
            $axmud::CLIENT->customGridWinHeight,
        );

        $winWidget->set_border_width($axmud::CLIENT->constGridBorderPixels);

        # Set the icon list for this window
        $iv = $self->winType . 'WinIconList';
        $winWidget->set_icon_list($axmud::CLIENT->desktopObj->{$iv});

        # Draw the widgets used by this window
        if (! $self->drawWidgets()) {

            return undef;
        }

        # The calling function can now move the window into position, before calling
        #   $self->winEnable to make it visible, and to set up any more ->signal_connects()
        return 1;
    }

    sub winEnable {

        # Called by GA::Obj::Workspace->createGridWin or ->createSimpleGridWin
        # After the Gtk3::Window has been setup and moved into position, makes it visible and calls
        #   any further ->signal_connects that must be not be setup until the window is visible
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   $listRef    - Reference to a list of functions to call, just after the Gtk3::Window is
        #                   created (can be used to set up further ->signal_connects, if this
        #                   window needs them)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 on success

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

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

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

        # Make the window appear on the desktop
        $self->winShowAll($self->_objClass . '->winEnable');
        $self->ivPoke('enabledFlag', TRUE);

        # For windows about to be placed on a grid, briefly minimise the window so it doesn't
        #   appear in the centre of the desktop before being moved to its correct workspace, size
        #   and position
#        if ($self->workspaceGridObj && $self->winWidget eq $self->winBox) {
#
#            $self->minimise();
#        }

        # This type of window is unique to its GA::Session (only one can be open at any time, per
        #   session); inform the session it has opened
        $self->session->set_mapWin($self);

        # Set up ->signal_connects that must not be set up until the window is visible
        $self->setConfigureEvent();         # 'configure-event'
        # Set up ->signal_connects specified by the calling function, if any
        if ($listRef) {

            foreach my $func (@$listRef) {

                $self->$func();
            }
        }

        # If the automapper object is in 'track alone' mode, disable the mode
        $self->session->mapObj->set_trackAloneFlag(FALSE);

        return 1;
    }

    sub winDisengage {

        # Should not be called, in general (provides compatibility with other types of window,
        #   whose window objects can be destroyed without closing the windows themselves)
        # If called, this function just calls $self->winDestroy and returns the result
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments or if the window can't be disengaged
        #   1 on success

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

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

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

        return $self->winDestroy();
    }

    sub winDestroy {

        # Called by GA::Obj::WorkspaceGrid->stop or by any other function
        # Updates the automapper object (GA::Obj::Map), informs the parent workspace grid (if this
        #   'grid' window is on a workspace grid) and the desktop object, and then destroys the
        #   Gtk3::Window (if it is open)
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments, if the window can't be destroyed or if it has already
        #       been destroyed
        #   1 on success

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

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

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

        if (! $self->winBox) {

            # Window already destroyed in a previous call to this function
            return undef;
        }

        # If the pause window is visible, destroy it
        if ($axmud::CLIENT->busyWin) {

            $self->hidePauseWin();
        }

        # If the automapper object knows the current world model room, and if the Locator task is
        #   running and knows about the current location, and if the world model flag that permits
        #   it is set, and if this Automapper window isn't currently in 'wait' mode, let the
        #   automapper go into 'track alone' mode
        if (
            $self->mapObj->currentRoom
            && $self->session->locatorTask
            && $self->session->locatorTask->roomObj
            && $self->worldModelObj->allowTrackAloneFlag
            && $self->mode ne 'wait'
        ) {
            # Go into 'track alone' mode
            $self->mapObj->set_trackAloneFlag(TRUE);
        }

        # Update the parent GA::Obj::Map in all cases
        $self->mapObj->set_mapWin();

        # Close any 'free' windows for which this window is a parent
        foreach my $winObj ($self->ivValues('childFreeWinHash')) {

            $winObj->winDestroy();
        }

        # Inform the parent workspace grid object (if any)
        if ($self->workspaceGridObj) {

            $self->workspaceGridObj->del_gridWin($self);
        }

        # Inform the desktop object
        $axmud::CLIENT->desktopObj->del_gridWin($self);

        # Destroy the Gtk3::Window
        eval { $self->winBox->destroy(); };
        if ($@) {

            # Window can't be destroyed
            return undef;

        } else {

            $self->ivUndef('winWidget');
            $self->ivUndef('winBox');
        }

        # Inform the ->owner, if there is one
        if ($self->owner) {

            $self->owner->del_winObj($self);
        }

        # This type of window is unique to its GA::Session (only one can be open at any time, per
        #   session); inform the session it has closed
        $self->session->set_mapWin();

        return 1;
    }

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

    sub drawWidgets {

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

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

        # Local variables
        my ($menuBar, $hPaned, $treeViewScroller, $canvasFrame);

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

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

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

        # Create a menu (if allowed)

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

        # Can be called by any function
        # Redraws some or all of the menu bar, toolbar(s), treeview and canvas
        # The widgets redrawn are specified by the calling function, but are not redrawn if the
        #   right flags aren't set (e.g. the menu bar isn't redrawn if
        #   GA::Obj::WorldModel->showMenuBarFlag isn't set)
        #
        # Expected arguments
        #   @widgetList - A list of widget names. One or all of the following strings, in any order:
        #                   'menu_bar', 'toolbar', 'treeview', 'canvas'
        #
        # Return values
        #   'undef' on improper arguments or if any of the widgets in @widgetList are unrecognised
        #   1 otherwise

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

        # Local variables
        my (
            $menuBar, $hPaned, $treeViewScroller, $canvasFrame,
            @toolbarList,
            %widgetHash,
        );

        # Check for improper arguments
        if (! @widgetList) {

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

        # Check that the strings in @widgetList are valid, and add each string into a hash so that
        #   no widget is drawn more than once
        # Initialise the hash of allowed widgets
        %widgetHash = (
            'menu_bar'  => FALSE,
            'toolbar'   => FALSE,
            'treeview'  => FALSE,
            'canvas'    => FALSE,
        );

        # Check everything in @widgetList
        foreach my $name (@widgetList) {

            if (! exists $widgetHash{$name}) {

                return $self->session->writeError(
                    'Unrecognised widget \'' . $name . '\'',
                    $self->_objClass . '->redrawWidgets',
                );

            } else {

                # If the same string appears more than once in @widgetList, we only draw the widget
                #   once
                $widgetHash{$name} = TRUE;
            }
        }

        # Remove the old widgets from the vertical packing box
        if ($self->menuBar) {

            $axmud::CLIENT->desktopObj->removeWidget($self->packingBox, $self->menuBar);
        }

        foreach my $toolbar ($self->toolbarList) {

            $axmud::CLIENT->desktopObj->removeWidget($self->packingBox, $toolbar);
        }

        if ($self->hPaned) {

            foreach my $child ($self->hPaned->get_children()) {

                $self->hPaned->remove($child);
            }

            $axmud::CLIENT->desktopObj->removeWidget($self->packingBox, $self->hPaned);

        } else {

            if ($self->treeViewScroller) {

                $axmud::CLIENT->desktopObj->removeWidget(
                    $self->packingBox,
                    $self->treeViewScroller,
                );
            }

            if ($self->canvasFrame) {

                $axmud::CLIENT->desktopObj->removeWidget($self->packingBox, $self->canvasFrame);
            }
        }

        # Redraw the menu bar, if specified (and if allowed)
        if ($self->worldModelObj->showMenuBarFlag) {

            if ($widgetHash{'menu_bar'}) {

                $self->resetMenuBarIVs();

                my $menuBar = $self->enableMenu();
                if ($menuBar) {

                    # Pack the new widget
                    $self->packingBox->pack_start($menuBar,FALSE,FALSE,0);

                } else {

                    # After the error, stop trying to draw menu bars
                    $self->worldModelObj->set_showMenuBarFlag(FALSE);
                }

            # Otherwise, repack the old menu bar
            } elsif ($self->menuBar) {

                $self->packingBox->pack_start($self->menuBar,FALSE,FALSE,0);
            }
        }

        # Redraw the toolbar(s), if specified (and if allowed)
        if ($self->worldModelObj->showToolbarFlag) {

            if ($widgetHash{'toolbar'}) {

                # Reset toolbar IVs to their default state; the subsequent call to
                #   $self->enableToolbar imports the list of button sets from the world model, and
                #   updates these IVs accordinly
                $self->resetToolbarIVs();

                @toolbarList = $self->enableToolbar();
                if (@toolbarList) {

                    foreach my $toolbar (@toolbarList) {

                        # Pack the new widget
                        $self->packingBox->pack_start($toolbar, FALSE, FALSE, 0);
                    }

                } else {

                    # After the error, stop trying to draw toolbars
                    $self->worldModelObj->set_showToolbarFlag(FALSE);
                }

            # Otherwise, repack the old toolbar(s)
            } else {

                foreach my $toolbar ($self->toolbarList) {

                    $self->packingBox->pack_start($toolbar, FALSE, FALSE, 0);

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN


                        # Add the frame to the right pane
                        $hPaned->add2($canvasFrame);

                    } else {

                        # Pack the frame directly into the packing box
                        $self->packingBox->pack_start($canvasFrame, TRUE, TRUE, 0);
                    }

                } else {

                    # After the error, stop trying to draw canvases
                    $self->worldModelObj->set_showCanvasFlag(FALSE);
                }

            # Otherwise, repack the old canvas
            } elsif ($self->canvasFrame) {

                if ($hPaned) {

                    # Add the frame to the right-hand pane
                    $hPaned->add2($self->canvasFrame);

                } else {

                    # Pack the frame directly into the packing box
                    $self->packingBox->pack_start($self->canvasFrame, TRUE, TRUE, 0);
                }
            }
        }

        # Now, for each widget that is no longer drawn, set default IVs
        if (! $self->worldModelObj->showMenuBarFlag) {

            $self->resetMenuBarIVs();
        }

        if (! $self->worldModelObj->showToolbarFlag) {

            $self->resetToolbarIVs();
        }

        if (! $self->worldModelObj->showTreeViewFlag || ! $self->worldModelObj->showCanvasFlag) {

            $self->ivUndef('hPaned');
        }

        if (! $self->worldModelObj->showTreeViewFlag) {

            $self->resetTreeViewIVs();
        }

        if (! $self->worldModelObj->showCanvasFlag) {

            $self->resetCanvasIVs();
        }

        # Repack complete
        $self->winShowAll($self->_objClass . '->redrawWidgets');
        $axmud::CLIENT->desktopObj->updateWidgets($self->_objClass . '->redrawWidgets');

        return 1;
    }

    # Standard 'map' window object functions

    sub winReset {

        # Called by GA::Obj::Map->openWin to reset an existing Automapper window
        #
        # Expected arguments
        #   $mapObj     - The calling GA::Obj::Map object
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

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

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

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

        # Set new Perl object component IVs
        $self->ivPoke('mapObj', $mapObj);
        $self->ivPoke('worldModelObj', $self->session->worldModelObj);

        # Reset the current region
        $self->ivUndef('currentRegionmap');
        $self->ivUndef('currentParchment');
        $self->ivEmpty('recentRegionList');

        # Reset parchment objects (which destroys all canvas widgets except the empty one created
        #   by the call to ->resetMap)
        $self->ivEmpty('parchmentHash');
        $self->ivEmpty('parchmentReadyHash');
        $self->ivEmpty('parchmentQueueList');

        # Reset selected objects
        $self->ivUndef('selectedRoom');
        $self->ivUndef('selectedExit');
        $self->ivUndef('selectedRoomTag');
        $self->ivUndef('selectedRoomGuild');
        $self->ivUndef('selectedLabel');
        $self->ivEmpty('selectedRoomHash');
        $self->ivEmpty('selectedExitHash');
        $self->ivEmpty('selectedRoomTagHash');
        $self->ivEmpty('selectedRoomGuildHash');
        $self->ivEmpty('selectedLabelHash');

        # Reset drawing cycle IVs
        $self->tidyUpDraw();
        $self->ivEmpty('drawCycleExitHash');

        # Reset other IVs to their default values
        $self->reset_freeClickMode();
        $self->ivPoke('mode', 'wait');
        $self->ivUndef('showChar');     # Show character visits for the current character

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

        if (defined $check) {

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

        # Get the original toolbar (always the first one in this list)
        $toolbar = $self->ivFirst('toolbarList');
        if (! $toolbar) {

            return undef;
        }

        # Decide which button set to show next
        $currentSet = $self->ivShow('toolbarHash', $toolbar);
        if (! $currentSet) {

            return undef;
        }

        # Compile a list of all button sets but the current one, starting with those which appear
        #   after the current one, then those that appear before it
        #   e.g. (A B current D E F) > (D E F A B)
        @setList = $self->constButtonSetList;
        for (my $count = 0; $count < scalar @setList; $count++) {

            if ($setList[$count] eq $currentSet) {

                $foundFlag = TRUE;

            } elsif ($foundFlag) {

                push (@afterList, $setList[$count]);

            } else {

                push (@beforeList, $setList[$count]);
            }
        }

        # Go through that list, from the beginning, and use the first button set that's not already
        #   visible
        OUTER: foreach my $set (@afterList, @beforeList) {

            if (! $self->ivShow('buttonSetHash', $set)) {

                $nextSet = $set;
                last OUTER;
            }
        }

        if (! $nextSet) {

            # All button sets are visible; cannot switch set
            return undef;
        }

        # Remove the existing button set (preserving the switcher and add buttons, and the separator
        #   that follows them)
        foreach my $widget ($self->toolbarButtonList) {

            $axmud::CLIENT->desktopObj->removeWidget($toolbar, $widget);
        }

        # After the separator, we draw the specified button set. This function decides which
        #   specific function to call, and returns the result
        @buttonList = $self->chooseButtonSet($toolbar, $nextSet);

        # Add the buttons/separators to the toolbar
        foreach my $button (@buttonList) {

            my $label;

            # (Separators don't have labels, so we need to check for that)
            if (! $axmud::CLIENT->toolbarLabelFlag && $button->isa('Gtk3::ToolButton')) {

                $button->set_label(undef);
            }

            $toolbar->insert($button, -1);
        }

        # Sensitise/desensitise menu bar/toolbar items, depending on current conditions
        $self->restrictWidgets();

        # Update IVs
        $self->ivAdd('buttonSetHash', $currentSet, FALSE);
        $self->ivAdd('buttonSetHash', $nextSet, TRUE);
        $self->ivAdd('toolbarHash', $toolbar, $nextSet);
        $self->ivPoke('toolbarButtonList', @buttonList);
        $self->ivPoke('toolbarOriginalSet', $nextSet);

        # Not worth calling $self->redrawWidgets, so must do a ->show_all()
        $toolbar->show_all();

        return 1;
    }

    sub addToolbar {

        # Called by a ->signal_connect in $self->drawToolbar whenever the user clicks the original
        #   toolbar's add button
        # Creates a popup menu containing all of the button sets that aren't currently visible, then
        #   imlements the user's choice
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments or if there's an error
        #   1 otherwise

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

        # Local variables
        my (
            @list,
            %hash,
        );

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

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

        # Find the current regionmap's equivalent world model object
        $number = $self->currentRegionmap->number;
        if ($number) {

            $obj = $self->worldModelObj->ivShow('modelHash', $number);

            # Open up an 'edit' window to edit the object
            $self->createFreeWin(
                'Games::Axmud::EditWin::ModelObj::Region',
                $self,
                $self->session,
                'Edit ' . $obj->category . ' model object #' . $obj->number,
                $obj,
                FALSE,                          # Not temporary
            );
        }

        return 1;
    }

    sub regionScreenshotCallback {

        # Called by $self->enableRegionsColumn
        # Takes a screenshot of a portion of the regionmap (or the whole regionmap), at the
        #   currently displayed level, and saves it in the ../screenshots directory
        #
        # Expected arguments
        #   $type       - 'visible' for the visible portion of the canvas, 'occupied' for the
        #                   occupied portion of the canvas, and 'whole' for the whole canvas
        #
        # Return values
        #   'undef' on improper arguments, if the standard callback check fails or if the user
        #       declines to take the screenshot after a warning
        #   1 otherwise

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

        # Local variables
        my (
            $xOffset, $yOffset, $xPos, $yPos, $left, $top, $right, $bottom, $width, $height, $msg,
            $result, $file, $path, $count,
        );

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

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

        # Standard callback check
        if (! $self->currentRegionmap) {

            return undef;
        }

        # The menu column is presumably still open - which will get in the way of the screenshot.
        #   Give it a chance to close
        $axmud::CLIENT->desktopObj->updateWidgets(
            $self->_objClass . '->regionScreenshotCallback',
        );

        if ($type eq 'visible') {

            # Find the position of the top-left corner of the visible canvas
            ($xOffset, $yOffset, $xPos, $yPos) = $self->getMapPosn();
            $left = int($self->currentRegionmap->mapWidthPixels * $xPos);
            $top = int($self->currentRegionmap->mapHeightPixels * $yPos);
            # Import the size of the visible canvas
            $width = $self->canvasScrollerWidth;
            $height = $self->canvasScrollerHeight;

        } elsif ($type eq 'occupied') {

            # Find the extent of the occupied map, in pixels
            ($left, $right, $top, $bottom) = $self->findOccupiedMap();
            $width = $right - $left + 1;
            $height = $bottom - $top + 1;

        } else {

            # Import the size of the whole canvas
            $width = $self->currentRegionmap->mapWidthPixels;
            $height = $self->currentRegionmap->mapHeightPixels;
        }

        # For very large screenshots, display a warning before starting the operation
        if ($width * $height > 100_000_000) {

            $msg = 'This operation will produce a very large image (' . $width . 'x' . $height
                        . ' pixels). ' . 'Are you sure you want to continue?';

            $result = $self->showMsgDialogue(
                'Screenshot',
                'warning',
                $msg,
                'yes-no',
            );

            if ($result ne 'yes') {

                return undef;
            }
        }

        # For large-ish screenshots, show the pause window
        if ($width * $height > 5_000_000) {

            $self->showPauseWin();
        }

        # Take the screenshot
        my $surface = Cairo::ImageSurface->create('rgb24', $width, $height);
        my $cr = Cairo::Context->create($surface);
        $cr->rectangle(0, 0, $width, $height);
        $cr->set_source_rgb(1, 1, 1);
        $cr->fill();

        if ($type eq 'visible' || $type eq 'occupied') {

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

            ) || (
                $startYPosPixels < $stopYPosPixels && (
                    $clickYPosPixels < $startYPosPixels || $clickYPosPixels > $stopYPosPixels
                )
            ) || (
                $startYPosPixels > $stopYPosPixels && (
                    $clickYPosPixels > $startYPosPixels || $clickYPosPixels < $stopYPosPixels
                )
            )
        ) {
            # The mouse click is too far away from the exit to be worth checking more precisely
            return undef;

        } else {

            # The mouse click is credibly close to the exit to be worth checking more preciselhy
            return 1;
        }
    }

    # Prompt functions ('dialogue' windows unique to the Automapper window)

    sub promptGridBlock {

        # Called by $self->addRoomAtBlockCallback or ->addLabelAtBlockCallback
        # Prompts the user to enter a gridblock via a 'dialogue' window, and returns the gridblock
        #   entered
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   An empty list on improper arguments or if the user clicks the 'cancel' button
        #   Otherwise returns a list in the form (x, y, z)

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

        # Local variables
        my (
            $response, $xPosBlocks, $yPosBlocks, $zPosBlocks,
            @emptyList,
        );

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

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

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Select gridblock',
            $self->winWidget,          # Parent window is this window
            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);

        # X co-ordinate
        my $labelX = Gtk3::Label->new();
        $vBox2->pack_start($labelX, FALSE, FALSE, 5);
        $labelX->set_alignment(0, 0);
        $labelX->set_markup(
            'X co-ordinate (0-' . ($self->currentRegionmap->gridWidthBlocks - 1) . ')'
        );

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

        # Y co-ordinate
        my $labelY = Gtk3::Label->new;
        $vBox2->pack_start($labelY, FALSE, FALSE, 5);
        $labelY->set_alignment(0, 0);
        $labelY->set_markup(
            'Y co-ordinate (0-' . ($self->currentRegionmap->gridHeightBlocks - 1) . ')'
        );

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

        # Z co-ordinate
        my $labelZ = Gtk3::Label->new;
        $vBox2->pack_start($labelZ, FALSE, FALSE, 5);
        $labelZ->set_alignment(0, 0);
        $labelZ->set_markup(
            'Z co-ordinate (any value)'
        );

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

        # As a timesaver, enter the currently displayed level (if any)
        if ($self->currentRegionmap) {

            $entryZ->set_text($self->currentRegionmap->currentLevel);
        }

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

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

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

            'Default (' . $self->worldModelObj->defaultGridWidthBlocks . ' x '
            . $self->worldModelObj->defaultGridHeightBlocks. ')',
                $self->worldModelObj->defaultGridWidthBlocks,
                $self->worldModelObj->defaultGridHeightBlocks,
            'Minuscule (5 x 5)',
                5,
                5,
            'Tiny (11 x 11)',
                11,
                11,
            'Very small (21 x 21)',
                21,
                21,
            'Small (51 x 51)',
                51,
                51,
            'Compact (101 x 101)',
                101,
                101,
            'Normal (201 x 201)',
                201,
                201,
            'Large (501 x 501)',
                501,
                501,
            'Enormous (1001 x 1001)',
                1001,
                1001,
        );

        do {

            my ($descrip, $width, $height);

            $descrip = shift @sizeList;
            $width = shift @sizeList;
            $height = shift @sizeList;

            # (The maximum size of a map shouldn't change, but check anyway)
            if (
                $width <= $self->worldModelObj->maxGridWidthBlocks
                && $height <= $self->worldModelObj->maxGridHeightBlocks
            ) {
                push (@comboList2, $descrip);
                $widthHash{$descrip} = $width;
                $heightHash{$descrip} = $height;
            }

        } until (! @sizeList);

        # That completes the setup. Now, 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);

        # Add widgets
        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);
        $label->set_markup(
            "Enter a name for the new region (max 32 chars),\n"
            . "or leave empty to generate a generic name",
        );

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

        my $label2 = Gtk3::Label->new();
        $vBox2->pack_start($label2, FALSE, FALSE, $spacing);
        $label2->set_alignment(0, 0);
        $label2->set_markup('(Optional) select the parent region');

        my $combo = Gtk3::ComboBoxText->new();
        $vBox2->pack_start($combo, FALSE, FALSE, $spacing);
        foreach my $item (@comboList) {

            $combo->append_text($item);
        }

        $combo->set_active(0);
        if ((scalar @comboList) == 1) {

            # No regions exist, so no need to offer a parent region
            $combo->set_sensitive(FALSE);
        }

        my $label3 = Gtk3::Label->new();
        $vBox2->pack_start($label3, FALSE, FALSE, $spacing);
        $label3->set_alignment(0, 0);
        $label3->set_markup('(Optional) change the map size');

        my $combo2 = Gtk3::ComboBoxText->new();
        $vBox2->pack_start($combo2, FALSE, FALSE, $spacing);
        foreach my $item (@comboList2) {

            $combo2->append_text($item);
        }

        $combo2->set_active(0);

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

                    }

                    next OUTER;
                }
            }

            # $dir is available
            push (@availableList, $dir);
        }

        # If the eight usual cardinal directions are not available, then the user must be offered
        #   'northnortheast', etc, even if ->showAllPrimaryFlag is not set
        if (! $self->worldModelObj->showAllPrimaryFlag && ! %checkHash) {

            OUTER: foreach my $dir (@extraList) {

                INNER: foreach my $number ($roomObj->ivValues('exitNumHash')) {

                    my $thisExitObj = $self->worldModelObj->ivShow('exitModelHash', $number);

                    if (
                        $thisExitObj->mapDir
                        && $thisExitObj->mapDir eq $dir
                        && $thisExitObj->drawMode ne 'temp_alloc'
                        && $thisExitObj->drawMode ne 'temp_unalloc'
                    ) {
                        # $dir isn't available
                        next OUTER;
                    }
                }

                # $dir is available
                push (@availableList, $dir);
            }
        }

        # Get a sorted list of all non-world profiles...
        foreach my $profObj ($self->session->ivValues('profHash')) {

            if ($profObj->category ne 'world') {

                push (@profList, $profObj->name);
            }
        }

        @profList = sort {lc($a) cmp lc($b)} (@profList);

        # ...and put the current world profile at the top of the list
        unshift (@profList, $self->session->currentWorld->name);

        # That completes the setup. Now, 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);

        # Add widgets
        my ($entry, $entry2, $entry3, $entry4, $comboBox, $comboBox2);

        # Called by $self->addExitCallback or ->changeDirCallback
        if (! $exitObj || ($exitObj && $mode eq 'change_dir')) {

            # Work out which map directon should be displayed in the first combobox (corresponds
            #   to GA::Obj::Exit->mapDir, if defiend)
            if ($exitObj && $exitObj->mapDir && $mode eq 'change_dir') {

                # Use the existing exit's map direction, ->mapDir (if defined). Does this direction
                #   already exist in @availableList?
                if (@availableList) {

                    OUTER: for (my $count = 0; $count < @availableList; $count++) {

                        if ($availableList[$count] eq $exitObj->mapDir) {

                            $match = $count;
                            last OUTER;
                        }
                    }
                }

                if (! defined $match) {

                    # The existing map direction is missing from the list; add it to
                    #   the beginning
                    unshift(@availableList, $exitObj->mapDir);
                    $match = 0;
                }

            } else {

                # Use the first map direction in the list initially
                $match = 0;
            }

            # Add a combobox to choose the map direction
            my $label = Gtk3::Label->new();
            $vBox2->pack_start($label, FALSE, FALSE, 5);
            $label->set_alignment(0, 0);
            $label->set_markup('Standard map direction, e.g. <i>\'north\' </i>');

            $comboBox = Gtk3::ComboBoxText->new();

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

            return @emptyList;
        }

        if ($self->worldModelObj->showAllPrimaryFlag) {
            @dirList = $axmud::CLIENT->constPrimaryDirList;
        } else {
            @dirList = $axmud::CLIENT->constShortPrimaryDirList;
        }

        # Extract all the available primary directions (those not in use by other exits)
        OUTER: foreach my $standardDir (@dirList) {

            # Get the custom primary direction
            my $customDir = $self->session->currentDict->ivShow('primaryDirHash', $standardDir);

            # If a single room is selected, don't show exits in directions that alreadyd exist
            if ($roomObj) {

                INNER: foreach my $number ($roomObj->ivValues('exitNumHash')) {

                    my $exitObj = $self->worldModelObj->ivShow('exitModelHash', $number);

                    if (
                        $exitObj->mapDir
                        && $exitObj->mapDir eq $standardDir
                        && $exitObj->drawMode ne 'temp_alloc'
                        && $exitObj->drawMode ne 'temp_unalloc'
                    ) {
                        # The primary direction isn't available
                        next OUTER;
                    }
                }
            }

            # $customDir can be shown in the 'dialogue' window
            $availableHash{$standardDir} = $customDir;
        }

        if (! %availableHash) {

            $self->showMsgDialogue(
                'Add multiple exits',
                'warning',
                'The selected room already has exits drawn in all primary directions',
                'ok',
            );

            return @emptyList;
        }

        # That completes the setup. Now, show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Add multiple exits',
            $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});

        # Destroy the window, when required
        $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);

        # Add a table, and arrange widgets on it
        my $table = Gtk3::Grid->new();
        $vBox2->pack_start($table, TRUE, TRUE, $axmud::CLIENT->constFreeSpacingPixels);
        $table->set_column_spacing($axmud::CLIENT->constFreeSpacingPixels);
        $table->set_row_spacing($axmud::CLIENT->constFreeSpacingPixels);

        my $label = Gtk3::Label->new();
        $table->attach($label, 0, 0, 3, 1);
        $label->set_alignment(0, 0);
        if ($self->selectedRoom) {

            $label->set_markup('<i>Add exits to 1 selected room</i>');

        } else {

            $label->set_markup(
                '<i>Add exits to ' . $self->ivPairs('selectedRoomHash') . ' selected rooms</i>',
            );
        }

        $count = 0;
        foreach my $dir (
            qw (
                north northeast east southeast south southwest west northwest
                up
                northnortheast eastnortheast eastsoutheast southsoutheast southsouthwest
                    westsouthwest westnorthwest northnorthwest
                down
            )
        ) {
            $count++;

            my $checkButton = Gtk3::CheckButton->new_with_label($dir);

            if ($count <= 9) {
                $table->attach($checkButton, 0, $count, 1, 1);
            } else {
                $table->attach($checkButton, 1, ($count - 9), 2, 1);
            }

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

                if ($checkButton->get_active()) {

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN


        # Prompt the user to choose an exit
        $choice = $self->showComboDialogue(
            'Select exit',
            $text,
            $stringListRef,
        );

        if (! $choice) {

            return undef;

        } else {

            # Return the blessed reference of the chosen exit
            return $$exitHashRef{$choice};
        }
    }

    sub promptFilePath {

        # Called by $self->setFilePathCallback
        # Prompts the user to enter a file path for the selected room and (optionally) the path
        #   to the virtual area, if the room is in one
        #
        # Expected arguments
        #   $roomObj    - The room for which to set a file path
        #
        # Return values
        #   On improper arguments or if the user clicks the cancel button, returns an empty list
        #   Otherwise returns a list of two elements, in the form
        #       (file_path, virtual_area_path)
        #   If the user doesn't enter text into one or the other boxes, one (or both) elements
        #       will be empty strings

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

        # Local variables
        my (
            $msg, $msg2, $response, $filePath, $virtualPath,
            @emptyList,
        );

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

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

        # Create the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Set file path',
            $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
        $msg = "Enter the path to the room\'s source code file in the mudlib (if known)\n";
        if ($roomObj->sourceCodePath) {
            $msg .= "<i>(current value: " . $roomObj->sourceCodePath . ")</i>";
        } else {
            $msg .= "<i>(current value: not set)</i>";
        }

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

        my $entry = Gtk3::Entry->new();
        $vBox2->pack_start($entry, FALSE, FALSE, 5);
        # Use the room's existing path, if it has one; otherwise, copy the last path entered by
        #   the user, so they can edit it without re-typing the whole thing
        if ($roomObj->sourceCodePath) {
            $entry->set_text($roomObj->sourceCodePath);
        } elsif ($self->worldModelObj->lastFilePath) {
            $entry->set_text($self->worldModelObj->lastFilePath);
        }

        # Second label and entry
        $msg2 = "(Optional) Enter a path to the virtual area, if the room is in one\n";
        if ($roomObj->virtualAreaPath) {
            $msg2 .= "<i>(current value: " . $roomObj->virtualAreaPath . ")</i>";
        } else {
            $msg2 .= "<i>(current value: not set)</i>";
        }

        my $label2 = Gtk3::Label->new();
        $vBox2->pack_start($label2, FALSE, FALSE, 5);
        $label2->set_alignment(0, 0);
        $label2->set_markup($msg2);

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

        my $entry2 = Gtk3::Entry->new();
        $hBox->pack_start($entry2, TRUE, TRUE, 0);
        # Use the room's existing virtual area path, if it has one; otherwise use the last path
        #   entered by the user
        if ($roomObj->virtualAreaPath) {
            $entry2->append_text($roomObj->virtualAreaPath);

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

        $vBox->show_all();

        # If the user clicked 'cancel', $response will be 'reject'
        # Otherwise, user clicked 'ok', and we need to get the coordinates typed
        $response = $dialogueWin->run();
        if ($response eq 'accept') {

            $filePath = $entry->get_text();
            $virtualPath = $entry2->get_text();
        }

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

        return ($filePath, $virtualPath);
    }

    sub promptAdjacentMode {

        # Called by $self->adjacentModeCallback
        # Prompts the user to enter new values for GA::Obj::WorldModel->adjacentMode and
        #   ->adjacentCount, and returns them
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   On improper arguments or if the user clicks the cancel button, returns an empty list
        #   Otherwise returns a list of two elements, in the form
        #       (mode, count)

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

        # Local variables
        my (
            $spacing, $first, $response, $responseText, $responseText2,
            @emptyList, @list, @comboList,
            %descripHash,
        );

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

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

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

        # Show the 'dialogue' window
        my $dialogueWin = Gtk3::Dialog->new(
            'Adjacent regions regions mode',
            $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 combo
        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, $spacing);
        $label->set_alignment(0, 0);
        $label->set_markup(
            "In adjacent regions mode, the pathfinding routines\n"
            . "treat rooms in nearby regions as if they were all\n"
            . "in the same region",
        );

        # Prepare the combo list. The current setting of GA::Obj::WorldModel->adjacentMode should be
        #   at the top
        @list = (
            'Don\'t use this mode'  => 'default',
            'Use adjacent regions'  => 'near',
            'Use all regions'       => 'all',
        );

        do {

            my ($descrip, $mode);

            $descrip = shift @list;
            $mode = shift @list;

            if ($mode eq $self->worldModelObj->adjacentMode) {

                $first = $descrip;

            } else {

                push (@comboList, $descrip);
            }

            $descripHash{$descrip} = $mode;

        } until (! @list);

        unshift (@comboList, $first);

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

            $combo->append_text($line);
        }
        $combo->set_active(0);
        # (->signal_connect appears below)

        # Second label and entry
        my $label2 = Gtk3::Label->new();
        $vBox2->pack_start($label2, FALSE, FALSE, $spacing);
        $label2->set_alignment(0, 0);
        $label2->set_markup(
            "How close adjacent regions must be (e.g. 1 - regions\n"
            . "must be connected, 2 - connected via intermediate\n"
            . "region, 0 - don\'t use adjacent regions right now)",
        );

        # (Use the same maximum characters that the 'edit' window uses
        my $entry = Gtk3::Entry->new();
        $vBox2->pack_start($entry, FALSE, FALSE, $spacing);
        $entry->set_max_length(4);
        $entry->set_text($self->worldModelObj->adjacentCount);
        if ($self->worldModelObj->adjacentMode ne 'near') {

            $entry->set_sensitive(FALSE);
        }

        # (->signal_connect from above)
        $combo->signal_connect('changed' => sub {

            my $descrip = $combo->get_active_text();

            if ($descripHash{$descrip} eq 'near') {

                $entry->set_text($self->worldModelObj->adjacentCount);
                $entry->set_sensitive(TRUE);

            } else {

                $entry->set_text('');
                $entry->set_sensitive(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 . '->promptAdjacentMode');

        # Get the response. 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 (defined $response && $response eq 'accept') {

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

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

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

        } else {

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

            # Return the response
            return @emptyList;
        }
    }

    sub promptConfigLabel {

        # Called by $self->addLabelAtBlockCallback, ->addLabelAtClickCallback and
        #   ->setLabelCallback
        # Prompts the user for some label text and an optional label style
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   $labelObj       - When called by ->setLabelCallback, the existing label text and style
        #   $customiseFlag  - If FALSE, the 'dialogue' window only shows label text and style. If
        #                       TRUE, the 'dialogue' window shows all label IVs
        #
        # Return values
        #   An empty list on improper arguments or if the user closes the window without making
        #       changes
        #   Otherwise returns a list in the form
        #       (label_text, label_style)
        #   ...where 'label_text' must contain at least one non-space character, and 'label_style'
        #       is the name of a label style object stored in GA::Obj::WorldModel->mapLabelStyleHash
        #       (or 'undef', if the label style object specified by
        #       GA::Obj::WorldModel->mapLabelStyle is used)

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

        # Local variables
        my (
            $title, $current, $response, $textColour, $underlayColour, $count, $index, $relSize,
            $text, $choice, $angleFlag,
            @emptyList, @list, @comboList,
            %descripHash, %revDescripHash,
        );

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

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

        # Show the 'dialogue' window
        if (! $customiseFlag) {
            $title = 'Add label';
        } else {
            $title = 'Customise label';
        }

        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/textview
        my $label = Gtk3::Label->new();
        $vBox2->pack_start($label, FALSE, FALSE, 5);
        $label->set_alignment(0, 0);
        $label->set_markup('Enter the label text');

        my ($entry, $scroller, $textView, $buffer);

        # (If the label object already uses multiple lines, then we have to allow multiline input,
        #   even if GA::Obj::WorldModel->mapLabelTextViewFlag is turned off)
        if (
            ! $self->worldModelObj->mapLabelTextViewFlag
            && (! $labelObj || ! ($labelObj->name =~ m/\n/))
        ) {
            # Create an entry
            $entry = Gtk3::Entry->new();
            # (->signal_connect appears below)
            $vBox2->pack_start($entry, FALSE, FALSE, 5);
            if ($labelObj) {

                $entry->set_text($labelObj->name);
            }

            if (! $customiseFlag) {

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

                    $text = $entry->get_text();
                    # This line ends the call to $dialogueWin->run(), as if the user had clicked the
                    #   'OK' button
                    $dialogueWin->destroy();
                });
            }

        } else {

            # Create a textview using the system's preferred colours and fonts
            $scroller = Gtk3::ScrolledWindow->new(undef, undef);
            $vBox2->pack_start($scroller, FALSE, FALSE, 5);
            $scroller->set_shadow_type($axmud::CLIENT->constShadowType);
            $scroller->set_policy('automatic', 'automatic');
            $scroller->set_size_request(200, 75);

            # Create a textview with default colours/fonts for a dialogue window
            $textView = Gtk3::TextView->new();
            $scroller->add($textView);
            $buffer = Gtk3::TextBuffer->new();
            $textView->set_buffer($buffer);
            $textView->set_editable(TRUE);
            $textView->set_cursor_visible(TRUE);

            $axmud::CLIENT->desktopObj->setTextViewStyle('dialogue', $textView);

            if ($labelObj) {

                $buffer->set_text($labelObj->name);
            }
        }

        my (
            $label2, $combo,
            $table,
            $label3, $frame, $canvas, $canvasObj, $button, $button2,
            $label4, $frame2, $canvas2, $canvasObj2, $button3, $button4,
            $label5, $entry2,
            $checkButton, $checkButton2, $checkButton3, $checkButton4, $checkButton5,
            $label6, $combo2,
            $entry3,
        );

        if (! $customiseFlag) {

            # Second label and combo
            $label2 = Gtk3::Label->new();
            $vBox2->pack_start($label2, FALSE, FALSE, 5);
            $label2->set_alignment(0, 0);
            $label2->set_markup('Select a label style');

            # (The world model defines a style for use with new labels; show it first in the list,
            #   or show the existing label's style
            if ($labelObj) {
                $current = $labelObj->style;
            } else {
                $current = $self->worldModelObj->mapLabelStyle;
            }

            foreach my $style (
                sort {lc($a) cmp lc($b)} ($self->worldModelObj->ivKeys('mapLabelStyleHash'))
            ) {
                if (! defined $current || $current ne $style) {

                    push (@comboList, $style);
                }
            }

            if (defined $current) {

                unshift(@comboList, $current);
            }

            $combo = Gtk3::ComboBoxText->new();
            $vBox2->pack_start($combo, FALSE, FALSE, 5);
            foreach my $item (@comboList) {

                $combo->append_text($item);
            }

            $combo->set_active(0);

        } else {

            # Extra widgets for all map label object IVs apart from ->style (which is about to be

lib/Games/Axmud/Win/Map.pm  view on Meta::CPAN

            $label6 = Gtk3::Label->new();
            $table->attach($label6, 0, 7, 3, 1);
            $label6->set_markup('Degrees (0-359)');
            $label6->set_alignment(0, 0.5);

            $entry3 = Gtk3::Entry->new();
            $table->attach($entry3, 3, 7, 9, 1);
            $entry3->set_text($labelObj->rotateAngle);
            $entry3->set_width_chars(3);
            $entry3->set_max_length(3);

            if ($angleFlag) {

                $combo2->set_active($index);
                $entry3->set_sensitive(FALSE);

            } else {

                $combo2->set_active($count);
                $entry3->set_sensitive(TRUE);
            }

            # ->signal_connect from above
            $combo2->signal_connect('changed' => sub {

                my $descrip = $combo2->get_active_text();

                if ($descrip eq $revDescripHash{-1}) {

                    $entry3->set_sensitive(TRUE);
                    $entry3->set_text(0);

                } else {

                    $entry3->set_sensitive(FALSE);
                    $entry3->set_text($descripHash{$descrip});
                }
            });
        }

        # Display the dialogue window. The double call to ->present is needed so the user can type
        #   into the entry/textview right away
        $vBox->show_all();
        $dialogueWin->present();
        $dialogueWin->present();

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

        if (defined $text) {

            # User pressed their ENTER key in the Gtk3::Entry, so $text is already set
            $response = 'accept';

        } elsif ($entry) {

            $text = $entry->get_text();

        } else {

            $text = $axmud::CLIENT->desktopObj->bufferGetText($buffer);
        }

        if ($response ne 'accept') {

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

            return @emptyList;

        # Otherwise, user clicked 'ok'
        } elsif (! $customiseFlag) {

            $choice = $combo->get_active_text();

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

            return ($text, $choice);

        } else {

            # Update the map label object's IVs
            $labelObj->ivPoke('textColour', $textColour);
            $labelObj->ivPoke('underlayColour', $underlayColour);

            $relSize = $entry2->get_text();
            if (defined $relSize && $axmud::CLIENT->floatCheck($relSize, 0.5, 10)) {

                $labelObj->ivPoke('relSize', $relSize);
            }

            if (! $checkButton->get_active()) {
                $labelObj->ivPoke('italicsFlag', FALSE);
            } else {
                $labelObj->ivPoke('italicsFlag', TRUE);
            }

            if (! $checkButton2->get_active()) {
                $labelObj->ivPoke('boldFlag', FALSE);
            } else {
                $labelObj->ivPoke('boldFlag', TRUE);
            }

            if (! $checkButton3->get_active()) {
                $labelObj->ivPoke('underlineFlag', FALSE);
            } else {
                $labelObj->ivPoke('underlineFlag', TRUE);
            }

            if (! $checkButton4->get_active()) {
                $labelObj->ivPoke('strikeFlag', FALSE);
            } else {
                $labelObj->ivPoke('strikeFlag', TRUE);
            }

            if (! $checkButton5->get_active()) {
                $labelObj->ivPoke('boxFlag', FALSE);
            } else {
                $labelObj->ivPoke('boxFlag', TRUE);
            }



( run in 1.425 second using v1.01-cache-2.11-cpan-f56aa216473 )