view release on metacpan or search on metacpan
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
],
# Constant hash of names of button sets and their corresponding (short) descriptions
constButtonDescripHash => {
'default' => 'Show the default button set', # Never actually used
'exits' => 'Show exit customisation buttons',
'painting' => 'Show room painting buttons',
'quick' => 'Show quick painting buttons',
'background' => 'Show background colouring buttons',
'tracking' => 'Show room tracking buttons',
'misc' => 'Show miscellaneous buttons',
'flags' => 'Show room flag filter buttons',
'interiors' => 'Show room interior buttons',
},
# Hash of names of button sets, showing which are visible (TRUE) and which are not
# visible (FALSE)
buttonSetHash => {
'default' => FALSE,
'exits' => FALSE,
'painting' => FALSE,
'quick' => FALSE,
'background' => FALSE,
'tracking' => FALSE,
'misc' => FALSE,
'flags' => FALSE,
'interiors' => FALSE,
},
# Ordered list of toolbar widgets that are visible now, with the default toolbar always
# first in the list
toolbarList => [],
# Corresponding hash of toolbar widgets, in the form
# $toolbarHash{toolbar_widget} = name_of_button_set_visible_now
toolbarHash => {},
# A list of button widgets in the original toolbar (not including the add button, the
# switcher button and the separator that follows them); updated every time the user
# clicks the switcher icon
# NB Buttons in additional toolbars aren't stored in an IV
toolbarButtonList => [],
# The 'add' button in the original toolbar
toolbarAddButton => undef,
# The 'switch' button in the original toolbar
toolbarSwitchButton => undef,
# The default set (the first one drawn); this IV never changes
constToolbarDefaultSet => 'default',
# Whenever the original (first) toolbar is drawn, this IV records the button set used
# (so that the same button set appears whenever $self->redrawWidgets is called)
toolbarOriginalSet => 'default',
# Hash of room flags currently in use as preferred room flags, and whose toolbar button
# in the 'painter' set (if visible) is currently toggled on. The hash is reset every
# time the toolbar is drawn or redrawn, and is used to make sure that the toggled
# button(s) remain toggled after the redraw
# Hash in the form
# toolbarRoomFlagHash{room_flag} = undef
toolbarRoomFlagHash => {},
# When a colour button in the quick painting button set it toggled, the corresponding
# room flag is stored here
# When this IV is defined, clicking a room toggles the room flag in that room. If
# multiple rooms are selected, and one of the selected rooms was the clicked one,
# the room flag is toggled in all of them
toolbarQuickPaintColour => undef,
# Menu bar/toolbar items which will be sensitised or desensitised, depending on the
# context. Hash in the form
# $menuToolItemHash{'item_name'} = Gtk3_widget
# ...where:
# 'item_name' is a descriptive scalar, e.g. 'move_up_level'
# 'Gtk3_widget' is the Gtk3::MenuItem or toolbar widget, typically Gtk3::ToolButton or
# Gtk3::RadioToolButton
# NB Entries in this hash continue to exist, after the widgets are no longer visible.
# Doesn't matter, because there are a limited number of 'item_name' scalars, and so
# a limited size to the hash (and referencing no-longer visible widgets, for example
# to sensitise/desensitise them, doesn't have any ill effects)
menuToolItemHash => {},
# A horizontal pane, dividing the treeview on the left from everything else on the right
hPaned => undef,
# The treeview widgets (on the left)
treeViewModel => undef,
treeView => undef,
treeViewScroller => undef,
treeViewWidthPixels => 150, # (Default width)
# The currently selected line of the treeview (selected by single-clicking on it)
treeViewSelectedLine => undef,
# A hash of regions in the treeview, which stores which rows containing parent regions
# have been expanded to reveal their child regions
# Hash in the form
# $treeViewRegionHash{region_name} = flag
# ...where 'flag' is TRUE when the row is expanded, FALSE when the row is not expanded
treeViewRegionHash => {},
# A hash of pointers (iters) in the treeview, so we can look up each region's cell
treeViewPointerHash => {},
# Canvas widgets (on the right)
# ->canvas and ->canvasBackground store widgets for the current region and level (or the
# empty background map, if no region/level are visible)
canvas => undef,
canvasBackground => undef,
canvasFrame => undef,
canvasScroller => undef,
canvasHAdjustment => undef,
canvasVAdjustment => undef,
# The size of the available area inside the scrolled window, set whenever the
# scrolled window's size-allocate signal is emitted (this is the only way to guarantee
# that the correct size is available to $self->setMapPosn)
canvasScrollerWidth => 1,
canvasScrollerHeight => 1,
# Blessed reference of the currently displayed GA::Obj::Regionmap ('undef' if no region
# is displayed; not necessarily the same region as the character's current location)
currentRegionmap => undef,
# Blessed reference of the currently displayed GA::Obj::Parchment ('undef' if no region
# is displayed; not necessarily the same region as the character's current location)
currentParchment => undef,
# List of the names of regions that have been the current region recently. Does not
# include the current region, nor any duplicates, nor more than three regions. The
# most recent current region is the first one in the list. The list is modified
# whenever $self->setCurrentRegion is called
recentRegionList => [],
# Flag set to TRUE if the visible map is the empty background map (created by a call to
# $self->resetMap). Set to FALSE if the visible map is a region (created by a call to
# $self->refreshMap). Set to FALSE if neither ->resetMap nor ->refreshMap have been
# called yet
emptyMapFlag => FALSE,
# The first call to $self->winUpdate calls $self->preparePreDraw to compile a list of
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
eastnortheast => [2, 1, 2, 3], # Same as E
east => [2, 1, 2, 3],
eastsoutheast => [2, 1, 2, 3], # Same as E
southeast => [2, 1, 0, 3],
southsoutheast => [0, 3, 2, 3], # Same as S
south => [0, 3, 2, 3],
southsouthwest => [0, 3, 2, 3], # Same as S
southwest => [0, 1, 2, 3],
westsouthwest => [0, 1, 0, 3], # Same as W
west => [0, 1, 0, 3],
westnorthwest => [0, 1, 0, 3], # Same as W
northwest => [2, 1, 0, 3],
northnorthwest => [0, 1, 2, 1], # Same as N
up => [0, 0],
down => [0, 0],
},
# Anchor hashes - converts a standard primary direction into a Gtk3 anchor constant, so
# that exit tags can be drawn in the right position
constGtkAnchorHash => {
north => 'GOO_CANVAS_ANCHOR_S',
# No GooCanvas2 constant for NNE, etc, so use the same as N
northnortheast => 'GOO_CANVAS_ANCHOR_S', # Same as N
northeast => 'GOO_CANVAS_ANCHOR_SW',
eastnortheast => 'GOO_CANVAS_ANCHOR_W', # Same as E
east => 'GOO_CANVAS_ANCHOR_W',
eastsoutheast => 'GOO_CANVAS_ANCHOR_W', # Same as E
southeast => 'GOO_CANVAS_ANCHOR_NW',
southsoutheast => 'GOO_CANVAS_ANCHOR_N', # Same as S
south => 'GOO_CANVAS_ANCHOR_N',
southsouthwest => 'GOO_CANVAS_ANCHOR_N', # Same as S
southwest => 'GOO_CANVAS_ANCHOR_NE',
westsouthwest => 'GOO_CANVAS_ANCHOR_E', # Same as W
west => 'GOO_CANVAS_ANCHOR_E',
westnorthwest => 'GOO_CANVAS_ANCHOR_E', # Same as w
northwest => 'GOO_CANVAS_ANCHOR_SE',
northnorthwest => 'GOO_CANVAS_ANCHOR_S', # Same as N
},
# Magnfication list. A list of standard magnification factors used for zooming in or out
# from the map
# Each GA::Obj::Regionmap object has its own ->magnification IV, so zooming on one
# region doesn't affect the magnification of others
# When the user zooms in or out, ->magnification is set to one of the values in this
# list, and various IVs in GA::Obj::Regionmap (such as ->blockWidthPixels and
# ->roomHeightPixels) are changed. When the map is redrawn, everything in it is bigger
# (or smaller)
constMagnifyList => [
0.01, 0.02, 0.04, 0.06, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
1,
1.1, 1.2, 1.35, 1.5, 2, 3, 5, 7, 10,
],
# A subset of these magnifications, used as menu items
constShortMagnifyList => [
0.5, 0.8, 1, 1.2, 1.5, 1.75, 2
],
# When some menu items are selected (e.g. View > Room filters > Release markers filter),
# a call is made to this session's GA::Obj::WorldModel, which in turn calls every
# Automapper window using the model, in order to update its menu. When this happens,
# the following flag is set to TRUE, so that updating the menu item doesn't cause
# further calls to GA::Obj::WorldModel
ignoreMenuUpdateFlag => FALSE,
# IVs used during a drag operation
# Flag set to TRUE during drag mode (set from the menu or the toolbar). Normally, it's
# necessary to hold down the Alt-Gr key to drag canvas objects; when drag mode is on,
# clicks on canvas objects are treated as the start of a drag, rather than a
# select/unselect operation)
# NB During a drag operation initiated with the Alt-Gr key, ->dragModeFlag's value
# doesn't change
dragModeFlag => FALSE,
# Flag set to TRUE when a dragging operation starts
dragFlag => FALSE,
# Flag set to TRUE when $self->continueDrag is called, and set back to FALSE at the
# end of that call. ->continueDrag does nothing if a previous call to the function
# hasn't been completed (happens a lot)
dragContinueFlag => FALSE,
# The canvas object that was underneath the mouse cursor when the drag operation began
# (the object that was grabbed, when using Alt-Gr)
dragCanvasObj => undef,
# A list of all canvas objects that are being dragged together. $self->dragCanvasObj is
# always the first item in the list
# If $self->dragCanvasObj is a room, all selected rooms/labels in the same region are
# dragged together
# If $self->dragCanvasObj is a label, both the label and its box (if drawn) are dragged
# together
dragCanvasObjList => [],
# The GA::ModelObj::Room / GA::Obj::Exit / GA::Obj::MapLabel being dragged,
# corresponding to $self->dragCanvasObj
dragModelObj => undef,
# The type of object being dragged - 'room', 'room_tag', 'room_guild', 'exit',
# 'exit_tag' or 'label'
dragModelObjType => undef,
# The canvas object's initial coordinates on the canvas
dragInitXPos => undef,
dragInitYPos => undef,
# The canvas object's current coordinates on the canvas
dragCurrentXPos => undef,
dragCurrentYPos => undef,
# When dragging a room(s), the fake room(s) drawn at the original location (so that the
# exits don't look messy)
dragFakeRoomList => [],
# When dragging an exit bend, the bend's index in the exit's list of bends (the bend
# closest to the start of the exit has the index 0)
dragBendNum => undef,
# When dragging an exit bend, the initial position of the bend, relative to the start of
# the bending section of the exit
dragBendInitXPos => undef,
dragBendInitYPos => undef,
# The corresponding IVs for the twin exit, when dragging an exit bend
dragBendTwinNum => undef,
dragBendTwinInitXPos => undef,
dragBendTwinInitYPos => undef,
# When dragging an exit bend, the exit drawing mode (corresponds to
# GA::Obj::WorldModel->drawExitMode)
dragExitDrawMode => undef,
# When dragging an exit bend, the draw ornaments flag (corresponds to
# GA:Obj::WorldModel->drawOrnamentsFlag
dragExitOrnamentsFlag => undef,
# IVs used during a selection box operation
# Flag set to TRUE when a selection box operation starts, but before the box has
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# 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)
if ($self->worldModelObj->showMenuBarFlag) {
$menuBar = $self->enableMenu();
if ($menuBar) {
# Pack the widget
$packingBox->pack_start($menuBar, FALSE, FALSE, 0);
}
}
# Create toolbar(s) at the top of the window (if allowed)
if ($self->worldModelObj->showToolbarFlag) {
# 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();
foreach my $toolbar ($self->enableToolbar()) {
# Pack the widget
$packingBox->pack_start($toolbar, FALSE, FALSE, 0);
}
}
# Create a horizontal pane to divide everything under the menu into two, with the treeview
# on the left, and everything else on the right (only if both the treeview and the canvas
# are shown)
if ($self->worldModelObj->showTreeViewFlag && $self->worldModelObj->showCanvasFlag) {
$hPaned = Gtk3::HPaned->new();
if ($hPaned) {
# Set the width of the space about to be filled with the treeview
$hPaned->set_position($self->treeViewWidthPixels);
# Pack the widget
$packingBox->pack_start($hPaned, TRUE, TRUE, 0);
$self->ivPoke('hPaned', $hPaned);
}
}
# Create a treeview (if allowed)
if ($self->worldModelObj->showTreeViewFlag) {
$treeViewScroller = $self->enableTreeView();
if ($treeViewScroller) {
# Pack the widget
if ($hPaned) {
# Add the treeview's scroller to the left pane
$hPaned->add1($treeViewScroller);
} else {
# Pack the treeview directly into the packing box
$packingBox->pack_start($treeViewScroller, TRUE, TRUE, 0);
}
}
}
# Create a canvas (if allowed)
if ($self->worldModelObj->showCanvasFlag) {
$canvasFrame = $self->enableCanvas();
if ($canvasFrame) {
# Pack the widget
if ($hPaned) {
# Add the frame to the right pane
$hPaned->add2($canvasFrame);
} else {
# Pack the frame directly into the packing box
$packingBox->pack_start($canvasFrame, TRUE, TRUE, 0);
}
}
}
return 1;
}
sub redrawWidgets {
# 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);
}
}
} else {
# When the toolbars are next drawn, make sure the default button set is visible in the
# original (first) toolbar
$self->ivPoke('toolbarOriginalSet', $self->constToolbarDefaultSet);
}
# Create a new horizontal pane (only if both the treeview and the canvas are allowed)
if ($self->worldModelObj->showTreeViewFlag && $self->worldModelObj->showCanvasFlag) {
$hPaned = Gtk3::HPaned->new();
if ($hPaned) {
# Set the width of the space about to be filled with the treeview
$hPaned->set_position($self->treeViewWidthPixels);
# Pack the widget
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
} elsif ($self->treeViewScroller) {
if ($hPaned) {
# Add the treeview's scroller to the left-hand pane
$hPaned->add1($self->treeViewScroller);
} else {
# Pack the treeview directly into the packing box
$self->packingBox->pack_start($self->treeViewScroller, TRUE, TRUE, 0);
}
}
}
# Redraw the canvas, if specified (and if allowed)
if ($self->worldModelObj->showCanvasFlag) {
if ($widgetHash{'canvas'}) {
$self->resetCanvasIVs();
$canvasFrame = $self->enableCanvas();
if ($canvasFrame) {
# Pack the new widget
if ($hPaned) {
# 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
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$self->winBox->signal_connect('configure-event' => sub {
my ($widget, $event) = @_;
# Let the GA::Client store the most recent size and position for a window of this
# ->winName, if it needs to
if ($self->winWidget) {
$axmud::CLIENT->add_storeGridPosn(
$self,
$self->winWidget->get_position(),
$self->winWidget->get_size(),
);
}
# Without returning 'undef', the window's strip/table objects aren't resized along with
# the window
return undef;
});
return 1;
}
sub setFocusOutEvent {
# Called by $self->winSetup
# Set up a ->signal_connect to watch out for the 'map' window losing the focus
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setFocusInEvent', @_);
}
$self->winBox->signal_connect('focus-out-event' => sub {
my ($widget, $event) = @_;
# If the tooltips are visible, hide them
if ($event->type eq 'focus-change' && $self->canvasTooltipFlag) {
$self->hideTooltips();
}
});
return 1;
}
# Other functions
sub resetMenuBarIVs {
# Called by $self->redrawWidgets at certain points, to reset the IVs storing details about
# the menu bar back to their defaults
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->resetMenuBarIVs', @_);
}
$self->ivUndef('menuBar');
$self->ivEmpty('menuToolItemHash');
return 1;
}
sub resetToolbarIVs {
# Called by $self->drawWidgets and $self->redrawWidget to reset the IVs storing details
# about toolbars back to their defaults
# (If $self->enableToolbar is then called, it's that function which imports a list of
# button sets from the world model and updates these IVs accordinly)
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->resetToolbarIVs', @_);
}
foreach my $key ($self->ivKeys('buttonSetHash')) {
$self->ivAdd('buttonSetHash', $key, FALSE);
}
$self->ivEmpty('toolbarList');
$self->ivEmpty('toolbarHash');
return 1;
}
sub resetTreeViewIVs {
# Called by $self->redrawWidgets at certain points, to reset the IVs storing details about
# the treeview back to their defaults
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->resetTreeViewIVs', @_);
}
$self->ivUndef('treeViewModel');
$self->ivUndef('treeView');
$self->ivUndef('treeViewScroller');
$self->ivUndef('treeViewSelectedLine');
$self->ivEmpty('treeViewRegionHash');
$self->ivEmpty('treeViewPointerHash');
return 1;
}
sub resetCanvasIVs {
# Called by $self->redrawWidgets at certain points, to reset the IVs storing details about
# the canvas back to their defaults
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->resetCanvasIVs', @_);
}
$self->ivUndef('canvas');
$self->ivUndef('canvasBackground');
# (For some reason, commenting out these lines decreases the draw time, during a call to
# $self->redrawWidgets, by about 40%. The IVs receive their correct values anyway when
# ->enableCanvas is called)
# $self->ivUndef('canvasFrame');
# $self->ivUndef('canvasScroller');
$self->ivUndef('canvasHAdjustment');
$self->ivUndef('canvasVAdjustment');
$self->ivUndef('canvasTooltipObj');
$self->ivUndef('canvasTooltipObjType');
$self->ivUndef('canvasTooltipFlag');
return 1;
}
# Menu widget methods
sub enableMenu {
# Called by $self->drawWidgets
# Sets up the Automapper window's Gtk3::MenuBar widget
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::MenuBar created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableMenu', @_);
}
# Create the menu bar
my $menuBar = Gtk3::MenuBar->new();
if (! $menuBar) {
return undef;
}
# 'File' column
my $column_file = $self->enableFileColumn();
my $item_file = Gtk3::MenuItem->new('_File');
$item_file->set_submenu($column_file);
$menuBar->append($item_file);
# 'Edit' column
my $column_edit = $self->enableEditColumn();
my $item_edit = Gtk3::MenuItem->new('_Edit');
$item_edit->set_submenu($column_edit);
$menuBar->append($item_edit);
# 'View' column
my $column_view = $self->enableViewColumn();
my $item_view = Gtk3::MenuItem->new('_View');
$item_view->set_submenu($column_view);
$menuBar->append($item_view);
# 'Mode' column
my $column_mode = $self->enableModeColumn();
my $item_mode = Gtk3::MenuItem->new('_Mode');
$item_mode->set_submenu($column_mode);
$menuBar->append($item_mode);
# 'Regions' column
my $column_regions = $self->enableRegionsColumn();
my $item_regions = Gtk3::MenuItem->new('_Regions');
$item_regions->set_submenu($column_regions);
$menuBar->append($item_regions);
# 'Rooms' column
my $column_rooms = $self->enableRoomsColumn();
my $item_rooms = Gtk3::MenuItem->new('R_ooms');
$item_rooms->set_submenu($column_rooms);
$menuBar->append($item_rooms);
# 'Exits' column
my $column_exits = $self->enableExitsColumn();
my $item_exits = Gtk3::MenuItem->new('E_xits');
$item_exits->set_submenu($column_exits);
$menuBar->append($item_exits);
# 'Labels' column
my $column_labels = $self->enableLabelsColumn();
my $item_labels = Gtk3::MenuItem->new('_Labels');
$item_labels->set_submenu($column_labels);
$menuBar->append($item_labels);
# Store the widget
$self->ivPoke('menuBar', $menuBar);
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
# Setup complete
return $menuBar;
}
sub enableFileColumn {
# Called by $self->enableMenu
# Sets up the 'File' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableFileColumn', @_);
}
# Set up column
my $column_file = Gtk3::Menu->new();
if (! $column_file) {
return undef;
}
my $item_loadModel = Gtk3::MenuItem->new('_Load world model');
$item_loadModel->signal_connect('activate' => sub {
# $self->winReset will be called by $self->set_worldModelObj when the ';load' command
# has finished its work
# NB Force pseudo command mode 'win_error' in this menu column (success system messages
# in the 'main' window; errors/improper arguments messages shown in a 'dialogue'
# window)
$self->session->pseudoCmd('load -m', 'win_error');
});
$column_file->append($item_loadModel);
my $item_loadAll = Gtk3::ImageMenuItem->new('L_oad all files');
$item_loadAll->signal_connect('activate' => sub {
# The ';load' command will $self->winReset when finished
$self->session->pseudoCmd('load', 'win_error');
});
my $img_loadAll = Gtk3::Image->new_from_stock('gtk-open', 'menu');
$item_loadAll->set_image($img_loadAll);
$column_file->append($item_loadAll);
$column_file->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_saveModel = Gtk3::MenuItem->new('_Save world model');
$item_saveModel->signal_connect('activate' => sub {
# Do a forced save. The ';save' command sets $self->freeClickMode back to 'default'
$self->session->pseudoCmd('save -m -f', 'win_error');
});
$column_file->append($item_saveModel);
my $item_saveAll = Gtk3::ImageMenuItem->new('S_ave all files');
$item_saveAll->signal_connect('activate' => sub {
# Do a forced save. The ';save' command sets $self->freeClickMode back to 'default'
$self->session->pseudoCmd('save -f', 'win_error');
});
my $img_saveAll = Gtk3::Image->new_from_stock('gtk-save', 'menu');
$item_saveAll->set_image($img_saveAll);
$column_file->append($item_saveAll);
$column_file->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_importModel = Gtk3::MenuItem->new('_Import/load world model...');
$item_importModel->signal_connect('activate' => sub {
$self->importModelCallback();
});
$column_file->append($item_importModel);
my $item_exportModel = Gtk3::MenuItem->new('Save/_export world model...');
$item_exportModel->signal_connect('activate' => sub {
$self->exportModelCallback();
});
$column_file->append($item_exportModel);
$column_file->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_mergeModel = Gtk3::MenuItem->new('_Merge world models...');
$item_mergeModel->signal_connect('activate' => sub {
$self->session->pseudoCmd('mergemodel')
});
$column_file->append($item_mergeModel);
$column_file->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_closeWindow = Gtk3::ImageMenuItem->new('_Close window');
$item_closeWindow->signal_connect('activate' => sub {
$self->winDestroy();
});
my $img_closeWindow = Gtk3::Image->new_from_stock('gtk-quit', 'menu');
$item_closeWindow->set_image($img_closeWindow);
$column_file->append($item_closeWindow);
# Setup complete
return $column_file;
}
sub enableEditColumn {
# Called by $self->enableMenu
# Sets up the 'Edit' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Local variables
my $winObj;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableEditColumn', @_);
}
# Set up column
my $column_edit = Gtk3::Menu->new();
if (! $column_edit) {
return undef;
}
# 'Select' submenu
my $subMenu_select = Gtk3::Menu->new();
# 'Select rooms' sub-submenu
my $subSubMenu_selectRooms = Gtk3::Menu->new();
my $item_selectNoTitle = Gtk3::MenuItem->new('Rooms with no _titles');
$item_selectNoTitle->signal_connect('activate' => sub {
$self->selectRoomCallback('no_title');
});
$subSubMenu_selectRooms->append($item_selectNoTitle);
my $item_selectNoDescrip = Gtk3::MenuItem->new('Rooms with no _descriptions');
$item_selectNoDescrip->signal_connect('activate' => sub {
$self->selectRoomCallback('no_descrip');
});
$subSubMenu_selectRooms->append($item_selectNoDescrip);
my $item_selectNoTitleDescrip = Gtk3::MenuItem->new('Rooms with _neither');
$item_selectNoTitleDescrip->signal_connect('activate' => sub {
$self->selectRoomCallback('no_title_descrip');
});
$subSubMenu_selectRooms->append($item_selectNoTitleDescrip);
my $item_selectTitleDescrip = Gtk3::MenuItem->new('Rooms with _both');
$item_selectTitleDescrip->signal_connect('activate' => sub {
$self->selectRoomCallback('title_descrip');
});
$subSubMenu_selectRooms->append($item_selectTitleDescrip);
$subSubMenu_selectRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectNoVisitChar = Gtk3::MenuItem->new('Rooms not visited by _character');
$item_selectNoVisitChar->signal_connect('activate' => sub {
$self->selectRoomCallback('no_visit_char');
});
$subSubMenu_selectRooms->append($item_selectNoVisitChar);
my $item_selectNoVisitAllChar = Gtk3::MenuItem->new('Rooms not visited by _anyone');
$item_selectNoVisitAllChar->signal_connect('activate' => sub {
$self->selectRoomCallback('no_visit_all');
});
$subSubMenu_selectRooms->append($item_selectNoVisitAllChar);
my $item_selectVisitChar = Gtk3::MenuItem->new('Rooms visited by c_haracter');
$item_selectVisitChar->signal_connect('activate' => sub {
$self->selectRoomCallback('visit_char');
});
$subSubMenu_selectRooms->append($item_selectVisitChar);
my $item_selectVisitAllChar = Gtk3::MenuItem->new('Rooms visited by an_yone');
$item_selectVisitAllChar->signal_connect('activate' => sub {
$self->selectRoomCallback('visit_all');
});
$subSubMenu_selectRooms->append($item_selectVisitAllChar);
$subSubMenu_selectRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectCheckable = Gtk3::MenuItem->new('Rooms with checkable d_irections');
$item_selectCheckable->signal_connect('activate' => sub {
$self->selectRoomCallback('checkable');
});
$subSubMenu_selectRooms->append($item_selectCheckable);
my $item_selectRooms = Gtk3::MenuItem->new('Select _rooms');
$item_selectRooms->set_submenu($subSubMenu_selectRooms);
$subMenu_select->append($item_selectRooms);
# 'Select exits' sub-submenu
my $subSubMenu_selectExits = Gtk3::Menu->new();
my $item_selectInRooms = Gtk3::MenuItem->new('Exits in selected _rooms');
$item_selectInRooms->signal_connect('activate' => sub {
$self->selectExitTypeCallback('in_rooms');
});
$subSubMenu_selectExits->append($item_selectInRooms);
$subSubMenu_selectExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectUnallocated = Gtk3::MenuItem->new('_Unallocated exits');
$item_selectUnallocated->signal_connect('activate' => sub {
$self->selectExitTypeCallback('unallocated');
});
$subSubMenu_selectExits->append($item_selectUnallocated);
my $item_selectUnallocatable = Gtk3::MenuItem->new('U_nallocatable exits');
$item_selectUnallocatable->signal_connect('activate' => sub {
$self->selectExitTypeCallback('unallocatable');
});
$subSubMenu_selectExits->append($item_selectUnallocatable);
my $item_selectUncertain = Gtk3::MenuItem->new('Un_certain exits');
$item_selectUncertain->signal_connect('activate' => sub {
$self->selectExitTypeCallback('uncertain');
});
$subSubMenu_selectExits->append($item_selectUncertain);
my $item_selectIncomplete = Gtk3::MenuItem->new('_Incomplete exits');
$item_selectIncomplete->signal_connect('activate' => sub {
$self->selectExitTypeCallback('incomplete');
});
$subSubMenu_selectExits->append($item_selectIncomplete);
my $item_selectAllAbove = Gtk3::MenuItem->new('_All of the above');
$item_selectAllAbove->signal_connect('activate' => sub {
$self->selectExitTypeCallback('all_above');
});
$subSubMenu_selectExits->append($item_selectAllAbove);
$subSubMenu_selectExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectImpassable = Gtk3::MenuItem->new('I_mpassable exits');
$item_selectImpassable->signal_connect('activate' => sub {
$self->selectExitTypeCallback('impass');
});
$subSubMenu_selectExits->append($item_selectImpassable);
my $item_selectMystery = Gtk3::MenuItem->new('M_ystery exits');
$item_selectMystery->signal_connect('activate' => sub {
$self->selectExitTypeCallback('mystery');
});
$subSubMenu_selectExits->append($item_selectMystery);
$subSubMenu_selectExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectNonSuper = Gtk3::MenuItem->new('R_egion exits');
$item_selectNonSuper->signal_connect('activate' => sub {
$self->selectExitTypeCallback('region');
});
$subSubMenu_selectExits->append($item_selectNonSuper);
my $item_selectSuper = Gtk3::MenuItem->new('_Super-region exits');
$item_selectSuper->signal_connect('activate' => sub {
$self->selectExitTypeCallback('super');
});
$subSubMenu_selectExits->append($item_selectSuper);
my $item_selectExits = Gtk3::MenuItem->new('Select _exits');
$item_selectExits->set_submenu($subSubMenu_selectExits);
$subMenu_select->append($item_selectExits);
$subMenu_select->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Select in region' sub-submenu
my $subSubMenu_selectRegion = Gtk3::Menu->new();
my $item_selectRegionRoom = Gtk3::MenuItem->new('Every _room');
$item_selectRegionRoom->signal_connect('activate' => sub {
$self->selectInRegionCallback('room');
});
$subSubMenu_selectRegion->append($item_selectRegionRoom);
my $item_selectRegionExit = Gtk3::MenuItem->new('Every _exit');
$item_selectRegionExit->signal_connect('activate' => sub {
$self->selectInRegionCallback('exit');
});
$subSubMenu_selectRegion->append($item_selectRegionExit);
my $item_selectRegionRoomTag = Gtk3::MenuItem->new('Every room _tag');
$item_selectRegionRoomTag->signal_connect('activate' => sub {
$self->selectInRegionCallback('room_tag');
});
$subSubMenu_selectRegion->append($item_selectRegionRoomTag);
my $item_selectRegionRoomGuild = Gtk3::MenuItem->new('Every room _guild');
$item_selectRegionRoomGuild->signal_connect('activate' => sub {
$self->selectInRegionCallback('room_guild');
});
$subSubMenu_selectRegion->append($item_selectRegionRoomGuild);
my $item_selectRegionLabel = Gtk3::MenuItem->new('Every _label');
$item_selectRegionLabel->signal_connect('activate' => sub {
$self->selectInRegionCallback('label');
});
$subSubMenu_selectRegion->append($item_selectRegionLabel);
$subSubMenu_selectRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectRegionAbove = Gtk3::MenuItem->new('_All of the above');
$item_selectRegionAbove->signal_connect('activate' => sub {
$self->selectInRegionCallback();
});
$subSubMenu_selectRegion->append($item_selectRegionAbove);
my $item_selectRegion = Gtk3::MenuItem->new('Select in re_gion');
$item_selectRegion->set_submenu($subSubMenu_selectRegion);
$subMenu_select->append($item_selectRegion);
# 'Select in map' sub-submenu
my $subSubMenu_selectMap = Gtk3::Menu->new();
my $item_selectMapRoom = Gtk3::MenuItem->new('Every _room');
$item_selectMapRoom->signal_connect('activate' => sub {
$self->selectInMapCallback('room');
});
$subSubMenu_selectMap->append($item_selectMapRoom);
my $item_selectMapExit = Gtk3::MenuItem->new('Every _exit');
$item_selectMapExit->signal_connect('activate' => sub {
$self->selectInMapCallback('exit');
});
$subSubMenu_selectMap->append($item_selectMapExit);
my $item_selectMapRoomTag = Gtk3::MenuItem->new('Every room _tag');
$item_selectMapRoomTag->signal_connect('activate' => sub {
$self->selectInMapCallback('room_tag');
});
$subSubMenu_selectMap->append($item_selectMapRoomTag);
my $item_selectMapRoomGuild = Gtk3::MenuItem->new('Every room _guild');
$item_selectMapRoomGuild->signal_connect('activate' => sub {
$self->selectInMapCallback('room_guild');
});
$subSubMenu_selectMap->append($item_selectMapRoomGuild);
my $item_selectMapLabel = Gtk3::MenuItem->new('Every _label');
$item_selectMapLabel->signal_connect('activate' => sub {
$self->selectInMapCallback('label');
});
$subSubMenu_selectMap->append($item_selectMapLabel);
$subSubMenu_selectMap->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectMapAbove = Gtk3::MenuItem->new('_All of the above');
$item_selectMapAbove->signal_connect('activate' => sub {
$self->selectInMapCallback();
});
$subSubMenu_selectMap->append($item_selectMapAbove);
my $item_selectMap = Gtk3::MenuItem->new('Select in _map');
$item_selectMap->set_submenu($subSubMenu_selectMap);
$subMenu_select->append($item_selectMap);
my $item_select = Gtk3::MenuItem->new('_Select');
$item_select->set_submenu($subMenu_select);
$column_edit->append($item_select);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'select', $item_select);
# 'Selected items' submenu
my $subMenu_selectedObjs = Gtk3::Menu->new();
my $item_identifyRoom = Gtk3::MenuItem->new('Identify _room(s)');
$item_identifyRoom->signal_connect('activate' => sub {
$self->identifyRoomsCallback();
});
$subMenu_selectedObjs->append($item_identifyRoom);
# (Requires $self->currentRegionmap and EITHER $self->selectedRoom or
# $self->selectedRoomHash or $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'identify_room', $item_identifyRoom);
my $item_identifyExit = Gtk3::MenuItem->new('Identify _exit(s)');
$item_identifyExit->signal_connect('activate' => sub {
$self->identifyExitsCallback();
});
$subMenu_selectedObjs->append($item_identifyExit);
# (Requires $self->currentRegionmap & either $self->selectedExit or
# $self->selectedExitHash)
$self->ivAdd('menuToolItemHash', 'identify_exit', $item_identifyExit);
my $item_selectedObjs = Gtk3::MenuItem->new('_Identify selected items');
$item_selectedObjs->set_submenu($subMenu_selectedObjs);
$column_edit->append($item_selectedObjs);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'selected_objs', $item_selectedObjs);
my $item_unselectAll = Gtk3::MenuItem->new('_Unselect all');
$item_unselectAll->signal_connect('activate' => sub {
$self->setSelectedObj();
});
$column_edit->append($item_unselectAll);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'unselect_all', $item_unselectAll);
$column_edit->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Search' submenu
my $subMenu_search = Gtk3::Menu->new();
my $item_searchModel = Gtk3::MenuItem->new('Search world _model...');
$item_searchModel->signal_connect('activate' => sub {
# Open a 'pref' window to conduct the search
$self->createFreeWin(
'Games::Axmud::PrefWin::Search',
$self,
$self->session,
'World model search',
);
});
$subMenu_search->append($item_searchModel);
$subMenu_search->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_findRoom = Gtk3::MenuItem->new('Find _room...');
$item_findRoom->signal_connect('activate' => sub {
$self->findRoomCallback();
});
$subMenu_search->append($item_findRoom);
my $item_findExit = Gtk3::MenuItem->new('Find _exit...');
$item_findExit->signal_connect('activate' => sub {
$self->findExitCallback();
});
$subMenu_search->append($item_findExit);
my $item_search = Gtk3::ImageMenuItem->new('S_earch');
my $img_search = Gtk3::Image->new_from_stock('gtk-find', 'menu');
$item_search->set_image($img_search);
$item_search->set_submenu($subMenu_search);
$column_edit->append($item_search);
# 'Generate reports' submenu
my $subMenu_reports = Gtk3::Menu->new();
my $item_showSummary = Gtk3::MenuItem->new('_Show general report');
$item_showSummary->signal_connect('activate' => sub {
# (Don't use $self->pseudoCmdMode - we want to see the footer messages)
$self->session->pseudoCmd('modelreport', 'show_all');
});
$subMenu_reports->append($item_showSummary);
my $item_showCurrentRegion = Gtk3::MenuItem->new('S_how current region');
$item_showCurrentRegion->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subMenu_reports->append($item_showCurrentRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_region', $item_showCurrentRegion);
$subMenu_reports->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Character visits' sub-submenu
my $subSubMenu_visits = Gtk3::Menu->new();
my $item_visits1 = Gtk3::MenuItem->new('_All regions/characters');
$item_visits1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -v', 'show_all');
});
$subSubMenu_visits->append($item_visits1);
my $item_visits2 = Gtk3::MenuItem->new('Current _region');
$item_visits2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -v -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_visits->append($item_visits2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_visits_2', $item_visits2);
my $item_visits3 = Gtk3::MenuItem->new('Current _character');
$item_visits3->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -v -c <' . $self->session->currentChar->name . '>',
'show_all',
);
});
$subSubMenu_visits->append($item_visits3);
# (Requires current character profile)
$self->ivAdd('menuToolItemHash', 'report_visits_3', $item_visits3);
my $item_visits4 = Gtk3::MenuItem->new('C_urrent region/character');
$item_visits4->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -v -r <' . $self->currentRegionmap->name . '>' . ' -c <'
. $self->session->currentChar->name . '>',
'show_all',
);
});
$subSubMenu_visits->append($item_visits4);
# (Requires $self->currentRegionmap and current character profile)
$self->ivAdd('menuToolItemHash', 'report_visits_4', $item_visits4);
my $item_visits = Gtk3::MenuItem->new('_Character visits');
$item_visits->set_submenu($subSubMenu_visits);
$subMenu_reports->append($item_visits);
# 'Room guilds' sub-submenu
my $subSubMenu_guilds = Gtk3::Menu->new();
my $item_guilds1 = Gtk3::MenuItem->new('_All regions/guilds');
$item_guilds1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -g', 'show_all');
});
$subSubMenu_guilds->append($item_guilds1);
my $item_guilds2 = Gtk3::MenuItem->new('Current _region');
$item_guilds2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -g -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_guilds->append($item_guilds2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_guilds_2', $item_guilds2);
my $item_guilds3 = Gtk3::MenuItem->new('Current _guild');
$item_guilds3->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -g -n <' . $self->session->currentGuild->name . '>',
'show_all',
);
});
$subSubMenu_guilds->append($item_guilds3);
# (Requires current guild profile)
$self->ivAdd('menuToolItemHash', 'report_guilds_3', $item_guilds3);
my $item_guilds4 = Gtk3::MenuItem->new('C_urrent region/guild');
$item_guilds4->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -g -r <' . $self->currentRegionmap->name . '>' . ' -n <'
. $self->session->currentGuild->name . '>',
'show_all',
);
});
$subSubMenu_guilds->append($item_guilds4);
# (Requires $self->currentRegionmap and current guild profile)
$self->ivAdd('menuToolItemHash', 'report_guilds_4', $item_guilds4);
my $item_guilds = Gtk3::MenuItem->new('Room _guilds');
$item_guilds->set_submenu($subSubMenu_guilds);
$subMenu_reports->append($item_guilds);
# 'Room flags' sub-submenu
my $subSubMenu_roomFlags = Gtk3::Menu->new();
my $item_roomFlags1 = Gtk3::MenuItem->new('_All regions/flags');
$item_roomFlags1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -f', 'show_all');
});
$subSubMenu_roomFlags->append($item_roomFlags1);
my $item_roomFlags2 = Gtk3::MenuItem->new('Current _region');
$item_roomFlags2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -f -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_roomFlags->append($item_roomFlags2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_flags_2', $item_roomFlags2);
my $item_roomFlags3 = Gtk3::MenuItem->new('_Specify flag...');
$item_roomFlags3->signal_connect('activate' => sub {
my (
$choice,
@list,
);
@list = $self->worldModelObj->roomFlagOrderedList;
$choice = $self->showComboDialogue(
'Select room flag',
'Select one of the world model\'s room flags',
\@list,
);
if ($choice) {
$self->session->pseudoCmd(
'modelreport -f -l <' . $choice . '>',
'show_all',
);
}
});
$subSubMenu_roomFlags->append($item_roomFlags3);
my $item_roomFlags4 = Gtk3::MenuItem->new('C_urrent region/specify flag...');
$item_roomFlags4->signal_connect('activate' => sub {
my (
$choice,
@list,
);
@list = $self->worldModelObj->roomFlagOrderedList;
$choice = $self->showComboDialogue(
'Select room flag',
'Select one of the world model\'s room flags',
\@list,
);
if ($choice) {
$self->session->pseudoCmd(
'modelreport -f -r <' . $self->currentRegionmap->name . '>' . ' -l <'
. $choice . '>',
'show_all',
);
}
});
$subSubMenu_roomFlags->append($item_roomFlags4);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_flags_4', $item_roomFlags4);
my $item_roomFlags = Gtk3::MenuItem->new('Room _flags');
$item_roomFlags->set_submenu($subSubMenu_roomFlags);
$subMenu_reports->append($item_roomFlags);
# 'Rooms' sub-submenu
my $subSubMenu_rooms = Gtk3::Menu->new();
my $item_rooms1 = Gtk3::MenuItem->new('_All regions');
$item_rooms1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -m', 'show_all');
});
$subSubMenu_rooms->append($item_rooms1);
my $item_rooms2 = Gtk3::MenuItem->new('_Current region');
$item_rooms2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -m -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_rooms->append($item_rooms2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_rooms_2', $item_rooms2);
my $item_rooms = Gtk3::MenuItem->new('_Rooms');
$item_rooms->set_submenu($subSubMenu_rooms);
$subMenu_reports->append($item_rooms);
# 'Exits' sub-submenu
my $subSubMenu_exits = Gtk3::Menu->new();
my $item_exits1 = Gtk3::MenuItem->new('_All regions');
$item_exits1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -x', 'show_all');
});
$subSubMenu_exits->append($item_exits1);
my $item_exits2 = Gtk3::MenuItem->new('_Current region');
$item_exits2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -x -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_exits->append($item_exits2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_exits_2', $item_exits2);
my $item_exits = Gtk3::MenuItem->new('_Exits');
$item_exits->set_submenu($subSubMenu_exits);
$subMenu_reports->append($item_exits);
# 'Checked directions' sub-submenu
my $subSubMenu_checked = Gtk3::Menu->new();
my $item_checked1 = Gtk3::MenuItem->new('_All regions');
$item_checked1->signal_connect('activate' => sub {
$self->session->pseudoCmd('modelreport -h', 'show_all');
});
$subSubMenu_checked->append($item_checked1);
my $item_checked2 = Gtk3::MenuItem->new('_Current region');
$item_checked2->signal_connect('activate' => sub {
$self->session->pseudoCmd(
'modelreport -h -r <' . $self->currentRegionmap->name . '>',
'show_all',
);
});
$subSubMenu_checked->append($item_checked2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'report_checked_2', $item_checked2);
my $item_checked = Gtk3::MenuItem->new('Checked _directions');
$item_checked->set_submenu($subSubMenu_checked);
$subMenu_reports->append($item_checked);
my $item_reports = Gtk3::MenuItem->new('_Generate reports');
$item_reports->set_submenu($subMenu_reports);
$column_edit->append($item_reports);
$column_edit->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Reset' sub-submenu
my $subMenu_reset = Gtk3::Menu->new();
my $item_resetRoomData = Gtk3::MenuItem->new('Reset _room data...');
$item_resetRoomData->signal_connect('activate' => sub {
$self->resetRoomDataCallback();
});
$subMenu_reset->append($item_resetRoomData);
my $item_resetCharVisits = Gtk3::MenuItem->new('Reset _visits by character...');
$item_resetCharVisits->signal_connect('activate' => sub {
$self->resetVisitsCallback();
});
$subMenu_reset->append($item_resetCharVisits);
my $item_reset = Gtk3::MenuItem->new('_Reset');
$item_reset->set_submenu($subMenu_reset);
$column_edit->append($item_reset);
$column_edit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editDict = Gtk3::ImageMenuItem->new('Edit current _dictionary...');
my $img_editDict = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editDict->set_image($img_editDict);
$item_editDict->signal_connect('activate' => sub {
# Open an 'edit' window for the current dictionary
$self->createFreeWin(
'Games::Axmud::EditWin::Dict',
$self,
$self->session,
'Edit dictionary \'' . $self->session->currentDict->name . '\'',
$self->session->currentDict,
FALSE, # Not temporary
);
});
$column_edit->append($item_editDict);
my $item_addWords = Gtk3::MenuItem->new('Add dictionary _words...');
$item_addWords->signal_connect('activate' => sub {
$self->createFreeWin(
'Games::Axmud::OtherWin::QuickWord',
$self,
$self->session,
'Quick word adder',
);
});
$column_edit->append($item_addWords);
my $item_updateModel = Gtk3::MenuItem->new('U_pdate model words');
$item_updateModel->signal_connect('activate' => sub {
# Use pseudo-command mode 'win_error' - show success messages in the 'main' window,
# error messages in 'dialogue' window
$self->session->pseudoCmd('updatemodel -t', 'win_error');
});
$column_edit->append($item_updateModel);
$column_edit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setupWizard = Gtk3::ImageMenuItem->new('Run _Locator wizard...');
my $img_setupWizard = Gtk3::Image->new_from_stock('gtk-page-setup', 'menu');
$item_setupWizard->set_image($img_setupWizard);
$item_setupWizard->signal_connect('activate' => sub {
if ($self->session->wizWin) {
# Some kind of 'wiz' window is already open
$self->session->wizWin->restoreFocus();
} else {
# Open the Locator wizard window
$self->session->pseudoCmd('locatorwizard', $self->pseudoCmdMode);
}
});
$column_edit->append($item_setupWizard);
my $item_editModel = Gtk3::ImageMenuItem->new('Edit world _model...');
my $img_editModel = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editModel->set_image($img_editModel);
$item_editModel->signal_connect('activate' => sub {
# Open an 'edit' window for the world model
$self->createFreeWin(
'Games::Axmud::EditWin::WorldModel',
$self,
$self->session,
'Edit world model',
$self->session->worldModelObj,
FALSE, # Not temporary
);
});
$column_edit->append($item_editModel);
# Setup complete
return $column_edit;
}
sub enableViewColumn {
# Sets up the 'View' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Local variables
my (
$item_group,
@magList, @shortMagList, @initList, @interiorList,
%interiorHash,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableViewColumn', @_);
}
# Set up column
my $column_view = Gtk3::Menu->new();
if (! $column_view) {
return undef;
}
# 'Window components' submenu
my $subMenu_winComponents = Gtk3::Menu->new();
my $item_showMenuBar = Gtk3::CheckMenuItem->new('Show menu_bar');
$item_showMenuBar->set_active($self->worldModelObj->showMenuBarFlag);
$item_showMenuBar->signal_connect('toggled' => sub {
$self->worldModelObj->toggleWinComponents(
'showMenuBarFlag',
$item_showMenuBar->get_active(),
);
});
$subMenu_winComponents->append($item_showMenuBar);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_menu_bar', $item_showMenuBar);
my $item_showToolbar = Gtk3::CheckMenuItem->new('Show _toolbar');
$item_showToolbar->set_active($self->worldModelObj->showToolbarFlag);
$item_showToolbar->signal_connect('toggled' => sub {
$self->worldModelObj->toggleWinComponents(
'showToolbarFlag',
$item_showToolbar->get_active(),
);
});
$subMenu_winComponents->append($item_showToolbar);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_toolbar', $item_showToolbar);
my $item_showTreeView = Gtk3::CheckMenuItem->new('Show _regions');
$item_showTreeView->set_active($self->worldModelObj->showTreeViewFlag);
$item_showTreeView->signal_connect('toggled' => sub {
$self->worldModelObj->toggleWinComponents(
'showTreeViewFlag',
$item_showTreeView->get_active(),
);
});
$subMenu_winComponents->append($item_showTreeView);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_treeview', $item_showTreeView);
my $item_showCanvas = Gtk3::CheckMenuItem->new('Show _map');
$item_showCanvas->set_active($self->worldModelObj->showCanvasFlag);
$item_showCanvas->signal_connect('toggled' => sub {
$self->worldModelObj->toggleWinComponents(
'showCanvasFlag',
$item_showCanvas->get_active(),
);
});
$subMenu_winComponents->append($item_showCanvas);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_canvas', $item_showCanvas);
$subMenu_winComponents->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_redrawWindow = Gtk3::MenuItem->new('Re_draw window');
$item_redrawWindow->signal_connect('activate' => sub {
$self->redrawWidgets('menu_bar', 'toolbar', 'treeview', 'canvas');
});
$subMenu_winComponents->append($item_redrawWindow);
my $item_windowComponents = Gtk3::MenuItem->new('_Window components');
$item_windowComponents->set_submenu($subMenu_winComponents);
$column_view->append($item_windowComponents);
# 'Current room' submenu
my $subMenu_currentRoom = Gtk3::Menu->new();
my $item_radio1 = Gtk3::RadioMenuItem->new_with_mnemonic(undef, 'Draw _normal room');
$item_radio1->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio1->get_active()) {
$self->worldModelObj->switchMode(
'currentRoomMode',
'single', # New value of ->currentRoomMode
FALSE, # No call to ->redrawRegions; current room is redrawn
'normal_current_mode',
);
}
});
my $item_group0 = $item_radio1->get_group();
$subMenu_currentRoom->append($item_radio1);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'normal_current_mode', $item_radio1);
my $item_radio2 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group0,
'Draw _emphasised room',
);
if ($self->worldModelObj->currentRoomMode eq 'double') {
$item_radio2->set_active(TRUE);
}
$item_radio2->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio2->get_active()) {
$self->worldModelObj->switchMode(
'currentRoomMode',
'double', # New value of ->currentRoomMode
FALSE, # No call to ->redrawRegions; current room is redrawn
'empahsise_current_room',
);
}
});
$subMenu_currentRoom->append($item_radio2);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'empahsise_current_room', $item_radio2);
my $item_radio3 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group0,
'Draw _filled-in room',
);
if ($self->worldModelObj->currentRoomMode eq 'interior') {
$item_radio3->set_active(TRUE);
}
$item_radio3->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio3->get_active()) {
$self->worldModelObj->switchMode(
'currentRoomMode',
'interior', # New value of ->currentRoomMode
FALSE, # No call to ->redrawRegions; current room is redrawn
'fill_in_current_room',
);
}
});
$subMenu_currentRoom->append($item_radio3);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'fill_in_current_room', $item_radio3);
my $item_currentRoom = Gtk3::MenuItem->new('_Draw current room');
$item_currentRoom->set_submenu($subMenu_currentRoom);
$column_view->append($item_currentRoom);
# 'Room filters' submenu
my $subMenu_roomFilters = Gtk3::Menu->new();
my $item_releaseAllFilters = Gtk3::CheckMenuItem->new('_Release all filters');
$item_releaseAllFilters->set_active($self->worldModelObj->allRoomFiltersFlag);
$item_releaseAllFilters->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allRoomFiltersFlag',
$item_releaseAllFilters->get_active(),
TRUE, # Do call $self->redrawRegions
'release_all_filters',
'icon_release_all_filters',
);
}
});
$subMenu_roomFilters->append($item_releaseAllFilters);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'release_all_filters', $item_releaseAllFilters);
$subMenu_roomFilters->append(Gtk3::SeparatorMenuItem->new()); # Separator
my @shortcutList = $axmud::CLIENT->constRoomFilterKeyList;
foreach my $filter ($axmud::CLIENT->constRoomFilterList) {
my $shortcut = shift @shortcutList;
my $menuItem = Gtk3::CheckMenuItem->new('Release ' . $shortcut . ' filter');
$menuItem->set_active($self->worldModelObj->ivShow('roomFilterApplyHash', $filter));
$menuItem->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFilter(
$filter,
$menuItem->get_active(),
);
}
});
$subMenu_roomFilters->append($menuItem);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', $filter . '_filter', $menuItem);
}
my $item_roomFilters = Gtk3::MenuItem->new('Room _filters');
$item_roomFilters->set_submenu($subMenu_roomFilters);
$column_view->append($item_roomFilters);
# 'Room interiors' submenu
my $subMenu_roomInteriors = Gtk3::Menu->new();
@initList = (
'none' => '_Don\'t draw counts',
'shadow_count' => 'Draw _unallocated/shadow exits',
'region_count' => 'Draw re_gion/super region exits',
'checked_count' => 'Draw _checked/checkable directions',
'room_content' => 'Draw _room contents',
'hidden_count' => 'Draw _hidden contents',
'temp_count' => 'Draw _temporary contents',
'word_count' => 'Draw r_ecognised words',
'room_tag' => 'Draw room t_ag',
'room_flag' => 'Draw r_oom flag text',
'visit_count' => 'Draw character _visits',
'compare_count' => 'Draw _matching rooms',
'profile_count' => 'Draw e_xclusive profiles',
'title_descrip' => 'Draw t_itles/descriptions',
'exit_pattern' => 'Draw exit _patterns',
'source_code' => 'Draw room _source code',
'grid_posn' => 'Dra_w grid coordinates',
'vnum' => 'Draw world\'s room v_num',
);
do {
my ($mode, $descrip);
$mode = shift @initList;
$descrip = shift @initList;
push (@interiorList, $mode);
$interiorHash{$mode} = $descrip;
} until (! @initList);
for (my $count = 0; $count < (scalar @interiorList); $count++) {
my ($icon, $mode);
$mode = $interiorList[$count];
# (For $count = 0, $item_group is 'undef')
my $item_radio = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group,
$interiorHash{$mode},
);
if ($self->worldModelObj->roomInteriorMode eq $mode) {
$item_radio->set_active(TRUE);
}
$item_radio->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio->get_active()) {
$self->worldModelObj->switchRoomInteriorMode($mode);
}
});
$item_group = $item_radio->get_group();
$subMenu_roomInteriors->append($item_radio);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'interior_mode_' . $mode, $item_radio);
}
$subMenu_roomInteriors->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_changeCharDrawn = Gtk3::MenuItem->new('Ch_ange character drawn...');
$item_changeCharDrawn->signal_connect('activate' => sub {
# (Callback func has no dependencies)
$self->changeCharDrawnCallback();
});
$subMenu_roomInteriors->append($item_changeCharDrawn);
my $item_roomInteriors = Gtk3::MenuItem->new('R_oom interiors');
$item_roomInteriors->set_submenu($subMenu_roomInteriors);
$column_view->append($item_roomInteriors);
# 'All exits' submenu
my $subMenu_allExits = Gtk3::Menu->new();
my $item_radio11 = Gtk3::RadioMenuItem->new_with_mnemonic(
undef,
'_Use region exit settings',
);
$item_radio11->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio11->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'ask_regionmap', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_defer_exits',
'icon_draw_defer_exits',
);
}
});
my $item_group1 = $item_radio11->get_group();
$subMenu_allExits->append($item_radio11);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_defer_exits', $item_radio11);
my $item_radio12 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group1,
'Draw _no exits',
);
if ($self->worldModelObj->drawExitMode eq 'no_exit') {
$item_radio12->set_active(TRUE);
}
$item_radio12->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio12->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'no_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_no_exits',
'icon_draw_no_exits',
);
}
});
$subMenu_allExits->append($item_radio12);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_no_exits', $item_radio12);
my $item_radio13 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group1,
'Draw _simple exits',
);
if ($self->worldModelObj->drawExitMode eq 'simple_exit') {
$item_radio13->set_active(TRUE);
}
$item_radio13->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio13->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'simple_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_simple_exits',
'icon_draw_simple_exits',
);
}
});
$subMenu_allExits->append($item_radio13);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_simple_exits', $item_radio13);
my $item_radio14 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group1,
'Draw _complex exits',
);
if ($self->worldModelObj->drawExitMode eq 'complex_exit') {
$item_radio14->set_active(TRUE);
}
$item_radio14->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio14->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'complex_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_complex_exits',
'icon_draw_complex_exits',
);
}
});
$subMenu_allExits->append($item_radio14);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_complex_exits', $item_radio14);
$subMenu_allExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_obscuredExits = Gtk3::CheckMenuItem->new('_Obscure unimportant exits');
$item_obscuredExits->set_active($self->worldModelObj->obscuredExitFlag);
$item_obscuredExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'obscuredExitFlag',
$item_obscuredExits->get_active(),
TRUE, # Do call $self->redrawRegions
'obscured_exits',
'icon_obscured_exits',
);
}
});
$subMenu_allExits->append($item_obscuredExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'obscured_exits', $item_obscuredExits);
my $item_autoRedraw = Gtk3::CheckMenuItem->new('_Auto-redraw obscured exits');
$item_autoRedraw->set_active($self->worldModelObj->obscuredExitRedrawFlag);
$item_autoRedraw->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'obscuredExitRedrawFlag',
$item_autoRedraw->get_active(),
TRUE, # Do call $self->redrawRegions
'auto_redraw_obscured',
'icon_auto_redraw_obscured',
);
}
});
$subMenu_allExits->append($item_autoRedraw);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_redraw_obscured', $item_autoRedraw);
my $item_obscuredExitRadius = Gtk3::MenuItem->new('Set obscure _radius...');
$item_obscuredExitRadius->signal_connect('activate' => sub {
$self->obscuredRadiusCallback();
});
$subMenu_allExits->append($item_obscuredExitRadius);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'obscured_exit_radius', $item_obscuredExitRadius);
$subMenu_allExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_drawOrnaments = Gtk3::CheckMenuItem->new('Draw exit orna_ments');
$item_drawOrnaments->set_active($self->worldModelObj->drawOrnamentsFlag);
$item_drawOrnaments->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'drawOrnamentsFlag',
$item_drawOrnaments->get_active(),
TRUE, # Do call $self->redrawRegions
'draw_ornaments',
'icon_draw_ornaments',
);
}
});
$subMenu_allExits->append($item_drawOrnaments);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_ornaments', $item_drawOrnaments);
my $item_allExits = Gtk3::MenuItem->new('Exits (_all regions)');
$item_allExits->set_submenu($subMenu_allExits);
$column_view->append($item_allExits);
# 'Region exits' submenu
my $subMenu_regionExits = Gtk3::Menu->new();
my $item_radio21 = Gtk3::RadioMenuItem->new_with_mnemonic(undef, 'Draw _no exits');
$item_radio21->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio21->get_active()) {
$self->worldModelObj->switchRegionDrawExitMode(
$self->currentRegionmap,
'no_exit',
);
}
});
my $item_group2 = $item_radio21->get_group();
$subMenu_regionExits->append($item_radio21);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'region_draw_no_exits', $item_radio21);
my $item_radio22 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group2,
'Draw _simple exits',
);
if ($self->currentRegionmap && $self->currentRegionmap->drawExitMode eq 'simple_exit') {
$item_radio22->set_active(TRUE);
}
$item_radio22->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio22->get_active()) {
$self->worldModelObj->switchRegionDrawExitMode(
$self->currentRegionmap,
'simple_exit',
);
}
});
$subMenu_regionExits->append($item_radio22);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'region_draw_simple_exits', $item_radio22);
my $item_radio23 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group2,
'Draw _complex exits',
);
if (
$self->currentRegionmap
&& $self->currentRegionmap->drawExitMode eq 'complex_exit'
) {
$item_radio23->set_active(TRUE);
}
$item_radio23->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio23->get_active()) {
$self->worldModelObj->switchRegionDrawExitMode(
$self->currentRegionmap,
'complex_exit',
);
}
});
$subMenu_regionExits->append($item_radio23);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'region_draw_complex_exits', $item_radio23);
$subMenu_regionExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_obscuredExitsRegion = Gtk3::CheckMenuItem->new('_Obscure unimportant exits');
if ($self->currentRegionmap) {
$item_obscuredExitsRegion->set_active($self->currentRegionmap->obscuredExitFlag);
}
$item_obscuredExitsRegion->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleObscuredExitFlag($self->currentRegionmap);
}
});
$subMenu_regionExits->append($item_obscuredExitsRegion);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'obscured_exits_region', $item_obscuredExitsRegion);
my $item_autoRedrawRegion = Gtk3::CheckMenuItem->new('_Auto-redraw obscured exits');
if ($self->currentRegionmap) {
$item_autoRedrawRegion->set_active($self->currentRegionmap->obscuredExitRedrawFlag);
}
$item_autoRedrawRegion->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleObscuredExitRedrawFlag($self->currentRegionmap);
}
});
$subMenu_regionExits->append($item_autoRedrawRegion);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_redraw_obscured_region', $item_autoRedrawRegion);
my $item_obscuredExitRadiusRegion = Gtk3::MenuItem->new('Set obscure _radius...');
$item_obscuredExitRadiusRegion->signal_connect('activate' => sub {
$self->obscuredRadiusCallback($self->currentRegionmap);
});
$subMenu_regionExits->append($item_obscuredExitRadiusRegion);
# (Never desensitised)
$self->ivAdd(
'menuToolItemHash',
'obscured_exit_radius_region',
$item_obscuredExitRadiusRegion,
);
$subMenu_regionExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_drawOrnamentsRegion = Gtk3::CheckMenuItem->new('Draw exit orna_ments');
if ($self->currentRegionmap) {
$item_drawOrnamentsRegion->set_active($self->currentRegionmap->drawOrnamentsFlag);
}
$item_drawOrnamentsRegion->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleDrawOrnamentsFlag($self->currentRegionmap);
}
});
$subMenu_regionExits->append($item_drawOrnamentsRegion);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_ornaments_region', $item_drawOrnamentsRegion);
my $item_regionExits = Gtk3::MenuItem->new('Exits (_current region)');
$item_regionExits->set_submenu($subMenu_regionExits);
$column_view->append($item_regionExits);
# (Requires $self->currentRegionmap and $self->worldModelObj->drawExitMode is
# 'ask_regionmap')
$self->ivAdd('menuToolItemHash', 'draw_region_exits', $item_regionExits);
$column_view->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_zoomIn = Gtk3::ImageMenuItem->new('Zoom i_n');
my $img_zoomIn = Gtk3::Image->new_from_stock('gtk-zoom-in', 'menu');
$item_zoomIn->set_image($img_zoomIn);
$item_zoomIn->signal_connect('activate' => sub {
$self->zoomCallback('in');
});
$column_view->append($item_zoomIn);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'zoom_in', $item_zoomIn);
my $item_zoomOut = Gtk3::ImageMenuItem->new('Zoom _out');
my $img_zoomOut = Gtk3::Image->new_from_stock('gtk-zoom-out', 'menu');
$item_zoomOut->set_image($img_zoomOut);
$item_zoomOut->signal_connect('activate' => sub {
$self->zoomCallback('out');
});
$column_view->append($item_zoomOut);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'zoom_out', $item_zoomOut);
# 'Zoom' submenu
my $subMenu_zoom = Gtk3::Menu->new();
# Import the list of magnifications
@magList = $self->constMagnifyList;
# Use a subset of magnifications from $self->constMagnifyList (and in reverse order to
# that found in $self->constMagnifyList)
@shortMagList = reverse $self->constShortMagnifyList;
foreach my $mag (@shortMagList) {
my $menuItem = Gtk3::MenuItem->new('Zoom ' . $mag * 100 . '%');
$menuItem->signal_connect('activate' => sub {
# No argument causes the called function to prompt the user
$self->zoomCallback($mag);
});
$subMenu_zoom->append($menuItem);
}
$subMenu_zoom->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_zoomMax = Gtk3::MenuItem->new('Zoom _in max');
$item_zoomMax->signal_connect('activate' => sub {
$self->zoomCallback($magList[-1]);
});
$subMenu_zoom->append($item_zoomMax);
my $item_zoomMin = Gtk3::MenuItem->new('Zoom _out max');
$item_zoomMin->signal_connect('activate' => sub {
$self->zoomCallback($magList[0]);
});
$subMenu_zoom->append($item_zoomMin);
$subMenu_zoom->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_zoomPrompt = Gtk3::MenuItem->new('O_ther...');
$item_zoomPrompt->signal_connect('activate' => sub {
# No argument causes the called function to prompt the user
$self->zoomCallback();
});
$subMenu_zoom->append($item_zoomPrompt);
my $item_zoom = Gtk3::ImageMenuItem->new('_Zoom');
my $img_zoom = Gtk3::Image->new_from_stock('gtk-zoom-fit', 'menu');
$item_zoom->set_image($img_zoom);
$item_zoom->set_submenu($subMenu_zoom);
$column_view->append($item_zoom);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'zoom_sub', $item_zoom);
$column_view->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Level' submenu
my $subMenu_level = Gtk3::Menu->new();
my $item_moveUpLevel = Gtk3::MenuItem->new('Move _up level');
$item_moveUpLevel->signal_connect('activate' => sub {
$self->setCurrentLevel($self->currentRegionmap->currentLevel + 1);
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
});
$subMenu_level->append($item_moveUpLevel);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'move_up_level', $item_moveUpLevel);
my $item_moveDownLevel = Gtk3::MenuItem->new('Move _down level');
$item_moveDownLevel->signal_connect('activate' => sub {
$self->setCurrentLevel($self->currentRegionmap->currentLevel - 1);
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
});
$subMenu_level->append($item_moveDownLevel);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'move_down_level', $item_moveDownLevel);
$subMenu_level->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_changeLevel = Gtk3::MenuItem->new('_Change level...');
$item_changeLevel->signal_connect('activate' => sub {
$self->changeLevelCallback();
});
$subMenu_level->append($item_changeLevel);
my $item_level = Gtk3::MenuItem->new('_Level');
$item_level->set_submenu($subMenu_level);
$column_view->append($item_level);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'level_sub', $item_level);
$column_view->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Centre map' submenu
my $subMenu_centreMap = Gtk3::Menu->new();
my $item_centreMap_currentRoom = Gtk3::MenuItem->new('_Current room');
$item_centreMap_currentRoom->signal_connect('activate' => sub {
$self->centreMapOverRoom($self->mapObj->currentRoom);
});
$subMenu_centreMap->append($item_centreMap_currentRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd(
'menuToolItemHash',
'centre_map_current_room',
$item_centreMap_currentRoom,
);
my $item_centreMap_selectRoom = Gtk3::MenuItem->new('_Selected room');
$item_centreMap_selectRoom->signal_connect('activate' => sub {
$self->centreMapOverRoom($self->selectedRoom);
});
$subMenu_centreMap->append($item_centreMap_selectRoom);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd(
'menuToolItemHash',
'centre_map_select_room',
$item_centreMap_selectRoom,
);
my $item_centreMap_lastKnownRoom = Gtk3::MenuItem->new('_Last known room');
$item_centreMap_lastKnownRoom->signal_connect('activate' => sub {
$self->centreMapOverRoom($self->mapObj->lastKnownRoom);
});
$subMenu_centreMap->append($item_centreMap_lastKnownRoom);
# (Requires $self->currentRegionmap & $self->mapObj->lastknownRoom)
$self->ivAdd(
'menuToolItemHash',
'centre_map_last_known_room',
$item_centreMap_lastKnownRoom,
);
$subMenu_centreMap->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_centreMap_middleGrid = Gtk3::MenuItem->new('_Middle of grid');
$item_centreMap_middleGrid->signal_connect('activate' => sub {
$self->setMapPosn(0.5, 0.5);
});
$subMenu_centreMap->append($item_centreMap_middleGrid);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'centre_map_middle_grid', $item_centreMap_middleGrid);
my $item_centreMap = Gtk3::MenuItem->new('Centre _map');
$item_centreMap->set_submenu($subMenu_centreMap);
$column_view->append($item_centreMap);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'centre_map_sub', $item_centreMap);
my $item_repositionAllMaps = Gtk3::MenuItem->new('_Reposition all maps');
$item_repositionAllMaps->signal_connect('activate' => sub {
$self->worldModelObj->repositionMaps();
});
$column_view->append($item_repositionAllMaps);
# 'Tracking' submenu
my $subMenu_tracking = Gtk3::Menu->new();
my $item_trackCurrentRoom = Gtk3::CheckMenuItem->new('_Track current room');
$item_trackCurrentRoom->set_active($self->worldModelObj->trackPosnFlag);
$item_trackCurrentRoom->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'trackPosnFlag',
$item_trackCurrentRoom->get_active(),
FALSE, # Don't call $self->redrawRegions
'track_current_room',
'icon_track_current_room',
);
}
});
$subMenu_tracking->append($item_trackCurrentRoom);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'track_current_room', $item_trackCurrentRoom);
$subMenu_tracking->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_radio31 = Gtk3::RadioMenuItem->new_with_mnemonic(undef, '_Always track');
if (
$self->worldModelObj->trackingSensitivity != 0.33
&& $self->worldModelObj->trackingSensitivity != 0.66
&& $self->worldModelObj->trackingSensitivity != 1
) {
# Only the sensitivity values 0, 0.33, 0.66 and 1 are curently allowed; act as
# though the IV was set to 0
$item_radio31->set_active(TRUE);
}
$item_radio31->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio31->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0);
}
});
my $item_group3 = $item_radio31->get_group();
$subMenu_tracking->append($item_radio31);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'track_always', $item_radio31);
my $item_radio32 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group3,
'Track near _centre',
);
if ($self->worldModelObj->trackingSensitivity == 0.33) {
$item_radio32->set_active(TRUE);
}
$item_radio32->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio32->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0.33);
}
});
$subMenu_tracking->append($item_radio32);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'track_near_centre', $item_radio32);
my $item_radio33 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group3,
'Track near _edge',
);
if ($self->worldModelObj->trackingSensitivity == 0.66) {
$item_radio33->set_active(TRUE);
}
$item_radio33->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio33->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0.66);
}
});
$subMenu_tracking->append($item_radio33);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'track_near_edge', $item_radio33);
my $item_radio34 = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_group3,
'Track if not _visible',
);
if ($self->worldModelObj->trackingSensitivity == 1) {
$item_radio34->set_active(TRUE);
}
$item_radio34->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $item_radio34->get_active()) {
$self->worldModelObj->setTrackingSensitivity(1);
}
});
$subMenu_tracking->append($item_radio34);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'track_not_visible', $item_radio34);
my $item_tracking = Gtk3::MenuItem->new('_Tracking');
$item_tracking->set_submenu($subMenu_tracking);
$column_view->append($item_tracking);
# Setup complete
return $column_view;
}
sub enableModeColumn {
# Called by $self->enableMenu
# Sets up the 'Mode' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableModeColumn', @_);
}
# Set up column
my $column_mode = Gtk3::Menu->new();
if (! $column_mode) {
return undef;
}
# (Save each radio menu item in a hash IV, so that when $self->setMode is called, the radio
# group can be toggled)
my $item_radio1 = Gtk3::RadioMenuItem->new_with_mnemonic(undef, '_Wait mode');
$item_radio1->signal_connect('toggled' => sub {
# (To stop the equivalent toolbar icon from being toggled by the call to ->setMode,
# make use of $self->ignoreMenuUpdateFlag)
if ($item_radio1->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('wait');
}
});
my $item_group = $item_radio1->get_group();
$column_mode->append($item_radio1);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'set_wait_mode', $item_radio1);
my $item_radio2 = Gtk3::RadioMenuItem->new_with_mnemonic($item_group, '_Follow mode');
$item_radio2->signal_connect('toggled' => sub {
if ($item_radio2->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('follow');
}
});
$column_mode->append($item_radio2);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'set_follow_mode', $item_radio2);
my $item_radio3 = Gtk3::RadioMenuItem->new_with_mnemonic($item_group, '_Update mode');
$item_radio3->signal_connect('toggled' => sub {
if ($item_radio3->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('update');
}
});
$column_mode->append($item_radio3);
# (Requires $self->currentRegionmap, GA::Obj::WorldModel->disableUpdateModeFlag set to
# FALSE and a session not in 'connect offline' mode
$self->ivAdd('menuToolItemHash', 'set_update_mode', $item_radio3);
$column_mode->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_dragMode = Gtk3::CheckMenuItem->new('_Drag mode');
$item_dragMode->set_active($self->dragModeFlag);
$item_dragMode->signal_connect('toggled' => sub {
if ($item_dragMode->get_active()) {
$self->ivPoke('dragModeFlag', TRUE);
} else {
$self->ivPoke('dragModeFlag', FALSE);
}
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_drag_mode')) {
my $menuItem = $self->ivShow('menuToolItemHash', 'icon_drag_mode');
$menuItem->set_active($item_dragMode->get_active());
}
});
$column_mode->append($item_dragMode);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'drag_mode', $item_dragMode);
my $item_graffitMode = Gtk3::CheckMenuItem->new('_Graffiti mode');
$item_graffitMode->set_active($self->graffitiModeFlag);
$item_graffitMode->signal_connect('toggled' => sub {
my @redrawList;
if ($item_graffitMode->get_active()) {
$self->ivPoke('graffitiModeFlag', TRUE);
# Tag current room, if any
if ($self->mapObj->currentRoom) {
$self->ivAdd('graffitiHash', $self->mapObj->currentRoom->number);
$self->markObjs('room', $self->mapObj->currentRoom);
$self->doDraw();
}
# Initialise graffitied room counts
$self->setWinTitle();
} else {
$self->ivPoke('graffitiModeFlag', FALSE);
foreach my $num ($self->ivKeys('graffitiHash')) {
my $roomObj = $self->worldModelObj->ivShow('modelHash', $num);
if ($roomObj) {
push (@redrawList, 'room', $self->worldModelObj->ivShow('modelHash', $num));
}
}
$self->ivEmpty('graffitiHash');
# Redraw any graffitied rooms
if (@redrawList) {
$self->markObjs(@redrawList);
$self->doDraw();
}
# Remove graffitied room counts
$self->setWinTitle();
}
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_graffiti_mode')) {
my $menuItem = $self->ivShow('menuToolItemHash', 'icon_graffiti_mode');
$menuItem->set_active($item_graffitMode->get_active());
}
# The menu items which toggle graffiti in selected rooms are desensitised if
# ->graffitiModeFlag is FALSE
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
});
$column_mode->append($item_graffitMode);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'graffiti_mode', $item_graffitMode);
$column_mode->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Match rooms' submenu
my $subMenu_matchRooms = Gtk3::Menu->new();
my $item_matchTitle = Gtk3::CheckMenuItem->new('Match room _titles');
$item_matchTitle->set_active($self->worldModelObj->matchTitleFlag);
$item_matchTitle->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'matchTitleFlag',
$item_matchTitle->get_active(),
FALSE, # Do call $self->redrawRegions
'match_title',
);
}
});
$subMenu_matchRooms->append($item_matchTitle);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'match_title', $item_matchTitle);
my $item_matchDescrip = Gtk3::CheckMenuItem->new('Match room _descriptions');
$item_matchDescrip->set_active($self->worldModelObj->matchDescripFlag);
$item_matchDescrip->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'matchDescripFlag',
$item_matchDescrip->get_active(),
FALSE, # Do call $self->redrawRegions
'match_descrip',
);
}
});
$subMenu_matchRooms->append($item_matchDescrip);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'match_descrip', $item_matchDescrip);
my $item_matchExit = Gtk3::CheckMenuItem->new('Match _exits');
$item_matchExit->set_active($self->worldModelObj->matchExitFlag);
$item_matchExit->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'matchExitFlag',
$item_matchExit->get_active(),
FALSE, # Do call $self->redrawRegions
'match_exit',
);
}
});
$subMenu_matchRooms->append($item_matchExit);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'match_exit', $item_matchExit);
my $item_matchSource = Gtk3::CheckMenuItem->new('Match _source code');
$item_matchSource->set_active($self->worldModelObj->matchSourceFlag);
$item_matchSource->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'matchSourceFlag',
$item_matchSource->get_active(),
FALSE, # Do call $self->redrawRegions
'match_source',
);
}
});
$subMenu_matchRooms->append($item_matchSource);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'match_source', $item_matchSource);
my $item_matchVNum = Gtk3::CheckMenuItem->new('Match room _vnum');
$item_matchVNum->set_active($self->worldModelObj->matchVNumFlag);
$item_matchVNum->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'matchVNumFlag',
$item_matchVNum->get_active(),
FALSE, # Do call $self->redrawRegions
'match_vnum',
);
}
});
$subMenu_matchRooms->append($item_matchVNum);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'match_vnum', $item_matchVNum);
$subMenu_matchRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_verboseChars = Gtk3::MenuItem->new('Set description _length...');
$item_verboseChars->signal_connect('activate' => sub {
$self->verboseCharsCallback();
});
$subMenu_matchRooms->append($item_verboseChars);
my $item_matchRooms = Gtk3::MenuItem->new('_Match rooms');
$item_matchRooms->set_submenu($subMenu_matchRooms);
$column_mode->append($item_matchRooms);
# 'Update rooms' submenu
my $subMenu_updateRooms = Gtk3::Menu->new();
my $item_updateTitle = Gtk3::CheckMenuItem->new('Update room _titles');
$item_updateTitle->set_active($self->worldModelObj->updateTitleFlag);
$item_updateTitle->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateTitleFlag',
$item_updateTitle->get_active(),
FALSE, # Do call $self->redrawRegions
'update_title',
);
}
});
$subMenu_updateRooms->append($item_updateTitle);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_title', $item_updateTitle);
my $item_updateDescrip = Gtk3::CheckMenuItem->new('Update room _descriptions');
$item_updateDescrip->set_active($self->worldModelObj->updateDescripFlag);
$item_updateDescrip->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateDescripFlag',
$item_updateDescrip->get_active(),
FALSE, # Do call $self->redrawRegions
'update_descrip',
);
}
});
$subMenu_updateRooms->append($item_updateDescrip);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_descrip', $item_updateDescrip);
my $item_updateExit = Gtk3::CheckMenuItem->new('Update _exits');
$item_updateExit->set_active($self->worldModelObj->updateExitFlag);
$item_updateExit->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateExitFlag',
$item_updateExit->get_active(),
FALSE, # Do call $self->redrawRegions
'update_exit',
);
}
});
$subMenu_updateRooms->append($item_updateExit);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_exit', $item_updateExit);
my $item_updateOrnament
= Gtk3::CheckMenuItem->new('Update _ornaments from exit state');
$item_updateOrnament->set_active($self->worldModelObj->updateOrnamentFlag);
$item_updateOrnament->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateOrnamentFlag',
$item_updateOrnament->get_active(),
FALSE, # Do call $self->redrawRegions
'update_ornament',
);
}
});
$subMenu_updateRooms->append($item_updateOrnament);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_ornament', $item_updateOrnament);
my $item_updateSource = Gtk3::CheckMenuItem->new('Update _source code');
$item_updateSource->set_active($self->worldModelObj->updateSourceFlag);
$item_updateSource->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateSourceFlag',
$item_updateSource->get_active(),
FALSE, # Do call $self->redrawRegions
'update_source',
);
}
});
$subMenu_updateRooms->append($item_updateSource);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_source', $item_updateSource);
my $item_updateVNum = Gtk3::CheckMenuItem->new('Update room _vnum, etc');
$item_updateVNum->set_active($self->worldModelObj->updateVNumFlag);
$item_updateVNum->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateVNumFlag',
$item_updateVNum->get_active(),
FALSE, # Do call $self->redrawRegions
'update_vnum',
);
}
});
$subMenu_updateRooms->append($item_updateVNum);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_vnum', $item_updateVNum);
my $item_updateRoomCmd = Gtk3::CheckMenuItem->new('Update room _commands');
$item_updateRoomCmd->set_active($self->worldModelObj->updateRoomCmdFlag);
$item_updateRoomCmd->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'updateRoomCmdFlag',
$item_updateRoomCmd->get_active(),
FALSE, # Do call $self->redrawRegions
'update_room_cmd',
);
}
});
$subMenu_updateRooms->append($item_updateRoomCmd);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'update_room_cmd', $item_updateRoomCmd);
$subMenu_updateRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_analyseDescrip = Gtk3::CheckMenuItem->new('_Analyse room descrips');
$item_analyseDescrip->set_active($self->worldModelObj->analyseDescripFlag);
$item_analyseDescrip->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'analyseDescripFlag',
$item_analyseDescrip->get_active(),
FALSE, # Don't call $self->redrawRegions
'analyse_descrip',
);
}
});
$subMenu_updateRooms->append($item_analyseDescrip);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'analyse_descrip', $item_analyseDescrip);
my $item_updateRooms = Gtk3::MenuItem->new('Update _rooms');
$item_updateRooms->set_submenu($subMenu_updateRooms);
$column_mode->append($item_updateRooms);
$column_mode->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Painter' submenu
my $subMenu_painter = Gtk3::Menu->new();
my $item_painterEnabled = Gtk3::CheckMenuItem->new('_Painter enabled');
$item_painterEnabled->set_active($self->painterFlag);
$item_painterEnabled->signal_connect('toggled' => sub {
my $item;
# Toggle the flag
if ($item_painterEnabled->get_active()) {
$self->ivPoke('painterFlag', TRUE);
} else {
$self->ivPoke('painterFlag', FALSE);
}
# Update the corresponding toolbar icon
$item = $self->ivShow('menuToolItemHash', 'icon_enable_painter');
if ($item) {
$item->set_active($self->painterFlag);
}
});
$subMenu_painter->append($item_painterEnabled);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'enable_painter', $item_painterEnabled);
$subMenu_painter->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_paintAll = Gtk3::RadioMenuItem->new_with_mnemonic(undef, 'Paint _all rooms');
$item_paintAll->signal_connect('toggled' => sub {
if ($item_paintAll->get_active) {
$self->worldModelObj->set_paintAllRoomsFlag(TRUE);
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_paint_all')) {
$self->ivShow('menuToolItemHash', 'icon_paint_all')->set_active(TRUE);
}
}
});
my $item_paintGroup = $item_paintAll->get_group();
$subMenu_painter->append($item_paintAll);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'paint_all', $item_paintAll);
my $item_paintNew = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_paintGroup,
'Paint _only new rooms',
);
if (! $self->worldModelObj->paintAllRoomsFlag) {
$item_paintNew->set_active(TRUE);
}
$item_paintNew->signal_connect('toggled' => sub {
if ($item_paintNew->get_active) {
$self->worldModelObj->set_paintAllRoomsFlag(FALSE);
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_paint_new')) {
$self->ivShow('menuToolItemHash', 'icon_paint_new')->set_active(TRUE);
}
}
});
$subMenu_painter->append($item_paintNew);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'paint_new', $item_paintNew);
$subMenu_painter->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_paintNormal = Gtk3::RadioMenuItem->new_with_mnemonic(
undef,
'Paint _normal rooms',
);
$item_paintNormal->signal_connect('toggled' => sub {
if ($item_paintNormal->get_active) {
$self->worldModelObj->painterObj->ivPoke('wildMode', 'normal');
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_paint_normal')) {
$self->ivShow('menuToolItemHash', 'icon_paint_normal')->set_active(TRUE);
}
}
});
my $item_paintGroup2 = $item_paintNormal->get_group();
$subMenu_painter->append($item_paintNormal);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'paint_normal', $item_paintNormal);
my $item_paintWild = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_paintGroup2,
'Paint _wilderness rooms',
);
if ($self->worldModelObj->painterObj->wildMode eq 'wild') {
$item_paintWild->set_active(TRUE);
}
$item_paintWild->signal_connect('toggled' => sub {
if ($item_paintWild->get_active) {
$self->worldModelObj->painterObj->ivPoke('wildMode', 'wild');
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_paint_wild')) {
$self->ivShow('menuToolItemHash', 'icon_paint_wild')->set_active(TRUE);
}
}
});
$subMenu_painter->append($item_paintWild);
# (Requires $self->session->currentWorld->basicMappingFlag to be FALSE)
$self->ivAdd('menuToolItemHash', 'paint_wild', $item_paintWild);
my $item_paintBorder = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_paintGroup2,
'Paint wilderness _border rooms',
);
if ($self->worldModelObj->painterObj->wildMode eq 'border') {
$item_paintBorder->set_active(TRUE);
}
$item_paintBorder->signal_connect('toggled' => sub {
if ($item_paintBorder->get_active) {
$self->worldModelObj->painterObj->ivPoke('wildMode', 'border');
# Set the equivalent toolbar button
if ($self->ivExists('menuToolItemHash', 'icon_paint_border')) {
$self->ivShow('menuToolItemHash', 'icon_paint_border')->set_active(TRUE);
}
}
});
$subMenu_painter->append($item_paintBorder);
# (Requires $self->session->currentWorld->basicMappingFlag to be FALSE)
$self->ivAdd('menuToolItemHash', 'paint_border', $item_paintBorder);
$subMenu_painter->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_repaintCurrentRoom = Gtk3::MenuItem->new('Repaint _current room');
$item_repaintCurrentRoom->signal_connect('activate' => sub {
if ($self->mapObj->currentRoom) {
# Repaint the current room. The TRUE argument instructs the function to tell
# the world model to redraw the room in every Automapper window
$self->paintRoom($self->mapObj->currentRoom, TRUE);
}
});
$subMenu_painter->append($item_repaintCurrentRoom);
# (Requires $self->currentRegionmap and $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'repaint_current', $item_repaintCurrentRoom);
my $item_repaintSelectedRooms = Gtk3::MenuItem->new('Repaint _selected rooms');
$item_repaintSelectedRooms->signal_connect('activate' => sub {
$self->repaintSelectedRoomsCallback();
});
$subMenu_painter->append($item_repaintSelectedRooms);
# (Requires $self->currentRegionmap and either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'repaint_selected', $item_repaintSelectedRooms);
$subMenu_painter->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editPainter = Gtk3::ImageMenuItem->new('_Edit painter...');
my $img_editPainter = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editPainter->set_image($img_editPainter);
$item_editPainter->signal_connect('activate' => sub {
# Open an 'edit' window for the painter object
$self->createFreeWin(
'Games::Axmud::EditWin::Painter',
$self,
$self->session,
'Edit world model painter',
$self->worldModelObj->painterObj,
FALSE, # Not temporary
);
});
$subMenu_painter->append($item_editPainter);
$subMenu_painter->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPainter = Gtk3::MenuItem->new('_Reset painter');
$item_resetPainter->signal_connect('activate' => sub {
$self->worldModelObj->resetPainter($self->session);
$self->showMsgDialogue(
'Painter',
'info',
'The painter object has been reset',
'ok',
);
});
$subMenu_painter->append($item_resetPainter);
my $item_painter = Gtk3::ImageMenuItem->new('_Painter');
my $img_painter = Gtk3::Image->new_from_stock('gtk-select-color', 'menu');
$item_painter->set_image($img_painter);
$item_painter->set_submenu($subMenu_painter);
$column_mode->append($item_painter);
$column_mode->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Auto-compare' submenu
my $subMenu_autoCompare = Gtk3::Menu->new();
my $item_compareDefault = Gtk3::RadioMenuItem->new_with_mnemonic(
undef,
'_Don\'t auto-compare current room',
);
$item_compareDefault->signal_connect('toggled' => sub {
if ($item_compareDefault->get_active) {
$self->worldModelObj->setAutoCompareMode('default');
}
});
my $item_compareGroup = $item_compareDefault->get_group();
$subMenu_autoCompare->append($item_compareDefault);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_default', $item_compareDefault);
my $item_compareNew = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_compareGroup,
'Auto-compare _new rooms',
);
if ($self->worldModelObj->autoCompareMode eq 'new') {
$item_compareNew->set_active(TRUE);
}
$item_compareNew->signal_connect('toggled' => sub {
if ($item_compareNew->get_active) {
$self->worldModelObj->setAutoCompareMode('new');
}
});
$subMenu_autoCompare->append($item_compareNew);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_new', $item_compareNew);
my $item_compareCurrent = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_compareGroup,
'Auto-compare the _current room',
);
if ($self->worldModelObj->autoCompareMode eq 'current') {
$item_compareCurrent->set_active(TRUE);
}
$item_compareCurrent->signal_connect('toggled' => sub {
if ($item_compareCurrent->get_active) {
$self->worldModelObj->setAutoCompareMode('current');
}
});
$subMenu_autoCompare->append($item_compareCurrent);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_current', $item_compareCurrent);
$subMenu_autoCompare->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_compareRegion = Gtk3::RadioMenuItem->new_with_mnemonic(
undef,
'Compare with rooms in _same region',
);
$item_compareRegion->signal_connect('toggled' => sub {
if ($item_compareRegion->get_active) {
$self->worldModelObj->toggleAutoCompareAllFlag(FALSE);
}
});
my $item_compareRegionGroup = $item_compareRegion->get_group();
$subMenu_autoCompare->append($item_compareRegion);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_region', $item_compareRegion);
my $item_compareWhole = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_compareRegionGroup,
'Compare with rooms in _whole world',
);
if ($self->worldModelObj->autoCompareAllFlag) {
$item_compareWhole->set_active(TRUE);
}
$item_compareWhole->signal_connect('toggled' => sub {
if ($item_compareWhole->get_active) {
$self->worldModelObj->toggleAutoCompareAllFlag(TRUE);
}
});
$subMenu_autoCompare->append($item_compareWhole);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_model', $item_compareWhole);
$subMenu_autoCompare->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_compareMax = Gtk3::MenuItem->new('Set _limit on room comparisons...');
$item_compareMax->signal_connect('activate' => sub {
$self->autoCompareMaxCallback();
});
$subMenu_autoCompare->append($item_compareMax);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_compare_max', $item_compareMax);
my $item_autoCompare = Gtk3::MenuItem->new('_Auto-compare');
$item_autoCompare->set_submenu($subMenu_autoCompare);
$column_mode->append($item_autoCompare);
# 'Auto-rescue mode' submenu
my $subMenu_autoRescue = Gtk3::Menu->new();
my $item_autoRescueEnable = Gtk3::CheckMenuItem->new('_Enable auto-rescue mode');
$item_autoRescueEnable->set_active($self->worldModelObj->autoRescueFlag);
$item_autoRescueEnable->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescueFlag',
$item_autoRescueEnable->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue',
);
}
});
$subMenu_autoRescue->append($item_autoRescueEnable);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue', $item_autoRescueEnable);
$subMenu_autoRescue->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_autoRescueFirst = Gtk3::CheckMenuItem->new(
'_Merge at first matching room',
);
$item_autoRescueFirst->set_active($self->worldModelObj->autoRescueFirstFlag);
$item_autoRescueFirst->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescueFirstFlag',
$item_autoRescueFirst->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue_prompt',
);
}
});
$subMenu_autoRescue->append($item_autoRescueFirst);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue_first', $item_autoRescueFirst);
my $item_autoRescuePrompt = Gtk3::CheckMenuItem->new('_Prompt before merging');
$item_autoRescuePrompt->set_active($self->worldModelObj->autoRescuePromptFlag);
$item_autoRescuePrompt->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescuePromptFlag',
$item_autoRescuePrompt->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue_prompt',
);
}
});
$subMenu_autoRescue->append($item_autoRescuePrompt);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue_prompt', $item_autoRescuePrompt);
$subMenu_autoRescue->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_autoRescueNoMove = Gtk3::CheckMenuItem->new('_Don\'t move non-matching rooms');
$item_autoRescueNoMove->set_active($self->worldModelObj->autoRescueNoMoveFlag);
$item_autoRescueNoMove->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescueNoMoveFlag',
$item_autoRescueNoMove->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue_no_move',
);
}
});
$subMenu_autoRescue->append($item_autoRescueNoMove);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue_no_move', $item_autoRescueNoMove);
my $item_autoRescueVisits = Gtk3::CheckMenuItem->new(
'_Only update visits in merged rooms',
);
$item_autoRescueVisits->set_active($self->worldModelObj->autoRescueVisitsFlag);
$item_autoRescueVisits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescueVisitsFlag',
$item_autoRescueVisits->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue_visits',
);
}
});
$subMenu_autoRescue->append($item_autoRescueVisits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue_visits', $item_autoRescueVisits);
my $item_autoRescueForce = Gtk3::CheckMenuItem->new(
'_Temporarily switch to \'update\' mode',
);
$item_autoRescueForce->set_active($self->worldModelObj->autoRescueForceFlag);
$item_autoRescueForce->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoRescueForceFlag',
$item_autoRescueForce->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_rescue_force',
);
}
});
$subMenu_autoRescue->append($item_autoRescueForce);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_rescue_force', $item_autoRescueForce);
my $item_autoRescue = Gtk3::MenuItem->new('Auto-r_escue mode');
$item_autoRescue->set_submenu($subMenu_autoRescue);
$column_mode->append($item_autoRescue);
# 'Auto-slide mode' submenu
my $subMenu_autoSlide = Gtk3::Menu->new();
my $item_slideMode = Gtk3::RadioMenuItem->new_with_mnemonic(
undef,
'_Don\'t auto-slide new rooms',
);
$item_slideMode->signal_connect('toggled' => sub {
if ($item_slideMode->get_active) {
$self->worldModelObj->setAutoSlideMode('default');
}
});
my $item_slideGroup = $item_slideMode->get_group();
$subMenu_autoSlide->append($item_slideMode);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_default', $item_slideMode);
my $item_slideOrigPull = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide original room _backwards',
);
if ($self->worldModelObj->autoSlideMode eq 'orig_pull') {
$item_slideOrigPull->set_active(TRUE);
}
$item_slideOrigPull->signal_connect('toggled' => sub {
if ($item_slideOrigPull->get_active) {
$self->worldModelObj->setAutoSlideMode('orig_pull');
}
});
$subMenu_autoSlide->append($item_slideOrigPull);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideOrigPull);
my $item_slideOrigPush = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide original room _forwards',
);
if ($self->worldModelObj->autoSlideMode eq 'orig_push') {
$item_slideOrigPush->set_active(TRUE);
}
$item_slideOrigPush->signal_connect('toggled' => sub {
if ($item_slideOrigPush->get_active) {
$self->worldModelObj->setAutoSlideMode('orig_push');
}
});
$subMenu_autoSlide->append($item_slideOrigPush);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideOrigPush);
my $item_slideOtherPull = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide blocking room b_ackwards',
);
if ($self->worldModelObj->autoSlideMode eq 'other_pull') {
$item_slideOtherPull->set_active(TRUE);
}
$item_slideOtherPull->signal_connect('toggled' => sub {
if ($item_slideOtherPull->get_active) {
$self->worldModelObj->setAutoSlideMode('other_pull');
}
});
$subMenu_autoSlide->append($item_slideOtherPull);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideOtherPull);
my $item_slideOtherPush = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide blocking room f_orwards',
);
if ($self->worldModelObj->autoSlideMode eq 'other_push') {
$item_slideOtherPush->set_active(TRUE);
}
$item_slideOtherPush->signal_connect('toggled' => sub {
if ($item_slideOtherPush->get_active) {
$self->worldModelObj->setAutoSlideMode('other_push');
}
});
$subMenu_autoSlide->append($item_slideOtherPush);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideOtherPush);
my $item_slideDestPull = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide new room ba_ckwards',
);
if ($self->worldModelObj->autoSlideMode eq 'dest_pull') {
$item_slideDestPull->set_active(TRUE);
}
$item_slideDestPull->signal_connect('toggled' => sub {
if ($item_slideDestPull->get_active) {
$self->worldModelObj->setAutoSlideMode('dest_pull');
}
});
$subMenu_autoSlide->append($item_slideDestPull);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideDestPull);
my $item_slideDestPush = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_slideGroup,
'Slide new room fo_rwards',
);
if ($self->worldModelObj->autoSlideMode eq 'dest_push') {
$item_slideDestPush->set_active(TRUE);
}
$item_slideDestPush->signal_connect('toggled' => sub {
if ($item_slideDestPush->get_active) {
$self->worldModelObj->setAutoSlideMode('dest_push');
}
});
$subMenu_autoSlide->append($item_slideDestPush);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_orig_pull', $item_slideDestPush);
$subMenu_autoSlide->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_slideMax = Gtk3::MenuItem->new('Set _limit on slide distance...');
$item_slideMax->signal_connect('activate' => sub {
$self->autoSlideMaxCallback();
});
$subMenu_autoSlide->append($item_slideMax);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'slide_max', $item_slideMax);
my $item_autoSlide = Gtk3::MenuItem->new('Auto-s_lide mode');
$item_autoSlide->set_submenu($subMenu_autoSlide);
$column_mode->append($item_autoSlide);
$column_mode->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Start-up flags' submenu
my $subMenu_startUpFlags = Gtk3::Menu->new();
my $item_autoOpenWindow = Gtk3::CheckMenuItem->new('Open _automapper on startup');
$item_autoOpenWindow->set_active($self->worldModelObj->autoOpenWinFlag);
$item_autoOpenWindow->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autoOpenWinFlag',
$item_autoOpenWindow->get_active(),
FALSE, # Don't call $self->redrawRegions
'auto_open_win',
);
}
});
$subMenu_startUpFlags->append($item_autoOpenWindow);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'auto_open_win', $item_autoOpenWindow);
my $item_pseudoWin = Gtk3::CheckMenuItem->new('Open as _pseudo-window');
$item_pseudoWin->set_active($self->worldModelObj->pseudoWinFlag);
$item_pseudoWin->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'pseudoWinFlag',
$item_pseudoWin->get_active(),
FALSE, # Don't call $self->redrawRegions
'pseudo_win',
);
}
});
$subMenu_startUpFlags->append($item_pseudoWin);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'pseudo_win', $item_pseudoWin);
my $item_allowTrackAlone = Gtk3::CheckMenuItem->new('_Follow character after closing');
$item_allowTrackAlone->set_active($self->worldModelObj->allowTrackAloneFlag);
$item_allowTrackAlone->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allowTrackAloneFlag',
$item_allowTrackAlone->get_active(),
FALSE, # Don't call $self->redrawRegions
'keep_following',
);
}
});
$subMenu_startUpFlags->append($item_allowTrackAlone);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'keep_following', $item_allowTrackAlone);
my $item_startUpFlags = Gtk3::MenuItem->new('S_tart-up flags');
$item_startUpFlags->set_submenu($subMenu_startUpFlags);
$column_mode->append($item_startUpFlags);
# 'Drawing flags' submenu
my $subMenu_drawingFlags = Gtk3::Menu->new();
my $item_roomTagsInCaps = Gtk3::CheckMenuItem->new('_Capitalise room tags');
$item_roomTagsInCaps->set_active($self->worldModelObj->capitalisedRoomTagFlag);
$item_roomTagsInCaps->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'capitalisedRoomTagFlag',
$item_roomTagsInCaps->get_active(),
TRUE, # Do call $self->redrawRegions
'room_tags_capitalised',
);
}
});
$subMenu_drawingFlags->append($item_roomTagsInCaps);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'room_tags_capitalised', $item_roomTagsInCaps);
my $item_drawBentExits = Gtk3::CheckMenuItem->new('Draw _bent broken exits');
$item_drawBentExits->set_active($self->worldModelObj->drawBentExitsFlag);
$item_drawBentExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'drawBentExitsFlag',
$item_drawBentExits->get_active(),
FALSE, # Don't call $self->redrawRegions
'draw_bent_exits',
);
}
});
$subMenu_drawingFlags->append($item_drawBentExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_bent_exits', $item_drawBentExits);
my $item_drawRoomEcho = Gtk3::CheckMenuItem->new('Draw _room echos');
$item_drawRoomEcho->set_active($self->worldModelObj->drawRoomEchoFlag);
$item_drawRoomEcho->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'drawRoomEchoFlag',
$item_drawRoomEcho->get_active(),
TRUE, # Do call $self->redrawRegions
'draw_room_echo',
);
}
});
$subMenu_drawingFlags->append($item_drawRoomEcho);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_room_echo', $item_drawRoomEcho);
my $item_showTooltips = Gtk3::CheckMenuItem->new('Show _tooltips');
$item_showTooltips->set_active($self->worldModelObj->showTooltipsFlag);
$item_showTooltips->signal_connect('toggled' => sub {
$self->worldModelObj->toggleShowTooltipsFlag(
$item_showTooltips->get_active(),
);
});
$subMenu_drawingFlags->append($item_showTooltips);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_tooltips', $item_showTooltips);
my $item_showNotes = Gtk3::CheckMenuItem->new('Show room _notes in tooltips');
$item_showNotes->set_active($self->worldModelObj->showNotesFlag);
$item_showNotes->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'showNotesFlag',
$item_showNotes->get_active(),
FALSE, # Don't call $self->redrawRegions
'show_notes',
);
}
});
$subMenu_drawingFlags->append($item_showNotes);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_notes', $item_showNotes);
my $item_drawingFlags = Gtk3::MenuItem->new('Draw_ing flags');
$item_drawingFlags->set_submenu($subMenu_drawingFlags);
$column_mode->append($item_drawingFlags);
# 'Movement flags' submenu
my $subMenu_moves = Gtk3::Menu->new();
my $item_allowAssisted = Gtk3::CheckMenuItem->new('_Allow assisted moves');
$item_allowAssisted->set_active($self->worldModelObj->assistedMovesFlag);
$item_allowAssisted->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedMovesFlag',
$item_allowAssisted->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_assisted_moves',
);
# The menu items below which set ->protectedMovesFlag and
# ->superProtectedMovesFlag are desensitised if ->assistedMovesFlag is FALSE
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
}
});
$subMenu_moves->append($item_allowAssisted);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_assisted_moves', $item_allowAssisted);
$subMenu_moves->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_assistedBreak = Gtk3::CheckMenuItem->new('_Break doors before move');
$item_assistedBreak->set_active($self->worldModelObj->assistedBreakFlag);
$item_assistedBreak->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedBreakFlag',
$item_assistedBreak->get_active(),
FALSE, # Don't call $self->redrawRegions
'break_before_move',
);
}
});
$subMenu_moves->append($item_assistedBreak);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'break_before_move', $item_assistedBreak);
my $item_assistedPick = Gtk3::CheckMenuItem->new('_Pick doors before move');
$item_assistedPick->set_active($self->worldModelObj->assistedPickFlag);
$item_assistedPick->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedPickFlag',
$item_assistedPick->get_active(),
FALSE, # Don't call $self->redrawRegions
'pick_before_move',
);
}
});
$subMenu_moves->append($item_assistedPick);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'pick_before_move', $item_assistedPick);
my $item_assistedUnlock = Gtk3::CheckMenuItem->new('_Unlock doors before move');
$item_assistedUnlock->set_active($self->worldModelObj->assistedUnlockFlag);
$item_assistedUnlock->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedUnlockFlag',
$item_assistedUnlock->get_active(),
FALSE, # Don't call $self->redrawRegions
'unlock_before_move',
);
}
});
$subMenu_moves->append($item_assistedUnlock);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'unlock_before_move', $item_assistedUnlock);
my $item_assistedOpen = Gtk3::CheckMenuItem->new('_Open doors before move');
$item_assistedOpen->set_active($self->worldModelObj->assistedOpenFlag);
$item_assistedOpen->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedOpenFlag',
$item_assistedOpen->get_active(),
FALSE, # Don't call $self->redrawRegions
'open_before_move',
);
}
});
$subMenu_moves->append($item_assistedOpen);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'open_before_move', $item_assistedOpen);
my $item_assistedClose = Gtk3::CheckMenuItem->new('_Close doors after move');
$item_assistedClose->set_active($self->worldModelObj->assistedCloseFlag);
$item_assistedClose->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'assistedCloseFlag',
$item_assistedClose->get_active(),
FALSE, # Don't call $self->redrawRegions
'close_after_move',
);
}
});
$subMenu_moves->append($item_assistedClose);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'close_after_move', $item_assistedClose);
my $item_assistedLock = Gtk3::CheckMenuItem->new('_Lock doors after move');
$item_assistedLock->set_active($self->worldModelObj->assistedLockFlag);
$item_assistedLock->signal_connect('toggled' => sub {
if (! $self->assistedLockFlag) {
$self->worldModelObj->toggleFlag(
'assistedLockFlag',
$item_assistedLock->get_active(),
FALSE, # Don't call $self->redrawRegions
'lock_after_move',
);
}
});
$subMenu_moves->append($item_assistedLock);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'lock_after_move', $item_assistedLock);
$subMenu_moves->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_allowProtected = Gtk3::CheckMenuItem->new('Allow p_rotected moves');
$item_allowProtected->set_active($self->worldModelObj->protectedMovesFlag);
$item_allowProtected->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'protectedMovesFlag',
$item_allowProtected->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_protected_moves',
);
# The menu item below which sets ->crafyMovesFlag is desensitised if
# ->assistedMovesFlag is false
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
}
});
$subMenu_moves->append($item_allowProtected);
# (Requires $self->worldModelObj->assistedMovesFlag)
$self->ivAdd('menuToolItemHash', 'allow_protected_moves', $item_allowProtected);
my $item_allowSuper = Gtk3::CheckMenuItem->new('Ca_ncel commands when overruled');
$item_allowSuper->set_active($self->worldModelObj->superProtectedMovesFlag);
$item_allowSuper->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'superProtectedMovesFlag',
$item_allowSuper->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_super_protected_moves',
);
}
});
$subMenu_moves->append($item_allowSuper);
# (Requires $self->worldModelObj->assistedMovesFlag)
$self->ivAdd('menuToolItemHash', 'allow_super_protected_moves', $item_allowSuper);
$subMenu_moves->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_allowCrafty = Gtk3::CheckMenuItem->new('Allow crafty _moves');
$item_allowCrafty->set_active($self->worldModelObj->craftyMovesFlag);
$item_allowCrafty->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'craftyMovesFlag',
$item_allowCrafty->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_crafty_moves',
);
}
});
$subMenu_moves->append($item_allowCrafty);
# (Requires $self->worldModelObj->protectedMovesFlag set to be FALSE)
$self->ivAdd('menuToolItemHash', 'allow_crafty_moves', $item_allowCrafty);
my $item_moves = Gtk3::MenuItem->new('Mo_vement flags');
$item_moves->set_submenu($subMenu_moves);
$column_mode->append($item_moves);
# 'Other flags' submenu
my $subMenu_otherFlags = Gtk3::Menu->new();
my $item_allowModelScripts = Gtk3::CheckMenuItem->new('_Allow model-wide scripts');
$item_allowModelScripts->set_active($self->worldModelObj->allowModelScriptFlag);
$item_allowModelScripts->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allowModelScriptFlag',
$item_allowModelScripts->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_model_scripts',
);
}
});
$subMenu_otherFlags->append($item_allowModelScripts);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_model_scripts', $item_allowModelScripts);
my $item_allowRoomScripts = Gtk3::CheckMenuItem->new(
'Allow ' . $axmud::BASIC_NAME . ' _scripts',
);
$item_allowRoomScripts->set_active($self->worldModelObj->allowRoomScriptFlag);
$item_allowRoomScripts->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allowRoomScriptFlag',
$item_allowRoomScripts->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_room_scripts',
);
}
});
$subMenu_otherFlags->append($item_allowRoomScripts);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_room_scripts', $item_allowRoomScripts);
my $item_countVisits = Gtk3::CheckMenuItem->new('_Count character visits');
$item_countVisits->set_active($self->worldModelObj->countVisitsFlag);
$item_countVisits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'countVisitsFlag',
$item_countVisits->get_active(),
FALSE, # Don't call $self->redrawRegions
'count_char_visits',
);
}
});
$subMenu_otherFlags->append($item_countVisits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'count_char_visits', $item_countVisits);
my $item_disableUpdate = Gtk3::CheckMenuItem->new('_Disable update mode');
$item_disableUpdate->set_active($self->worldModelObj->disableUpdateModeFlag);
$item_disableUpdate->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleDisableUpdateModeFlag(
$item_disableUpdate->get_active(),
);
}
});
$subMenu_otherFlags->append($item_disableUpdate);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'disable_update_mode', $item_disableUpdate);
my $item_explainGetLost = Gtk3::CheckMenuItem->new('_Explain when getting lost');
$item_explainGetLost->set_active($self->worldModelObj->explainGetLostFlag);
$item_explainGetLost->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'explainGetLostFlag',
$item_explainGetLost->get_active(),
FALSE, # Don't call $self->redrawRegions
'explain_get_lost',
);
}
});
$subMenu_otherFlags->append($item_explainGetLost);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'explain_get_lost', $item_explainGetLost);
my $item_followAnchor = Gtk3::CheckMenuItem->new('New exits for _follow anchors');
$item_followAnchor->set_active($self->worldModelObj->followAnchorFlag);
$item_followAnchor->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'followAnchorFlag',
$item_followAnchor->get_active(),
FALSE, # Don't call $self->redrawRegions
'follow_anchor',
);
}
});
$subMenu_otherFlags->append($item_followAnchor);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'follow_anchor', $item_followAnchor);
my $item_allowCtrlCopy = Gtk3::CheckMenuItem->new('_Move rooms to click with CTRL+C');
$item_allowCtrlCopy->set_active($self->worldModelObj->allowCtrlCopyFlag);
$item_allowCtrlCopy->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allowCtrlCopyFlag',
$item_allowCtrlCopy->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_ctrl_copy',
);
}
});
$subMenu_otherFlags->append($item_allowCtrlCopy);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_ctrl_copy', $item_allowCtrlCopy);
my $item_showAllPrimary = Gtk3::CheckMenuItem->new('S_how all directions in dialogues');
$item_showAllPrimary->set_active($self->worldModelObj->showAllPrimaryFlag);
$item_showAllPrimary->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'showAllPrimaryFlag',
$item_showAllPrimary->get_active(),
FALSE, # Don't call $self->redrawRegions
'show_all_primary',
);
}
});
$subMenu_otherFlags->append($item_showAllPrimary);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'show_all_primary', $item_showAllPrimary);
my $item_otherFlags = Gtk3::MenuItem->new('_Other flags');
$item_otherFlags->set_submenu($subMenu_otherFlags);
$column_mode->append($item_otherFlags);
# Setup complete
return $column_mode;
}
sub enableRegionsColumn {
# Called by $self->enableMenu
# Sets up the 'Regions' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableRegionsColumn', @_);
}
# Set up column
my $column_regions = Gtk3::Menu->new();
if (! $column_regions) {
return undef;
}
my $item_newRegion = Gtk3::ImageMenuItem->new('_New region...');
my $img_newRegion = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_newRegion->set_image($img_newRegion);
$item_newRegion->signal_connect('activate' => sub {
$self->newRegionCallback(FALSE);
});
$column_regions->append($item_newRegion);
my $item_newTempRegion = Gtk3::ImageMenuItem->new('New _temporary region...');
my $img_newTempRegion = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_newTempRegion->set_image($img_newTempRegion);
$item_newTempRegion->signal_connect('activate' => sub {
$self->newRegionCallback(TRUE);
});
$column_regions->append($item_newTempRegion);
$column_regions->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editRegion = Gtk3::ImageMenuItem->new('_Edit region...');
my $img_editRegion = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editRegion->set_image($img_editRegion);
$item_editRegion->signal_connect('activate' => sub {
$self->editRegionCallback();
});
$column_regions->append($item_editRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'edit_region', $item_editRegion);
my $item_editRegionmap = Gtk3::ImageMenuItem->new('Edit _regionmap...');
my $img_editRegionmap = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editRegionmap->set_image($img_editRegionmap);
$item_editRegionmap->signal_connect('activate' => sub {
# Open an 'edit' window for the regionmap
$self->createFreeWin(
'Games::Axmud::EditWin::Regionmap',
$self,
$self->session,
'Edit \'' . $self->currentRegionmap->name . '\' regionmap',
$self->currentRegionmap,
FALSE, # Not temporary
);
});
$column_regions->append($item_editRegionmap);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'edit_regionmap', $item_editRegionmap);
$column_regions->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Region list' submenu
my $subMenu_regionsTree = Gtk3::Menu->new();
my $item_resetList = Gtk3::MenuItem->new('_Reset region list');
$item_resetList->signal_connect('activate' => sub {
$self->worldModelObj->resetRegionList();
});
$subMenu_regionsTree->append($item_resetList);
my $item_reverseList = Gtk3::MenuItem->new('Re_verse region list');
$item_reverseList->signal_connect('activate' => sub {
$self->worldModelObj->reverseRegionList();
});
$subMenu_regionsTree->append($item_reverseList);
$subMenu_regionsTree->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_moveCurrentRegion = Gtk3::MenuItem->new('_Move current region to top');
$item_moveCurrentRegion->signal_connect('activate' => sub {
$self->worldModelObj->moveRegionToTop($self->currentRegionmap);
});
$subMenu_regionsTree->append($item_moveCurrentRegion);
# (Requires $self->currentRegionmap for a region that doesn't have a parent region)
$self->ivAdd('menuToolItemHash', 'move_region_top', $item_moveCurrentRegion);
$subMenu_regionsTree->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_identifyRegion = Gtk3::MenuItem->new('_Identify highlighted region');
$item_identifyRegion->signal_connect('activate' => sub {
$self->identifyRegionCallback();
});
$subMenu_regionsTree->append($item_identifyRegion);
# (Requires $self->treeViewSelectedLine)
$self->ivAdd('menuToolItemHash', 'identify_region', $item_identifyRegion);
my $item_regionsTree = Gtk3::MenuItem->new('Region _list');
$item_regionsTree->set_submenu($subMenu_regionsTree);
$column_regions->append($item_regionsTree);
# 'Current region' submenu
my $subMenu_currentRegion = Gtk3::Menu->new();
my $item_renameRegion = Gtk3::MenuItem->new('_Rename region...');
$item_renameRegion->signal_connect('activate' => sub {
$self->renameRegionCallback();
});
$subMenu_currentRegion->append($item_renameRegion);
my $item_changeParent = Gtk3::MenuItem->new('_Set parent region...');
$item_changeParent->signal_connect('activate' => sub {
$self->changeRegionParentCallback();
});
$subMenu_currentRegion->append($item_changeParent);
$subMenu_currentRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_regionFinished = Gtk3::MenuItem->new('Set f_inished region');
$item_regionFinished->signal_connect('activate' => sub {
$self->regionFinishedCallback();
});
$subMenu_currentRegion->append($item_regionFinished);
$subMenu_currentRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_convertRegionExit = Gtk3::MenuItem->new('_Convert all region exits');
$item_convertRegionExit->signal_connect('activate' => sub {
$self->convertRegionExitCallback(TRUE);
});
$subMenu_currentRegion->append($item_convertRegionExit);
my $item_deconvertRegionExit = Gtk3::MenuItem->new(
'_Deconvert all super-region exits',
);
$item_deconvertRegionExit->signal_connect('activate' => sub {
$self->convertRegionExitCallback(FALSE);
});
$subMenu_currentRegion->append($item_deconvertRegionExit);
$subMenu_currentRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetObjectCounts = Gtk3::MenuItem->new('Reset _object counts');
$item_resetObjectCounts->signal_connect('activate' => sub {
# Empty the hashes which store temporary object counts and redraw the region
$self->worldModelObj->resetRegionCounts($self->currentRegionmap);
});
$subMenu_currentRegion->append($item_resetObjectCounts);
my $item_removeRoomFlags = Gtk3::MenuItem->new('Remove room _flags...');
$item_removeRoomFlags->signal_connect('activate' => sub {
$self->removeRoomFlagsCallback();
});
$subMenu_currentRegion->append($item_removeRoomFlags);
my $item_currentRegion = Gtk3::MenuItem->new('C_urrent region');
$item_currentRegion->set_submenu($subMenu_currentRegion);
$column_regions->append($item_currentRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'current_region', $item_currentRegion);
# 'Pre-drawn regions' submenu
my $subMenu_preDrawRegion = Gtk3::Menu->new();
my $item_allowPreDraw = Gtk3::CheckMenuItem->new('_Allow pre-drawing of maps');
$item_allowPreDraw->set_active($self->worldModelObj->preDrawAllowFlag);
$item_allowPreDraw->signal_connect('toggled' => sub {
$self->worldModelObj->toggleFlag(
'preDrawAllowFlag',
$item_allowPreDraw->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_pre_draw',
);
});
$subMenu_preDrawRegion->append($item_allowPreDraw);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_pre_draw', $item_allowPreDraw);
my $item_setPreDrawSize = Gtk3::MenuItem->new('_Set minimum region size');
$item_setPreDrawSize->signal_connect('activate' => sub {
$self->preDrawSizeCallback();
});
$subMenu_preDrawRegion->append($item_setPreDrawSize);
my $item_setRetainSize = Gtk3::MenuItem->new('Set minimum retention size');
$item_setRetainSize->signal_connect('activate' => sub {
$self->preDrawRetainCallback();
});
$subMenu_preDrawRegion->append($item_setRetainSize);
my $item_setPreDrawSpeed = Gtk3::MenuItem->new('Set pre-draw speed');
$item_setPreDrawSpeed->signal_connect('activate' => sub {
$self->preDrawSpeedCallback();
});
$subMenu_preDrawRegion->append($item_setPreDrawSpeed);
$subMenu_preDrawRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_redrawRegion = Gtk3::MenuItem->new('Re_draw this region');
$item_redrawRegion->signal_connect('activate' => sub {
$self->redrawRegions($self->currentRegionmap, TRUE);
});
$subMenu_preDrawRegion->append($item_redrawRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'redraw_region', $item_redrawRegion);
my $item_redrawAllRegions = Gtk3::MenuItem->new('Redraw _all drawn regions');
$item_redrawAllRegions->signal_connect('activate' => sub {
$self->redrawRegionsCallback();
});
$subMenu_preDrawRegion->append($item_redrawAllRegions);
my $item_preDrawRegion = Gtk3::MenuItem->new('_Pre-drawn regions');
$item_preDrawRegion->set_submenu($subMenu_preDrawRegion);
$column_regions->append($item_preDrawRegion);
$column_regions->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Colour schemes' submenu
my $subMenu_regionScheme = Gtk3::Menu->new();
my $item_addScheme = Gtk3::MenuItem->new('_Add new colour scheme...');
$item_addScheme->signal_connect('activate' => sub {
$self->addRegionSchemeCallback();
});
$subMenu_regionScheme->append($item_addScheme);
my $item_editScheme = Gtk3::MenuItem->new('_Edit colour scheme...');
$item_editScheme->signal_connect('activate' => sub {
$self->doRegionSchemeCallback('edit');
});
$subMenu_regionScheme->append($item_editScheme);
my $item_renameScheme = Gtk3::MenuItem->new('_Rename colour scheme...');
$item_renameScheme->signal_connect('activate' => sub {
$self->doRegionSchemeCallback('rename');
});
$subMenu_regionScheme->append($item_renameScheme);
my $item_deleteScheme = Gtk3::MenuItem->new('_Delete colour scheme...');
$item_deleteScheme->signal_connect('activate' => sub {
$self->doRegionSchemeCallback('delete');
});
$subMenu_regionScheme->append($item_deleteScheme);
$subMenu_regionScheme->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'This region' sub-submenu
my $subSubMenu_thisRegionScheme = Gtk3::Menu->new();
my $item_attachScheme = Gtk3::MenuItem->new('_Attach colour scheme...');
$item_attachScheme->signal_connect('activate' => sub {
$self->attachRegionSchemeCallback();
});
$subSubMenu_thisRegionScheme->append($item_attachScheme);
# (Requires $self->currentRegionmap and at least one non-default region colour
# schemes)
$self->ivAdd('menuToolItemHash', 'attach_region_scheme', $item_attachScheme);
my $item_detachScheme = Gtk3::MenuItem->new('_Detach colour scheme');
$item_detachScheme->signal_connect('activate' => sub {
$self->detachRegionSchemeCallback();
});
$subSubMenu_thisRegionScheme->append($item_detachScheme);
# (Requires $self->currentRegionmap with a defined ->regionScheme IV)
$self->ivAdd('menuToolItemHash', 'detach_region_scheme', $item_detachScheme);
$subSubMenu_thisRegionScheme->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editThisScheme = Gtk3::MenuItem->new('_Edit colour scheme...');
$item_editThisScheme->signal_connect('activate' => sub {
$self->doRegionSchemeCallback('edit', $self->currentRegionmap);
});
$subSubMenu_thisRegionScheme->append($item_editThisScheme);
my $item_thisRegionScheme = Gtk3::MenuItem->new('_Current region');
$item_thisRegionScheme->set_submenu($subSubMenu_thisRegionScheme);
$subMenu_regionScheme->append($item_thisRegionScheme);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'this_region_scheme', $item_thisRegionScheme);
my $item_colourScheme = Gtk3::MenuItem->new('Colour sc_hemes');
$item_colourScheme->set_submenu($subMenu_regionScheme);
$column_regions->append($item_colourScheme);
# 'Background colours' submenu
my $subMenu_bgColours = Gtk3::Menu->new();
my $item_removeBGAll = Gtk3::MenuItem->new('_Remove colour...');
$item_removeBGAll->signal_connect('activate' => sub {
$self->removeBGColourCallback();
});
$subMenu_bgColours->append($item_removeBGAll);
my $item_removeBGColour = Gtk3::MenuItem->new('Remove _all colours');
$item_removeBGColour->signal_connect('activate' => sub {
$self->removeBGAllCallback();
});
$subMenu_bgColours->append($item_removeBGColour);
my $item_bgColours = Gtk3::MenuItem->new('_Background colours');
$item_bgColours->set_submenu($subMenu_bgColours);
$column_regions->append($item_bgColours);
# (Requires $self->currentRegionmap whose ->gridColourBlockHash and/or ->gridColourObjHash
# is not empty)
$self->ivAdd('menuToolItemHash', 'empty_bg_colours', $item_bgColours);
$column_regions->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Recalculate paths' submenu
my $subMenu_recalculatePaths = Gtk3::Menu->new();
my $item_recalculateInCurrentRegion = Gtk3::MenuItem->new('In _current region');
$item_recalculateInCurrentRegion->signal_connect('activate' => sub {
$self->recalculatePathsCallback('current');
});
$subMenu_recalculatePaths->append($item_recalculateInCurrentRegion);
# (Requires $self->currentRegionmap and a non-empty
# self->currentRegionmap->gridRoomHash)
$self->ivAdd(
'menuToolItemHash',
'recalculate_in_region',
$item_recalculateInCurrentRegion,
);
my $item_recalculateSelectRegion = Gtk3::MenuItem->new('In _region...');
$item_recalculateSelectRegion->signal_connect('activate' => sub {
$self->recalculatePathsCallback('select');
});
$subMenu_recalculatePaths->append($item_recalculateSelectRegion);
my $item_recalculateAllRegions = Gtk3::MenuItem->new('In _all regions');
$item_recalculateAllRegions->signal_connect('activate' => sub {
$self->recalculatePathsCallback('all');
});
$subMenu_recalculatePaths->append($item_recalculateAllRegions);
$subMenu_recalculatePaths->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_recalculateFromExit = Gtk3::MenuItem->new('For selected _exit');
$item_recalculateFromExit->signal_connect('activate' => sub {
$self->recalculatePathsCallback('exit');
});
$subMenu_recalculatePaths->append($item_recalculateFromExit);
# (Requires $self->currentRegionmap and a $self->selectedExit which is a super-region
# exit)
$self->ivAdd('menuToolItemHash', 'recalculate_from_exit', $item_recalculateFromExit);
my $item_recalculatePaths = Gtk3::MenuItem->new('Re_calculate region paths');
$item_recalculatePaths->set_submenu($subMenu_recalculatePaths);
$column_regions->append($item_recalculatePaths);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'recalculate_paths', $item_recalculatePaths);
# 'Locate current room' submenu
my $subMenu_locateCurrentRoom = Gtk3::Menu->new();
my $item_locateInCurrentRegion = Gtk3::MenuItem->new('In _current region');
$item_locateInCurrentRegion->signal_connect('activate' => sub {
$self->locateCurrentRoomCallback('current');
});
$subMenu_locateCurrentRoom->append($item_locateInCurrentRegion);
# (Requires $self->currentRegionmap and a non-empty GA::Obj::Regionmap->gridRoomHash)
$self->ivAdd('menuToolItemHash', 'locate_room_in_current', $item_locateInCurrentRegion);
my $item_locateInSelectRegion = Gtk3::MenuItem->new('In _region...');
$item_locateInSelectRegion->signal_connect('activate' => sub {
$self->locateCurrentRoomCallback('select');
});
$subMenu_locateCurrentRoom->append($item_locateInSelectRegion);
my $item_locateInAllRegions = Gtk3::MenuItem->new('In _all regions');
$item_locateInAllRegions->signal_connect('activate' => sub {
$self->locateCurrentRoomCallback('all');
});
$subMenu_locateCurrentRoom->append($item_locateInAllRegions);
my $item_locateCurrentRoom = Gtk3::ImageMenuItem->new('L_ocate current room');
my $img_locateCurrentRoom = Gtk3::Image->new_from_stock('gtk-find', 'menu');
$item_locateCurrentRoom->set_image($img_locateCurrentRoom);
$item_locateCurrentRoom->set_submenu($subMenu_locateCurrentRoom);
$column_regions->append($item_locateCurrentRoom);
# 'Screenshots' submenu
my $subMenu_screenshots = Gtk3::Menu->new();
my $item_visibleScreenshot = Gtk3::MenuItem->new('_Visible map');
$item_visibleScreenshot->signal_connect('activate' => sub {
$self->regionScreenshotCallback('visible');
});
$subMenu_screenshots->append($item_visibleScreenshot);
my $item_occupiedScreenshot = Gtk3::MenuItem->new('_Occupied portion');
$item_occupiedScreenshot->signal_connect('activate' => sub {
$self->regionScreenshotCallback('occupied');
});
$subMenu_screenshots->append($item_occupiedScreenshot);
my $item_wholeScreenshot = Gtk3::MenuItem->new('_Whole region');
$item_wholeScreenshot->signal_connect('activate' => sub {
$self->regionScreenshotCallback('whole');
});
$subMenu_screenshots->append($item_wholeScreenshot);
my $item_screenshots = Gtk3::MenuItem->new('Take _screenshot');
$item_screenshots->set_submenu($subMenu_screenshots);
$column_regions->append($item_screenshots);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'screenshots', $item_screenshots);
$column_regions->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_emptyRegion = Gtk3::MenuItem->new('E_mpty region');
$item_emptyRegion->signal_connect('activate' => sub {
$self->emptyRegionCallback();
});
$column_regions->append($item_emptyRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'empty_region', $item_emptyRegion);
my $item_deleteRegion = Gtk3::ImageMenuItem->new('_Delete region');
my $img_deleteRegion = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteRegion->set_image($img_deleteRegion);
$item_deleteRegion->signal_connect('activate' => sub {
$self->deleteRegionCallback();
});
$column_regions->append($item_deleteRegion);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'delete_region', $item_deleteRegion);
my $item_deleteTempRegion = Gtk3::ImageMenuItem->new('Delete temporar_y regions');
my $img_deleteTempRegion = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteTempRegion->set_image($img_deleteTempRegion);
$item_deleteTempRegion->signal_connect('activate' => sub {
$self->deleteTempRegionsCallback();
});
$column_regions->append($item_deleteTempRegion);
# Setup complete
return $column_regions;
}
sub enableRoomsColumn {
# Called by $self->enableMenu
# Sets up the 'Rooms' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableRoomsColumn', @_);
}
# Set up column
my $column_rooms = Gtk3::Menu->new();
if (! $column_rooms) {
return undef;
}
my $item_setCurrentRoom = Gtk3::MenuItem->new('_Set current room');
$item_setCurrentRoom->signal_connect('activate' => sub {
$self->mapObj->setCurrentRoom($self->selectedRoom);
});
$column_rooms->append($item_setCurrentRoom);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'set_current_room', $item_setCurrentRoom);
my $item_unsetCurrentRoom = Gtk3::MenuItem->new('_Unset current room');
$item_unsetCurrentRoom->signal_connect('activate' => sub {
# This function automatically redraws the room
$self->mapObj->setCurrentRoom();
});
$column_rooms->append($item_unsetCurrentRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'unset_current_room', $item_unsetCurrentRoom);
$column_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Locator task' submenu
my $subMenu_locatorTask = Gtk3::Menu->new();
my $item_resetLocator = Gtk3::MenuItem->new('_Reset Locator');
$item_resetLocator->signal_connect('activate' => sub {
$self->resetLocatorCallback();
});
$subMenu_locatorTask->append($item_resetLocator);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'reset_locator', $item_resetLocator);
my $item_updateLocator = Gtk3::MenuItem->new('_Update Locator');
$item_updateLocator->signal_connect('activate' => sub {
# Update the Locator task
$self->mapObj->updateLocator();
});
$subMenu_locatorTask->append($item_updateLocator);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'update_locator', $item_updateLocator);
$subMenu_locatorTask->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setFacing = Gtk3::MenuItem->new('_Set facing direction...');
$item_setFacing->signal_connect('activate' => sub {
$self->setFacingCallback();
});
$subMenu_locatorTask->append($item_setFacing);
my $item_resetFacing = Gtk3::MenuItem->new('R_eset facing direction...');
$item_resetFacing->signal_connect('activate' => sub {
$self->resetFacingCallback();
});
$subMenu_locatorTask->append($item_resetFacing);
$subMenu_locatorTask->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_viewLocatorRoom = Gtk3::MenuItem->new('_View Locator room...');
$item_viewLocatorRoom->signal_connect('activate' => sub {
$self->editLocatorRoomCallback();
});
$subMenu_locatorTask->append($item_viewLocatorRoom);
my $item_locatorTask = Gtk3::MenuItem->new('_Locator task');
$item_locatorTask->set_submenu($subMenu_locatorTask);
$column_rooms->append($item_locatorTask);
# 'Pathfinding' submenu
my $subMenu_pathFinding = Gtk3::Menu->new();
my $item_highlightPath = Gtk3::MenuItem->new('_Highlight path');
$item_highlightPath->signal_connect('activate' => sub {
$self->processPathCallback('select_room');
});
$subMenu_pathFinding->append($item_highlightPath);
# (Requires $self->currentRegionmap, $self->mapObj->currentRoom and $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'path_finding_highlight', $item_highlightPath);
my $item_displayPath = Gtk3::MenuItem->new('_Edit path...');
$item_displayPath->signal_connect('activate' => sub {
$self->processPathCallback('pref_win');
});
$subMenu_pathFinding->append($item_displayPath);
# (Requires $self->currentRegionmap, $self->mapObj->currentRoom and $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'path_finding_edit', $item_displayPath);
my $item_goToRoom = Gtk3::MenuItem->new('_Go to room');
$item_goToRoom->signal_connect('activate' => sub {
$self->processPathCallback('send_char');
});
$subMenu_pathFinding->append($item_goToRoom);
# (Requires $self->currentRegionmap, $self->mapObj->currentRoom and $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'path_finding_go', $item_goToRoom);
$subMenu_pathFinding->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_allowPostProcessing = Gtk3::CheckMenuItem->new('_Allow post-processing');
$item_allowPostProcessing->set_active($self->worldModelObj->postProcessingFlag);
$item_allowPostProcessing->signal_connect('toggled' => sub {
$self->worldModelObj->toggleFlag(
'postProcessingFlag',
$item_allowPostProcessing->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_post_process',
);
});
$subMenu_pathFinding->append($item_allowPostProcessing);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_post_process', $item_allowPostProcessing);
my $item_avoidHazardousRooms = Gtk3::CheckMenuItem->new('A_void hazardous rooms');
$item_avoidHazardousRooms->set_active($self->worldModelObj->avoidHazardsFlag);
$item_avoidHazardousRooms->signal_connect('toggled' => sub {
$self->worldModelObj->toggleFlag(
'avoidHazardsFlag',
$item_avoidHazardousRooms->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_hazard_rooms',
);
});
$subMenu_pathFinding->append($item_avoidHazardousRooms);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_hazard_rooms', $item_avoidHazardousRooms);
my $item_doubleClickPathFind = Gtk3::CheckMenuItem->new(
'Allow _double-click moves',
);
$item_doubleClickPathFind->set_active($self->worldModelObj->quickPathFindFlag);
$item_doubleClickPathFind->signal_connect('toggled' => sub {
$self->worldModelObj->toggleFlag(
'quickPathFindFlag',
$item_doubleClickPathFind->get_active(),
FALSE, # Don't call $self->redrawRegions
'allow_quick_path_find',
);
});
$subMenu_pathFinding->append($item_doubleClickPathFind);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'allow_quick_path_find', $item_doubleClickPathFind);
$subMenu_pathFinding->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_adjacentMode = Gtk3::MenuItem->new('_Set adjacent regions mode...');
$item_adjacentMode->signal_connect('activate' => sub {
$self->adjacentModeCallback();
});
$subMenu_pathFinding->append($item_adjacentMode);
my $item_pathFinding = Gtk3::MenuItem->new('_Pathfinding');
$item_pathFinding->set_submenu($subMenu_pathFinding);
$column_rooms->append($item_pathFinding);
# 'Move rooms/labels' submenu
my $subMenu_moveRooms = Gtk3::Menu->new();
my $item_moveSelected = Gtk3::MenuItem->new('Move in _direction...');
$item_moveSelected->signal_connect('activate' => sub {
$self->moveSelectedRoomsCallback();
});
$subMenu_moveRooms->append($item_moveSelected);
# (Requires $self->currentRegionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'move_rooms_dir', $item_moveSelected);
my $item_moveSelectedToClick = Gtk3::MenuItem->new('Move to _click');
$item_moveSelectedToClick->signal_connect('activate' => sub {
# Set the free clicking mode: $self->mouseClickEvent will move the objects when the
# user next clicks on an empty part of the map
$self->set_freeClickMode('move_room');
});
$subMenu_moveRooms->append($item_moveSelectedToClick);
# (Requires $self->currentRegionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'move_rooms_click', $item_moveSelectedToClick);
$subMenu_moveRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Transfer to region' sub-submenu
my $subSubMenu_transferRegion = Gtk3::Menu->new();
if ($self->recentRegionList) {
foreach my $name ($self->recentRegionList) {
my $item_regionName = Gtk3::MenuItem->new($name);
$item_regionName->signal_connect('activate' => sub {
$self->transferSelectedRoomsCallback($name);
});
$subSubMenu_transferRegion->append($item_regionName);
}
} else {
my $item_regionNone = Gtk3::MenuItem->new('(No recent regions)');
$item_regionNone->set_sensitive(FALSE);
$subSubMenu_transferRegion->append($item_regionNone);
}
$subSubMenu_transferRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_transferSelect = Gtk3::MenuItem->new('Select region...');
$item_transferSelect->signal_connect('activate' => sub {
$self->transferSelectedRoomsCallback();
});
$subSubMenu_transferRegion->append($item_transferSelect);
my $item_transferRegion = Gtk3::MenuItem->new('_Transfer to region');
$item_transferRegion->set_submenu($subSubMenu_transferRegion);
$subMenu_moveRooms->append($item_transferRegion);
# (Requires $self->currentRegionmap, one or more selected rooms and at least two regions
# in the world model)
$self->ivAdd('menuToolItemHash', 'transfer_to_region', $item_transferRegion);
$subMenu_moveRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_mergeMoveRooms = Gtk3::MenuItem->new('_Merge/move rooms');
$item_mergeMoveRooms->signal_connect('activate' => sub {
$self->doMerge($self->mapObj->currentRoom);
});
$subMenu_moveRooms->append($item_mergeMoveRooms);
# (Requires $self->currentRegionmap, a current room and the automapper object being set
# up to perform a merge)
$self->ivAdd('menuToolItemHash', 'move_merge_rooms', $item_mergeMoveRooms);
my $item_moveRooms = Gtk3::MenuItem->new('_Move rooms/labels');
$item_moveRooms->set_submenu($subMenu_moveRooms);
$column_rooms->append($item_moveRooms);
# (Requires $self->currentRegionmap and EITHER one or more selected rooms OR a current room
# and the automapper being set up to perform a merge)
$self->ivAdd('menuToolItemHash', 'move_rooms_labels', $item_moveRooms);
$column_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Add room' submenu
my $subMenu_addRoom = Gtk3::Menu->new();
my $item_addFirstRoom = Gtk3::MenuItem->new('Add _first room');
$item_addFirstRoom->signal_connect('activate' => sub {
$self->addFirstRoomCallback();
});
$subMenu_addRoom->append($item_addFirstRoom);
# (Requires $self->currentRegionmap & an empty $self->currentRegionmap->gridRoomHash)
$self->ivAdd('menuToolItemHash', 'add_first_room', $item_addFirstRoom);
my $item_addRoomAtClick = Gtk3::MenuItem->new('Add room at _click');
$item_addRoomAtClick->signal_connect('activate' => sub {
# Set the free clicking mode: $self->mouseClickEvent will create the new room when
# the user next clicks on an empty part of the map
if ($self->currentRegionmap) {
$self->set_freeClickMode('add_room');
}
});
$subMenu_addRoom->append($item_addRoomAtClick);
my $item_addRoomAtBlock = Gtk3::MenuItem->new('Add room at _block...');
$item_addRoomAtBlock->signal_connect('activate' => sub {
$self->addRoomAtBlockCallback();
});
$subMenu_addRoom->append($item_addRoomAtBlock);
my $item_addRoom = Gtk3::ImageMenuItem->new('Add _room');
my $img_addRoom = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addRoom->set_image($img_addRoom);
$item_addRoom->set_submenu($subMenu_addRoom);
$column_rooms->append($item_addRoom);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'add_room', $item_addRoom);
# 'Add pattern' submenu
my $subMenu_exitPatterns = Gtk3::Menu->new();
my $item_addFailedExitWorld = Gtk3::MenuItem->new('Add failed exit to _world...');
$item_addFailedExitWorld->signal_connect('activate' => sub {
$self->addFailedExitCallback(TRUE);
});
$subMenu_exitPatterns->append($item_addFailedExitWorld);
my $item_addFailedExitRoom = Gtk3::MenuItem->new('Add failed exit to current _room...');
$item_addFailedExitRoom->signal_connect('activate' => sub {
$self->addFailedExitCallback(FALSE, $self->mapObj->currentRoom);
});
$subMenu_exitPatterns->append($item_addFailedExitRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'add_failed_room', $item_addFailedExitRoom);
$subMenu_exitPatterns->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addInvoluntaryExitRoom = Gtk3::MenuItem->new(
'Add _involuntary exit to current room...',
);
$item_addInvoluntaryExitRoom->signal_connect('activate' => sub {
$self->addInvoluntaryExitCallback($self->mapObj->currentRoom);
});
$subMenu_exitPatterns->append($item_addInvoluntaryExitRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'add_involuntary_exit', $item_addInvoluntaryExitRoom);
my $item_addRepulseExitRoom = Gtk3::MenuItem->new(
'Add r_epulse exit to current room...',
);
$item_addRepulseExitRoom->signal_connect('activate' => sub {
$self->addRepulseExitCallback($self->mapObj->currentRoom);
});
$subMenu_exitPatterns->append($item_addRepulseExitRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'add_repulse_exit', $item_addRepulseExitRoom);
$subMenu_exitPatterns->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addSpecialDepartRoom = Gtk3::MenuItem->new(
'Add _special departure to current room...',
);
$item_addSpecialDepartRoom->signal_connect('activate' => sub {
$self->addSpecialDepartureCallback($self->mapObj->currentRoom);
});
$subMenu_exitPatterns->append($item_addSpecialDepartRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'add_special_depart', $item_addSpecialDepartRoom);
my $item_addUnspecifiedRoom = Gtk3::MenuItem->new(
'Add _unspecified room pattern...',
);
$item_addUnspecifiedRoom->signal_connect('activate' => sub {
$self->addUnspecifiedPatternCallback($self->mapObj->currentRoom);
});
$subMenu_exitPatterns->append($item_addUnspecifiedRoom);
# (Requires $self->currentRegionmap & $self->mapObj->currentRoom)
$self->ivAdd('menuToolItemHash', 'add_unspecified_pattern', $item_addUnspecifiedRoom);
my $item_exitPatterns = Gtk3::MenuItem->new('Add p_attern');
$item_exitPatterns->set_submenu($subMenu_exitPatterns);
$column_rooms->append($item_exitPatterns);
# 'Add to model' submenu
my $subMenu_addToModel = Gtk3::Menu->new();
my $item_addRoomContents = Gtk3::MenuItem->new('Add _contents...');
$item_addRoomContents->signal_connect('activate' => sub {
$self->addContentsCallback(FALSE);
});
$subMenu_addToModel->append($item_addRoomContents);
# Requires $self->currentRegionmap, $self->mapObj->currentRoom
$self->ivAdd('menuToolItemHash', 'add_room_contents', $item_addRoomContents);
my $item_addContentsString = Gtk3::MenuItem->new('Add c_ontents from string...');
$item_addContentsString->signal_connect('activate' => sub {
$self->addContentsCallback(TRUE);
});
$subMenu_addToModel->append($item_addContentsString);
# Requires $self->currentRegionmap, $self->selectedRoom
$self->ivAdd('menuToolItemHash', 'add_contents_string', $item_addContentsString);
$subMenu_addToModel->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addHiddenObj = Gtk3::MenuItem->new('Add _hidden object...');
$item_addHiddenObj->signal_connect('activate' => sub {
$self->addHiddenObjCallback(FALSE);
});
$subMenu_addToModel->append($item_addHiddenObj);
# Requires $self->currentRegionmap, $self->mapObj->currentRoom
$self->ivAdd('menuToolItemHash', 'add_hidden_object', $item_addHiddenObj);
my $item_addHiddenString = Gtk3::MenuItem->new('Add h_idden object from string...');
$item_addHiddenString->signal_connect('activate' => sub {
$self->addHiddenObjCallback(TRUE);
});
$subMenu_addToModel->append($item_addHiddenString);
# Requires $self->currentRegionmap, $self->selectedRoom
$self->ivAdd('menuToolItemHash', 'add_hidden_string', $item_addHiddenString);
$subMenu_addToModel->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addSearchResult = Gtk3::MenuItem->new('Add _search result...');
$item_addSearchResult->signal_connect('activate' => sub {
$self->addSearchResultCallback();
});
$subMenu_addToModel->append($item_addSearchResult);
# Requires $self->currentRegionmap and $self->mapObj->currentRoom
$self->ivAdd('menuToolItemHash', 'add_search_result', $item_addSearchResult);
my $item_addToModel = Gtk3::MenuItem->new('Add to m_odel');
$item_addToModel->set_submenu($subMenu_addToModel);
$column_rooms->append($item_addToModel);
# Requires $self->currentRegionmap and either $self->mapObj->currentRoom or
# $self->selectedRoom
$self->ivAdd('menuToolItemHash', 'add_to_model', $item_addToModel);
$column_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Add/set exits' submenu
my $subMenu_setExits = Gtk3::Menu->new();
my $item_addNormal = Gtk3::MenuItem->new('Add _normal exit...');
$item_addNormal->signal_connect('activate' => sub {
$self->addExitCallback(FALSE); # FALSE - not a hidden exit
});
$subMenu_setExits->append($item_addNormal);
# (Requires $self->currentRegionmap and a $self->selectedRoom whose ->wildMode is not
# 'wild' - the value 'border' is ok, though)
$self->ivAdd('menuToolItemHash', 'add_normal_exit', $item_addNormal);
my $item_addHiddenExit = Gtk3::MenuItem->new('Add _hidden exit...');
$item_addHiddenExit->signal_connect('activate' => sub {
$self->addExitCallback(TRUE); # TRUE - a hidden exit
});
$subMenu_setExits->append($item_addHiddenExit);
# (Requires $self->currentRegionmap and a $self->selectedRoom whose ->wildMode is not
# 'wild' - the value 'border' is ok, though)
$self->ivAdd('menuToolItemHash', 'add_hidden_exit', $item_addHiddenExit);
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addMultiple = Gtk3::MenuItem->new('Add _multiple exits...');
$item_addMultiple->signal_connect('activate' => sub {
$self->addMultipleExitsCallback();
});
$subMenu_setExits->append($item_addMultiple);
# (Requires $self->currentRegionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'add_multiple_exits', $item_addMultiple);
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_removeChecked = Gtk3::MenuItem->new('Remove _checked direction...');
$item_removeChecked->signal_connect('activate' => sub {
$self->removeCheckedDirCallback(FALSE);
});
$subMenu_setExits->append($item_removeChecked);
# (Require a current regionmap, a single selected room that has one or more checked
# directions)
$self->ivAdd('menuToolItemHash', 'remove_checked', $item_removeChecked);
my $item_removeCheckedAll = Gtk3::MenuItem->new('Remove _all checked directions');
$item_removeCheckedAll->signal_connect('activate' => sub {
$self->removeCheckedDirCallback(TRUE);
});
$subMenu_setExits->append($item_removeCheckedAll);
# (Require a current regionmap, a single selected room that has one or more checked
# directions)
$self->ivAdd('menuToolItemHash', 'remove_checked_all', $item_removeCheckedAll);
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_markNormal = Gtk3::MenuItem->new('Mark room(s) as n_ormal');
$item_markNormal->signal_connect('activate' => sub {
$self->setWildCallback('normal');
});
$subMenu_setExits->append($item_markNormal);
# (Require a current regionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'wilderness_normal', $item_markNormal);
my $item_markWild = Gtk3::MenuItem->new('Mark room(s) as _wilderness');
$item_markWild->signal_connect('activate' => sub {
$self->setWildCallback('wild');
});
$subMenu_setExits->append($item_markWild);
# (Require a current regionmap, one or more selected rooms and
# $self->session->currentWorld->basicMappingFlag to be FALSE)
$self->ivAdd('menuToolItemHash', 'wilderness_wild', $item_markWild);
my $item_markBorder = Gtk3::MenuItem->new('Mark room(s) as wilderness _border');
$item_markBorder->signal_connect('activate' => sub {
$self->setWildCallback('border');
});
$subMenu_setExits->append($item_markBorder);
# (Require a current regionmap, one or more selected rooms and
# $self->session->currentWorld->basicMappingFlag to be FALSE)
$self->ivAdd('menuToolItemHash', 'wilderness_border', $item_markBorder);
my $item_setExits = Gtk3::ImageMenuItem->new('Add/set _exits');
my $img_setExits = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_setExits->set_image($img_setExits);
$item_setExits->set_submenu($subMenu_setExits);
$column_rooms->append($item_setExits);
# (Require a current regionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'set_exits', $item_setExits);
my $item_selectExit = Gtk3::MenuItem->new('Select e_xit in room...');
$item_selectExit->signal_connect('activate' => sub {
$self->selectExitCallback();
});
$column_rooms->append($item_selectExit);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'select_exit', $item_selectExit);
$column_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editRoom = Gtk3::ImageMenuItem->new('Ed_it room...');
my $img_editRoom = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editRoom->set_image($img_editRoom);
$item_editRoom->signal_connect('activate' => sub {
# Open the room's 'edit' window
$self->createFreeWin(
'Games::Axmud::EditWin::ModelObj::Room',
$self,
$self->session,
'Edit ' . $self->selectedRoom->category . ' model object',
$self->selectedRoom,
FALSE, # Not temporary
);
});
$column_rooms->append($item_editRoom);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'edit_room', $item_editRoom);
# 'Room text' submenu
my $subMenu_roomText = Gtk3::Menu->new();
my $item_setRoomTag = Gtk3::MenuItem->new('Set room _tag...');
$item_setRoomTag->signal_connect('activate' => sub {
$self->setRoomTagCallback();
});
$subMenu_roomText->append($item_setRoomTag);
# (Requires $self->currentRegionmap and either $self->selectedRoom or
# $self->selectedRoomTag)
$self->ivAdd('menuToolItemHash', 'set_room_tag', $item_setRoomTag);
my $item_setGuild = Gtk3::MenuItem->new('Set room _guild...');
$item_setGuild->signal_connect('activate' => sub {
$self->setRoomGuildCallback();
});
$subMenu_roomText->append($item_setGuild);
# (Requires $self->currentRegionmap and one or more of $self->selectedRoom,
# $self->selectedRoomHash, $self->selectedRoomGuild, $self->selectedRoomGuildHash)
$self->ivAdd('menuToolItemHash', 'set_room_guild', $item_setGuild);
$subMenu_roomText->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPositions = Gtk3::MenuItem->new('_Reset text positions');
$item_resetPositions->signal_connect('activate' => sub {
$self->resetRoomOffsetsCallback();
});
$subMenu_roomText->append($item_resetPositions);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'reset_positions', $item_resetPositions);
$subMenu_roomText->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_roomText = Gtk3::MenuItem->new('Set room _text');
$item_roomText->set_submenu($subMenu_roomText);
$column_rooms->append($item_roomText);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'room_text', $item_roomText);
# 'Toggle room flag' submenu
my $subMenu_toggleRoomFlag = Gtk3::Menu->new();
if ($self->worldModelObj->roomFlagShowMode eq 'default') {
# Show all room flags, sorted by filter
foreach my $filter ($axmud::CLIENT->constRoomFilterList) {
# A sub-sub menu for $filter
my $subSubMenu_filter = Gtk3::Menu->new();
my @nameList = $self->worldModelObj->getRoomFlagsInFilter($filter);
foreach my $name (@nameList) {
my $obj = $self->worldModelObj->ivShow('roomFlagHash', $name);
if ($obj) {
my $menuItem = Gtk3::MenuItem->new($obj->descrip);
$menuItem->signal_connect('activate' => sub {
# Toggle the flags for all selected rooms, redraw them and (if the
# flag is one of the hazardous room flags) recalculate the
# regionmap's paths. The TRUE argument tells the world model to
# redraw the rooms
$self->worldModelObj->toggleRoomFlags(
$self->session,
TRUE,
$obj->name,
$self->compileSelectedRooms(),
);
});
$subSubMenu_filter->append($menuItem);
}
}
if (! @nameList) {
my $menuItem = Gtk3::MenuItem->new('(No flags in this filter)');
$menuItem->set_sensitive(FALSE);
$subSubMenu_filter->append($menuItem);
}
my $menuItem = Gtk3::MenuItem->new(ucfirst($filter));
$menuItem->set_submenu($subSubMenu_filter);
$subMenu_toggleRoomFlag->append($menuItem);
}
} else {
# Show selected room flags, sorted only by priority
my %showHash = $self->worldModelObj->getVisibleRoomFlags();
if (%showHash) {
foreach my $obj (sort {$a->priority <=> $b->priority} (values %showHash)) {
my $menuItem = Gtk3::MenuItem->new($obj->descrip);
$menuItem->signal_connect('activate' => sub {
# Toggle the flags for all selected rooms, redraw them and (if the
# flag is one of the hazardous room flags) recalculate the
# regionmap's paths. The TRUE argument tells the world model to
# redraw the rooms
$self->worldModelObj->toggleRoomFlags(
$self->session,
TRUE,
$obj->name,
$self->compileSelectedRooms(),
);
});
$subMenu_toggleRoomFlag->append($menuItem);
}
} else {
my $menuItem = Gtk3::MenuItem->new('(None are marked visible)');
$menuItem->set_sensitive(FALSE);
$subMenu_toggleRoomFlag->append($menuItem);
}
}
my $item_toggleRoomFlag = Gtk3::MenuItem->new('Toggle room _flags');
$item_toggleRoomFlag->set_submenu($subMenu_toggleRoomFlag);
$column_rooms->append($item_toggleRoomFlag);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'toggle_room_flag_sub', $item_toggleRoomFlag);
# 'Other room features' submenu
my $subMenu_roomFeatures = Gtk3::Menu->new();
# 'Update character visits' sub-submenu
my $subSubMenu_updateVisits = Gtk3::Menu->new();
my $item_increaseSetCurrent = Gtk3::MenuItem->new('Increase & set _current');
$item_increaseSetCurrent->signal_connect('activate' => sub {
$self->updateVisitsCallback('increase');
$self->mapObj->setCurrentRoom($self->selectedRoom);
});
$subSubMenu_updateVisits->append($item_increaseSetCurrent);
# (Requires $self->currentRegionmap and $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'increase_set_current', $item_increaseSetCurrent);
$subSubMenu_updateVisits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_increaseVisits = Gtk3::MenuItem->new('_Increase by one');
$item_increaseVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('increase');
});
$subSubMenu_updateVisits->append($item_increaseVisits);
my $item_decreaseVisits = Gtk3::MenuItem->new('_Decrease by one');
$item_decreaseVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('decrease');
});
$subSubMenu_updateVisits->append($item_decreaseVisits);
my $item_manualVisits = Gtk3::MenuItem->new('Set _manually');
$item_manualVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('manual');
});
$subSubMenu_updateVisits->append($item_manualVisits);
my $item_resetVisits = Gtk3::MenuItem->new('_Reset to zero');
$item_resetVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('reset');
});
$subSubMenu_updateVisits->append($item_resetVisits);
$subSubMenu_updateVisits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_toggleGraffiti = Gtk3::MenuItem->new('Toggle _graffiti');
$item_toggleGraffiti->signal_connect('activate' => sub {
$self->toggleGraffitiCallback();
});
$subSubMenu_updateVisits->append($item_toggleGraffiti);
# (Requires $self->currentRegionmap, $self->graffitiModeFlag & one or more selected
# rooms)
$self->ivAdd('menuToolItemHash', 'toggle_graffiti', $item_toggleGraffiti);
my $item_updateVisits = Gtk3::MenuItem->new('Update character _visits');
$item_updateVisits->set_submenu($subSubMenu_updateVisits);
$subMenu_roomFeatures->append($item_updateVisits);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'update_visits', $item_updateVisits);
# 'Room exclusivity' sub-submenu
my $subSubMenu_exclusivity = Gtk3::Menu->new();
my $item_toggleExclusivity = Gtk3::MenuItem->new('_Toggle exclusivity');
$item_toggleExclusivity->signal_connect('activate' => sub {
$self->toggleExclusiveProfileCallback();
});
$subSubMenu_exclusivity->append($item_toggleExclusivity);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'toggle_exclusivity', $item_toggleExclusivity);
$subSubMenu_exclusivity->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addExclusiveProf = Gtk3::MenuItem->new('_Add exclusive profile...');
$item_addExclusiveProf->signal_connect('activate' => sub {
$self->addExclusiveProfileCallback();
});
$subSubMenu_exclusivity->append($item_addExclusiveProf);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'add_exclusive_prof', $item_addExclusiveProf);
my $item_clearExclusiveProf = Gtk3::MenuItem->new('_Clear exclusive profiles');
$item_clearExclusiveProf->signal_connect('activate' => sub {
$self->resetExclusiveProfileCallback();
});
$subSubMenu_exclusivity->append($item_clearExclusiveProf);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'clear_exclusive_profs', $item_clearExclusiveProf);
my $item_exclusivity = Gtk3::MenuItem->new('Room _exclusivity');
$item_exclusivity->set_submenu($subSubMenu_exclusivity);
$subMenu_roomFeatures->append($item_exclusivity);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'room_exclusivity', $item_exclusivity);
# 'Source code' sub-submenu
my $subSubMenu_sourceCode = Gtk3::Menu->new();
my $item_setFilePath = Gtk3::MenuItem->new('_Set file path...');
$item_setFilePath->signal_connect('activate' => sub {
$self->setFilePathCallback();
});
$subSubMenu_sourceCode->append($item_setFilePath);
# (Requires $self->currentRegionmap and $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'set_file_path', $item_setFilePath);
my $item_setVirtualArea = Gtk3::MenuItem->new('Set virtual _area...');
$item_setVirtualArea->signal_connect('activate' => sub {
$self->setVirtualAreaCallback(TRUE);
});
$subSubMenu_sourceCode->append($item_setVirtualArea);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'set_virtual_area', $item_setVirtualArea);
my $item_resetVirtualArea = Gtk3::MenuItem->new('_Reset virtual area...');
$item_resetVirtualArea->signal_connect('activate' => sub {
$self->setVirtualAreaCallback(FALSE);
});
$subSubMenu_sourceCode->append($item_resetVirtualArea);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'reset_virtual_area', $item_resetVirtualArea);
my $item_showSourceCode = Gtk3::MenuItem->new('S_how file paths');
$item_showSourceCode->signal_connect('activate' => sub {
# (Don't use $self->pseudoCmdMode - we want to see the footer messages)
$self->session->pseudoCmd('listsourcecode', 'show_all');
});
$subSubMenu_sourceCode->append($item_showSourceCode);
$subSubMenu_sourceCode->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_viewSourceCode = Gtk3::MenuItem->new('_View file...');
$item_viewSourceCode->signal_connect('activate' => sub {
$self->quickFreeWin(
'Games::Axmud::OtherWin::SourceCode',
$self->session,
# Config
'model_obj' => $self->selectedRoom,
);
});
$subSubMenu_sourceCode->append($item_viewSourceCode);
# (Requires $self->currentRegionmap, $self->selectedRoom &
# $self->selectedRoom->sourceCodePath & empty
# $self->selectedRoom->virtualAreaPath)
$self->ivAdd('menuToolItemHash', 'view_source_code', $item_viewSourceCode);
my $item_editSourceCode = Gtk3::MenuItem->new('_Edit file...');
$item_editSourceCode->signal_connect('activate' => sub {
$self->editFileCallback();
});
$subSubMenu_sourceCode->append($item_editSourceCode);
# (Requires $self->currentRegionmap, $self->selectedRoom &
# $self->selectedRoom->sourceCodePath & empty
# $self->selectedRoom->virtualAreaPath)
$self->ivAdd('menuToolItemHash', 'edit_source_code', $item_editSourceCode);
$subSubMenu_sourceCode->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_viewVirtualArea = Gtk3::MenuItem->new('View virtual area _file...');
$item_viewVirtualArea->signal_connect('activate' => sub {
$self->quickFreeWin(
'Games::Axmud::OtherWin::SourceCode',
$self->session,
# Config
'model_obj' => $self->selectedRoom,
'virtual_flag' => TRUE,
);
});
$subSubMenu_sourceCode->append($item_viewVirtualArea);
# (Requires $self->currentRegionmap, $self->selectedRoom &
# $self->selectedRoom->virtualAreaPath
$self->ivAdd('menuToolItemHash', 'view_virtual_area', $item_viewVirtualArea);
my $item_editVirtualArea = Gtk3::MenuItem->new('E_dit virtual area file...');
$item_editVirtualArea->signal_connect('activate' => sub {
# Use TRUE to specify that the virtual area file should be opened
$self->editFileCallback(TRUE);
});
$subSubMenu_sourceCode->append($item_editVirtualArea);
# (Requires $self->currentRegionmap, $self->selectedRoom &
# $self->selectedRoom->virtualAreaPath
$self->ivAdd('menuToolItemHash', 'edit_virtual_area', $item_editVirtualArea);
my $item_sourceCode = Gtk3::MenuItem->new('Source _code');
$item_sourceCode->set_submenu($subSubMenu_sourceCode);
$subMenu_roomFeatures->append($item_sourceCode);
$subMenu_roomFeatures->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setInteriorOffsets = Gtk3::MenuItem->new('_Synchronise grid coordinates...');
$item_setInteriorOffsets->signal_connect('activate' => sub {
$self->setInteriorOffsetsCallback();
});
$subMenu_roomFeatures->append($item_setInteriorOffsets);
my $item_resetInteriorOffsets = Gtk3::MenuItem->new('_Reset grid coordinates');
$item_resetInteriorOffsets->signal_connect('activate' => sub {
$self->resetInteriorOffsetsCallback();
});
$subMenu_roomFeatures->append($item_resetInteriorOffsets);
my $item_roomFeatures = Gtk3::MenuItem->new('Ot_her room features');
$item_roomFeatures->set_submenu($subMenu_roomFeatures);
$column_rooms->append($item_roomFeatures);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'other_room_features', $item_roomFeatures);
$column_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteRoom = Gtk3::ImageMenuItem->new('_Delete rooms');
my $img_deleteRoom = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteRoom->set_image($img_deleteRoom);
$item_deleteRoom->signal_connect('activate' => sub {
$self->deleteRoomsCallback();
});
$column_rooms->append($item_deleteRoom);
# (Requires $self->currentRegionmap & either $self->selectedRoom or
# $self->selectedRoomHash)
$self->ivAdd('menuToolItemHash', 'delete_room', $item_deleteRoom);
# Setup complete
return $column_rooms;
}
sub enableExitsColumn {
# Called by $self->enableMenu
# Sets up the 'Exits' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Local variables
my @titleList;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableExitsColumn', @_);
}
# Set up column
my $column_exits = Gtk3::Menu->new();
if (! $column_exits) {
return undef;
}
# 'Set direction' submenu
my $subMenu_setDir = Gtk3::Menu->new();
my $item_changeDir = Gtk3::MenuItem->new('_Change direction...');
$item_changeDir->signal_connect('activate' => sub {
$self->changeDirCallback();
});
$subMenu_setDir->append($item_changeDir);
# (Requires $self->currentRegionmap and $self->selectedExit and
# $self->selectedExit->drawMode is 'primary' or 'perm_alloc')
$self->ivAdd('menuToolItemHash', 'change_direction', $item_changeDir);
my $item_altDir = Gtk3::MenuItem->new('Set _alternative direction(s)...');
$item_altDir->signal_connect('activate' => sub {
$self->setAltDirCallback();
});
$subMenu_setDir->append($item_altDir);
my $item_setDir = Gtk3::MenuItem->new('Set di_rection');
$item_setDir->set_submenu($subMenu_setDir);
$column_exits->append($item_setDir);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_exit_dir', $item_setDir);
my $item_setAssisted = Gtk3::MenuItem->new('Set assisted _move...');
$item_setAssisted->signal_connect('activate' => sub {
$self->setAssistedMoveCallback();
});
$column_exits->append($item_setAssisted);
# (Requires $self->currentRegionmap and $self->selectedExit and
# $self->selectedExit->drawMode is 'primary', 'temp_unalloc' or 'perm_alloc')
$self->ivAdd('menuToolItemHash', 'set_assisted_move', $item_setAssisted);
# 'Allocate map direction' submenu
my $subMenu_allocateMapDir = Gtk3::Menu->new();
my $item_allocatePrimary = Gtk3::MenuItem->new('Choose _direction...');
$item_allocatePrimary->signal_connect('activate' => sub {
$self->allocateMapDirCallback();
});
$subMenu_allocateMapDir->append($item_allocatePrimary);
my $item_confirmTwoWay = Gtk3::MenuItem->new('Confirm _two-way exit...');
$item_confirmTwoWay->signal_connect('activate' => sub {
$self->confirmTwoWayCallback();
});
$subMenu_allocateMapDir->append($item_confirmTwoWay);
my $item_allocateMapDir = Gtk3::MenuItem->new('_Allocate map direction');
$item_allocateMapDir->set_submenu($subMenu_allocateMapDir);
$column_exits->append($item_allocateMapDir);
# (Requires $self->currentRegionmap and $self->selectedExit and
# $self->selectedExit->drawMode is 'temp_alloc' or 'temp_unalloc')
$self->ivAdd('menuToolItemHash', 'allocate_map_dir', $item_allocateMapDir);
my $item_allocateShadow = Gtk3::MenuItem->new('Allocate _shadow...');
$item_allocateShadow->signal_connect('activate' => sub {
$self->allocateShadowCallback();
});
$column_exits->append($item_allocateShadow);
# (Requires $self->currentRegionmap and $self->selectedExit and
# $self->selectedExit->drawMode is 'temp_alloc' or 'temp_unalloc')
$self->ivAdd('menuToolItemHash', 'allocate_shadow', $item_allocateShadow);
$column_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_connectExitToClick = Gtk3::MenuItem->new('_Connect to click');
$item_connectExitToClick->signal_connect('activate' => sub {
$self->connectToClickCallback();
});
$column_exits->append($item_connectExitToClick);
# (Requires $self->currentRegionmap, $self->selectedExit and
# $self->selectedExit->drawMode 'primary', 'temp_unalloc' or 'perm_alloc')
$self->ivAdd('menuToolItemHash', 'connect_to_click', $item_connectExitToClick);
my $item_disconnectExit = Gtk3::MenuItem->new('D_isconnect exit');
$item_disconnectExit->signal_connect('activate' => sub {
$self->disconnectExitCallback();
});
$column_exits->append($item_disconnectExit);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'disconnect_exit', $item_disconnectExit);
$column_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Set ornaments' submenu
my $subMenu_setOrnament = Gtk3::Menu->new();
# Create a list of exit ornament types, in groups of two, in the form
# (menu_item_title, exit_ornament_type)
@titleList = (
'_No ornament', 'none',
'_Openable exit', 'open',
'_Lockable exit', 'lock',
'_Pickable exit', 'pick',
'_Breakable exit', 'break',
'_Impassable exit', 'impass',
'_Mystery exit', 'mystery',
);
do {
my ($title, $type);
$title = shift @titleList;
$type = shift @titleList;
my $menuItem = Gtk3::MenuItem->new($title);
$menuItem->signal_connect('activate' => sub {
$self->exitOrnamentCallback($type);
});
$subMenu_setOrnament->append($menuItem);
} until (! @titleList);
$subMenu_setOrnament->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setTwinOrnament = Gtk3::CheckMenuItem->new('Also set _twin exits');
$item_setTwinOrnament->set_active($self->worldModelObj->setTwinOrnamentFlag);
$item_setTwinOrnament->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'setTwinOrnamentFlag',
$item_setTwinOrnament->get_active(),
FALSE, # Don't call $self->redrawRegions
'also_set_twin_exits',
);
}
});
$subMenu_setOrnament->append($item_setTwinOrnament);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'also_set_twin_exits', $item_setTwinOrnament);
my $item_setOrnament = Gtk3::MenuItem->new('Set _ornaments');
$item_setOrnament->set_submenu($subMenu_setOrnament);
$column_exits->append($item_setOrnament);
# (Requires $self->currentRegionmap & either $self->selectedExit or
# $self->selectedExitHash)
$self->ivAdd('menuToolItemHash', 'set_ornament_sub', $item_setOrnament);
# 'Set exit type' submenu
my $subMenu_setExitType = Gtk3::Menu->new();
# 'Set hidden' sub-submenu
my $subSubMenu_setHidden = Gtk3::Menu->new();
my $item_setHiddenExit = Gtk3::MenuItem->new('Mark exit _hidden');
$item_setHiddenExit->signal_connect('activate' => sub {
$self->hiddenExitCallback(TRUE);
});
$subSubMenu_setHidden->append($item_setHiddenExit);
my $item_setNotHiddenExit = Gtk3::MenuItem->new('Mark exit _not hidden');
$item_setNotHiddenExit->signal_connect('activate' => sub {
$self->hiddenExitCallback(FALSE);
});
$subSubMenu_setHidden->append($item_setNotHiddenExit);
my $item_setHidden = Gtk3::MenuItem->new('Set _hidden');
$item_setHidden->set_submenu($subSubMenu_setHidden);
$subMenu_setExitType->append($item_setHidden);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_hidden_sub', $item_setHidden);
# 'Set broken' sub-submenu
my $subSubMenu_setBroken = Gtk3::Menu->new();
my $item_markBrokenExit = Gtk3::MenuItem->new('_Mark exit as broken');
$item_markBrokenExit->signal_connect('activate' => sub {
$self->markBrokenExitCallback();
});
$subSubMenu_setBroken->append($item_markBrokenExit);
my $item_toggleBrokenExit = Gtk3::MenuItem->new('_Toggle bent broken exit');
$item_toggleBrokenExit->signal_connect('activate' => sub {
$self->worldModelObj->toggleBentExit(
TRUE, # Update Automapper windows now
$self->selectedExit,
);
});
$subSubMenu_setBroken->append($item_toggleBrokenExit);
# (Requires $self->currentRegionmap and a $self->selectedExit which is a broken
# exit)
$self->ivAdd('menuToolItemHash', 'toggle_bent_exit', $item_toggleBrokenExit);
$subSubMenu_setBroken->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreBrokenExit = Gtk3::MenuItem->new('_Restore unbroken exit');
$item_restoreBrokenExit->signal_connect('activate' => sub {
$self->restoreBrokenExitCallback();
});
$subSubMenu_setBroken->append($item_restoreBrokenExit);
my $item_setBroken = Gtk3::MenuItem->new('Set _broken');
$item_setBroken->set_submenu($subSubMenu_setBroken);
$subMenu_setExitType->append($item_setBroken);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_broken_sub', $item_setBroken);
# 'Set one-way' sub-submenu
my $subSubMenu_setOneWay = Gtk3::Menu->new();
my $item_markOneWayExit = Gtk3::MenuItem->new('_Mark exit as one-way');
$item_markOneWayExit->signal_connect('activate' => sub {
$self->markOneWayExitCallback();
});
$subSubMenu_setOneWay->append($item_markOneWayExit);
$subSubMenu_setOneWay->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreUncertainExit = Gtk3::MenuItem->new('Restore _uncertain exit');
$item_restoreUncertainExit->signal_connect('activate' => sub {
$self->restoreOneWayExitCallback(FALSE);
});
$subSubMenu_setOneWay->append($item_restoreUncertainExit);
my $item_restoreTwoWayExit = Gtk3::MenuItem->new('Restore _two-way exit');
$item_restoreTwoWayExit->signal_connect('activate' => sub {
$self->restoreOneWayExitCallback(TRUE);
});
$subSubMenu_setOneWay->append($item_restoreTwoWayExit);
$subSubMenu_setOneWay->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setIncomingDir = Gtk3::MenuItem->new('Set incoming _direction...');
$item_setIncomingDir->signal_connect('activate' => sub {
$self->setIncomingDirCallback();
});
$subSubMenu_setOneWay->append($item_setIncomingDir);
# (Requires $self->currentRegionmap and a $self->selectedExit which is a one-way
# exit)
$self->ivAdd('menuToolItemHash', 'set_incoming_dir', $item_setIncomingDir);
my $item_setOneWay = Gtk3::MenuItem->new('Set _one-way');
$item_setOneWay->set_submenu($subSubMenu_setOneWay);
$subMenu_setExitType->append($item_setOneWay);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_oneway_sub', $item_setOneWay);
# 'Set retracing' sub-submenu
my $subSubMenu_setRetracing = Gtk3::Menu->new();
my $item_markRetracingExit = Gtk3::MenuItem->new('_Mark exit as retracing');
$item_markRetracingExit->signal_connect('activate' => sub {
$self->markRetracingExitCallback();
});
$subSubMenu_setRetracing->append($item_markRetracingExit);
$subSubMenu_setRetracing->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreRetracingExit = Gtk3::MenuItem->new('_Restore incomplete exit');
$item_restoreRetracingExit->signal_connect('activate' => sub {
$self->restoreRetracingExitCallback();
});
$subSubMenu_setRetracing->append($item_restoreRetracingExit);
my $item_setRetracing = Gtk3::MenuItem->new('Set _retracing');
$item_setRetracing->set_submenu($subSubMenu_setRetracing);
$subMenu_setExitType->append($item_setRetracing);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_retracing_sub', $item_setRetracing);
# 'Set random' sub-submenu
my $subSubMenu_setRandomExit = Gtk3::Menu->new();
my $item_markRandomRegion = Gtk3::MenuItem->new(
'Set random destination in same _region',
);
$item_markRandomRegion->signal_connect('activate' => sub {
$self->markRandomExitCallback('same_region');
});
$subSubMenu_setRandomExit->append($item_markRandomRegion);
my $item_markRandomAnywhere
= Gtk3::MenuItem->new('Set random destination _anywhere');
$item_markRandomAnywhere->signal_connect('activate' => sub {
$self->markRandomExitCallback('any_region');
});
$subSubMenu_setRandomExit->append($item_markRandomAnywhere);
my $item_randomTempRegion
= Gtk3::MenuItem->new('_Create destination in temporary region');
$item_randomTempRegion->signal_connect('activate' => sub {
$self->markRandomExitCallback('temp_region');
});
$subSubMenu_setRandomExit->append($item_randomTempRegion);
my $item_markRandomList = Gtk3::MenuItem->new('_Use list of random destinations');
$item_markRandomList->signal_connect('activate' => sub {
$self->markRandomExitCallback('room_list');
});
$subSubMenu_setRandomExit->append($item_markRandomList);
$subSubMenu_setRandomExit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreRandomExit = Gtk3::MenuItem->new('Restore _incomplete exit');
$item_restoreRandomExit->signal_connect('activate' => sub {
$self->restoreRandomExitCallback();
});
$subSubMenu_setRandomExit->append($item_restoreRandomExit);
my $item_setRandomExit = Gtk3::MenuItem->new('Set r_andom');
$item_setRandomExit->set_submenu($subSubMenu_setRandomExit);
$subMenu_setExitType->append($item_setRandomExit);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_random_sub', $item_setRandomExit);
# 'Set super' sub-submenu
my $subSubMenu_setSuperExit = Gtk3::Menu->new();
my $item_markSuper = Gtk3::MenuItem->new('Mark exit as _super-region exit');
$item_markSuper->signal_connect('activate' => sub {
$self->markSuperExitCallback(FALSE);
});
$subSubMenu_setSuperExit->append($item_markSuper);
my $item_markSuperExcl = Gtk3::MenuItem->new(
'Mark exit as _exclusive super-region exit',
);
$item_markSuperExcl->signal_connect('activate' => sub {
$self->markSuperExitCallback(TRUE);
});
$subSubMenu_setSuperExit->append($item_markSuperExcl);
$subSubMenu_setSuperExit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_markNotSuper = Gtk3::MenuItem->new('Mark exit as _normal region exit');
$item_markNotSuper->signal_connect('activate' => sub {
$self->restoreSuperExitCallback();
});
$subSubMenu_setSuperExit->append($item_markNotSuper);
my $item_setSuperExit = Gtk3::MenuItem->new('Set _super');
$item_setSuperExit->set_submenu($subSubMenu_setSuperExit);
$subMenu_setExitType->append($item_setSuperExit);
# (Requires $self->currentRegionmap and $self->selectedExit which is a region exit)
$self->ivAdd('menuToolItemHash', 'set_super_sub', $item_setSuperExit);
$subMenu_setExitType->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setExitTwin = Gtk3::MenuItem->new('Set exit _twin...');
$item_setExitTwin->signal_connect('activate' => sub {
$self->setExitTwinCallback();
});
$subMenu_setExitType->append($item_setExitTwin);
# (Requires $self->currentRegionmap and a $self->selectedExit which is either a one-way
# exit or an uncertain exit)
$self->ivAdd('menuToolItemHash', 'set_exit_twin', $item_setExitTwin);
my $item_setExitType = Gtk3::MenuItem->new('Set _exit type');
$item_setExitType->set_submenu($subMenu_setExitType);
$column_exits->append($item_setExitType);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'set_exit_type', $item_setExitType);
# 'Exit tags' submenu
my $subMenu_exitTags = Gtk3::Menu->new();
my $item_setExitText = Gtk3::MenuItem->new('_Edit tag text');
$item_setExitText->signal_connect('activate' => sub {
$self->editExitTagCallback();
});
$subMenu_exitTags->append($item_setExitText);
# (Requires $self->currentRegionmap and either a $self->selectedExit which is a region
# exit, or a $self->selectedExitTag)
$self->ivAdd('menuToolItemHash', 'edit_tag_text', $item_setExitText);
my $item_toggleExitTag = Gtk3::MenuItem->new('_Toggle exit tag');
$item_toggleExitTag->signal_connect('activate' => sub {
$self->toggleExitTagCallback();
});
$subMenu_exitTags->append($item_toggleExitTag);
# (Requires $self->currentRegionmap and either a $self->selectedExit which is a region
# exit, or a $self->selectedExitTag)
$self->ivAdd('menuToolItemHash', 'toggle_exit_tag', $item_toggleExitTag);
$subMenu_exitTags->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPositions = Gtk3::MenuItem->new('_Reset tag positions');
$item_resetPositions->signal_connect('activate' => sub {
$self->resetExitOffsetsCallback();
});
$subMenu_exitTags->append($item_resetPositions);
# (Requires $self->currentRegionmap and one or more of $self->selectedExit,
# $self->selectedExitHash, $self->selectedExitTag and $self->selectedExitTagHash)
$self->ivAdd('menuToolItemHash', 'reset_exit_tags', $item_resetPositions);
$subMenu_exitTags->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_applyExitTags = Gtk3::MenuItem->new('_Apply all tags in region');
$item_applyExitTags->signal_connect('activate' => sub {
$self->applyExitTagsCallback(TRUE);
});
$subMenu_exitTags->append($item_applyExitTags);
my $item_cancelExitTags = Gtk3::MenuItem->new('_Cancel all tags in region');
$item_cancelExitTags->signal_connect('activate' => sub {
$self->applyExitTagsCallback(FALSE);
});
$subMenu_exitTags->append($item_cancelExitTags);
my $item_exitTags = Gtk3::MenuItem->new('Exit _tags');
$item_exitTags->set_submenu($subMenu_exitTags);
$column_exits->append($item_exitTags);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'exit_tags', $item_exitTags);
$column_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editExit = Gtk3::ImageMenuItem->new('Edit e_xit...');
my $img_editExit = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editExit->set_image($img_editExit);
$item_editExit->signal_connect('activate' => sub {
$self->editExitCallback();
});
$column_exits->append($item_editExit);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'edit_exit', $item_editExit);
$column_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Exit options' submenu
my $subMenu_exitOptions = Gtk3::Menu->new();
my $item_completeSelected = Gtk3::MenuItem->new('_Complete selected uncertain exits');
$item_completeSelected->signal_connect('activate' => sub {
$self->completeExitsCallback();
});
$subMenu_exitOptions->append($item_completeSelected);
my $item_connectAdjacent = Gtk3::MenuItem->new('C_onnect selected adjacent rooms');
$item_connectAdjacent->signal_connect('activate' => sub {
$self->connectAdjacentCallback();
});
$subMenu_exitOptions->append($item_connectAdjacent);
# (Requires $self->currentRegionmap and one or more selected rooms)
$self->ivAdd('menuToolItemHash', 'connect_adjacent', $item_connectAdjacent);
$subMenu_exitOptions->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_autocomplete = Gtk3::CheckMenuItem->new('_Autocomplete uncertain exits');
$item_autocomplete->set_active($self->worldModelObj->autocompleteExitsFlag);
$item_autocomplete->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'autocompleteExitsFlag',
$item_autocomplete->get_active(),
FALSE, # Don't call $self->redrawRegions
'autcomplete_uncertain',
);
}
});
$subMenu_exitOptions->append($item_autocomplete);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'autocomplete_uncertain', $item_autocomplete);
my $item_intUncertain = Gtk3::CheckMenuItem->new('_Intelligent uncertain exits');
$item_intUncertain->set_active(
$self->worldModelObj->intelligentExitsFlag,
);
$item_intUncertain->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'intelligentExitsFlag',
$item_intUncertain->get_active(),
FALSE, # Don't call $self->redrawRegions
'intelligent_uncertain',
);
}
});
$subMenu_exitOptions->append($item_intUncertain);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'intelligent_uncertain', $item_intUncertain);
$subMenu_exitOptions->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_collectChecked = Gtk3::CheckMenuItem->new('Co_llect checked directions');
$item_collectChecked->set_active(
$self->worldModelObj->collectCheckedDirsFlag,
);
$item_collectChecked->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'collectCheckedDirsFlag',
$item_collectChecked->get_active(),
FALSE, # Don't call $self->redrawRegions
'collect_checked_dirs',
);
}
});
$subMenu_exitOptions->append($item_collectChecked);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'collect_checked_dirs', $item_collectChecked);
my $item_drawChecked = Gtk3::CheckMenuItem->new('_Draw checked directions');
$item_drawChecked->set_active(
$self->worldModelObj->drawCheckedDirsFlag,
);
$item_drawChecked->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'drawCheckedDirsFlag',
$item_drawChecked->get_active(),
FALSE, # Don't call $self->redrawRegions
'draw_checked_dirs',
);
}
# Redraw the region, if one is visible
if ($self->currentRegionmap) {
$self->redrawRegions();
}
});
$subMenu_exitOptions->append($item_drawChecked);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'draw_checked_dirs', $item_drawChecked);
$subMenu_exitOptions->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Checkable directions' sub-submenu
my $subSubMenu_checkable = Gtk3::Menu->new();
my $item_checkableSimple
= Gtk3::RadioMenuItem->new_with_mnemonic(undef, 'Count _NSEW');
$item_checkableSimple->signal_connect('toggled' => sub {
if ($item_checkableSimple->get_active) {
$self->worldModelObj->setCheckableDirMode('simple');
}
});
my $item_checkableGroup = $item_checkableSimple->get_group();
$subSubMenu_checkable->append($item_checkableSimple);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'checkable_dir_simple', $item_checkableSimple);
my $item_checkableDiku = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_checkableGroup,
'Count NSEW_UD',
);
if ($self->worldModelObj->checkableDirMode eq 'diku') {
$item_checkableDiku->set_active(TRUE);
}
$item_checkableDiku->signal_connect('toggled' => sub {
if ($item_checkableDiku->get_active) {
$self->worldModelObj->setCheckableDirMode('diku');
}
});
$subSubMenu_checkable->append($item_checkableDiku);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'checkable_dir_diku', $item_checkableDiku);
my $item_checkableLP = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_checkableGroup,
'Count NSEWUD, N_E/NW/SE/SW',
);
if ($self->worldModelObj->checkableDirMode eq 'lp') {
$item_checkableLP->set_active(TRUE);
}
$item_checkableLP->signal_connect('toggled' => sub {
if ($item_checkableLP->get_active) {
$self->worldModelObj->setCheckableDirMode('lp');
}
});
$subSubMenu_checkable->append($item_checkableLP);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'checkable_dir_lp', $item_checkableLP);
my $item_checkableComplex = Gtk3::RadioMenuItem->new_with_mnemonic(
$item_checkableGroup,
'Count _all primary directions',
);
if ($self->worldModelObj->checkableDirMode eq 'complex') {
$item_checkableComplex->set_active(TRUE);
}
$item_checkableComplex->signal_connect('toggled' => sub {
if ($item_checkableComplex->get_active) {
$self->worldModelObj->setCheckableDirMode('complex');
}
});
$subSubMenu_checkable->append($item_checkableComplex);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'checkable_dir_complex', $item_checkableComplex);
my $item_exits = Gtk3::MenuItem->new('C_heckable directions');
$item_exits->set_submenu($subSubMenu_checkable);
$subMenu_exitOptions->append($item_exits);
my $item_exitOptions = Gtk3::MenuItem->new('Exit o_ptions');
$item_exitOptions->set_submenu($subMenu_exitOptions);
$column_exits->append($item_exitOptions);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'exit_options', $item_exitOptions);
# 'Exit lengths' submenu
my $subMenu_exitLengths = Gtk3::Menu->new();
my $item_horizontalLength = Gtk3::MenuItem->new('Set _horizontal length...');
$item_horizontalLength->signal_connect('activate' => sub {
$self->setExitLengthCallback('horizontal');
});
$subMenu_exitLengths->append($item_horizontalLength);
my $item_verticalLength = Gtk3::MenuItem->new('Set _vertical length...');
$item_verticalLength->signal_connect('activate' => sub {
$self->setExitLengthCallback('vertical');
});
$subMenu_exitLengths->append($item_verticalLength);
$subMenu_exitLengths->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetLength = Gtk3::MenuItem->new('_Reset exit lengths');
$item_resetLength->signal_connect('activate' => sub {
$self->resetExitLengthCallback();
});
$subMenu_exitLengths->append($item_resetLength);
my $item_exitLengths = Gtk3::MenuItem->new('Exit _lengths');
$item_exitLengths->set_submenu($subMenu_exitLengths);
$column_exits->append($item_exitLengths);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'exit_lengths', $item_exitLengths);
$column_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteExit = Gtk3::ImageMenuItem->new('_Delete exit');
my $img_deleteExit = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteExit->set_image($img_deleteExit);
$item_deleteExit->signal_connect('activate' => sub {
$self->deleteExitCallback();
});
$column_exits->append($item_deleteExit);
# (Requires $self->currentRegionmap and $self->selectedExit)
$self->ivAdd('menuToolItemHash', 'delete_exit', $item_deleteExit);
# Setup complete
return $column_exits;
}
sub enableLabelsColumn {
# Called by $self->enableMenu
# Sets up the 'Labels' column of the Automapper window's menu bar
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Local variables
my $alignFlag;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableLabelsColumn', @_);
}
# Set up column
my $column_labels = Gtk3::Menu->new();
if (! $column_labels) {
return undef;
}
my $item_addLabelAtClick = Gtk3::ImageMenuItem->new('Add label at _click');
my $img_addLabelAtClick = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addLabelAtClick->set_image($img_addLabelAtClick);
$item_addLabelAtClick->signal_connect('activate' => sub {
# Set the free click mode; $self->canvasEventHandler will create the new label when the
# user next clicks on an empty part of the map
if ($self->currentRegionmap) {
$self->set_freeClickMode('add_label');
}
});
$column_labels->append($item_addLabelAtClick);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'add_label_at_click', $item_addLabelAtClick);
my $item_addLabelAtBlock = Gtk3::ImageMenuItem->new('Add label at _block');
my $img_addLabelAtBlock = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addLabelAtBlock->set_image($img_addLabelAtBlock);
$item_addLabelAtBlock->signal_connect('activate' => sub {
$self->addLabelAtBlockCallback();
});
$column_labels->append($item_addLabelAtBlock);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'add_label_at_block', $item_addLabelAtBlock);
$column_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setLabel = Gtk3::ImageMenuItem->new('_Set label...');
my $img_setLabel = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_setLabel->set_image($img_setLabel);
$item_setLabel->signal_connect('activate' => sub {
$self->setLabelCallback(FALSE);
});
$column_labels->append($item_setLabel);
# (Requires $self->currentRegionmap and $self->selectedLabel)
$self->ivAdd('menuToolItemHash', 'set_label', $item_setLabel);
my $item_customiseLabel = Gtk3::ImageMenuItem->new('C_ustomise label...');
my $img_customiseLabel = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_customiseLabel->set_image($img_customiseLabel);
$item_customiseLabel->signal_connect('activate' => sub {
$self->setLabelCallback(TRUE);
});
$column_labels->append($item_customiseLabel);
# (Requires $self->currentRegionmap and $self->selectedLabel)
$self->ivAdd('menuToolItemHash', 'customise_label', $item_customiseLabel);
my $item_useMultiLine = Gtk3::CheckMenuItem->new('Use _multiline labels');
$item_useMultiLine->set_active($self->worldModelObj->mapLabelTextViewFlag);
$item_useMultiLine->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'mapLabelTextViewFlag',
$item_useMultiLine->get_active(),
FALSE, # Don't call $self->redrawRegions
'use_multi_line',
);
}
});
$column_labels->append($item_useMultiLine);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'use_multi_line', $item_useMultiLine);
$column_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_selectLabel = Gtk3::MenuItem->new('S_elect label...');
$item_selectLabel->signal_connect('activate' => sub {
$self->selectLabelCallback();
});
$column_labels->append($item_selectLabel);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'select_label', $item_selectLabel);
$column_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addStyle = Gtk3::ImageMenuItem->new('_Add label style...');
my $img_addStyle = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addStyle->set_image($img_addStyle);
$item_addStyle->signal_connect('activate' => sub {
$self->addStyleCallback();
});
$column_labels->append($item_addStyle);
my $item_editStyle = Gtk3::ImageMenuItem->new('Ed_it label style...');
my $img_editStyle = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editStyle->set_image($img_editStyle);
$item_editStyle->signal_connect('activate' => sub {
$self->editStyleCallback();
});
$column_labels->append($item_editStyle);
# (Requires at least one label style in $self->worldModelObj->mapLabelStyleHash)
$self->ivAdd('menuToolItemHash', 'edit_style', $item_selectLabel);
# 'Label alignment' submenu
my $subMenu_alignment = Gtk3::Menu->new();
my $item_alignHorizontal = Gtk3::CheckMenuItem->new('Align _horizontally');
$item_alignHorizontal->set_active($self->worldModelObj->mapLabelAlignXFlag);
$item_alignHorizontal->signal_connect('toggled' => sub {
# Use $alignFlag to avoid an infinite loop, if we have to toggle the button back to
# its original state because the user declined to confirm the operation
if (! $alignFlag) {
if (! $self->toggleAlignCallback('horizontal')) {
$alignFlag = TRUE;
if (! $item_alignHorizontal->get_active()) {
$item_alignHorizontal->set_active(TRUE);
} else {
$item_alignHorizontal->set_active(FALSE);
}
$alignFlag = FALSE;
}
}
});
$subMenu_alignment->append($item_alignHorizontal);
my $item_alignVertical = Gtk3::CheckMenuItem->new('Align _vertically');
$item_alignVertical->set_active($self->worldModelObj->mapLabelAlignYFlag);
$item_alignVertical->signal_connect('toggled' => sub {
# Use $alignFlag to avoid an infinite loop, if we have to toggle the button back to
# its original state because the user declined to confirm the operation
if (! $alignFlag) {
if (! $self->toggleAlignCallback('vertical')) {
$alignFlag = TRUE;
if (! $item_alignVertical->get_active()) {
$item_alignVertical->set_active(TRUE);
} else {
$item_alignVertical->set_active(FALSE);
}
$alignFlag = FALSE;
}
}
});
$subMenu_alignment->append($item_alignVertical);
my $item_alignment = Gtk3::MenuItem->new('_Label alignment');
$item_alignment->set_submenu($subMenu_alignment);
$column_labels->append($item_alignment);
$column_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteLabel = Gtk3::ImageMenuItem->new('_Delete labels');
my $img_deleteLabel = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteLabel->set_image($img_deleteLabel);
$item_deleteLabel->signal_connect('activate' => sub {
# Callback to prompt for confirmation, before deleting multiple labels
$self->deleteLabelsCallback();
});
$column_labels->append($item_deleteLabel);
# (Requires $self->currentRegionmap & either $self->selectedLabel or
# $self->selectedLabelHash)
$self->ivAdd('menuToolItemHash', 'delete_label', $item_deleteLabel);
my $item_quickDelete = Gtk3::ImageMenuItem->new('_Quick label deletion...');
my $img_quickDelete = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_quickDelete->set_image($img_quickDelete);
$item_quickDelete->signal_connect('activate' => sub {
$self->session->pseudoCmd('quicklabeldelete', $self->pseudoCmdMode);
});
$column_labels->append($item_quickDelete);
# Setup complete
return $column_labels;
}
# Popup menu widget methods
sub enableCanvasPopupMenu {
# Called by $self->canvasEventHandler
# Creates a popup-menu for the Gtk3::Canvas when no rooms, exits, room tags or labels are
# selected
#
# Expected arguments
# $clickXPosPixels, $clickYPosPixels
# - Coordinates of the pixel that was right-clicked on the map
# $clickXPosBlocks, $clickYPosBlocks
# - Coordinates of the gridblock that was right-clicked on the map
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my (
$self, $clickXPosPixels, $clickYPosPixels, $clickXPosBlocks, $clickYPosBlocks, $check,
) = @_;
# Check for improper arguments
if (
! defined $clickXPosPixels || ! defined $clickYPosPixels
|| ! defined $clickXPosBlocks || ! defined $clickYPosBlocks || defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableCanvasPopupMenu', @_);
}
# Set up the popup menu
my $menu_canvas = Gtk3::Menu->new();
if (! $menu_canvas) {
return undef;
}
# (Everything here assumes $self->currentRegionmap)
my $item_addFirstRoom = Gtk3::ImageMenuItem->new('Add _first room');
my $img_addFirstRoom = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addFirstRoom->set_image($img_addFirstRoom);
$item_addFirstRoom->signal_connect('activate' => sub {
$self->addFirstRoomCallback();
});
$menu_canvas->append($item_addFirstRoom);
# (Also requires empty $self->currentRegionmap->gridRoomHash)
if ($self->currentRegionmap->gridRoomHash) {
$item_addFirstRoom->set_sensitive(FALSE);
}
my $item_addRoomHere = Gtk3::ImageMenuItem->new('Add _room here');
my $img_addRoomHere = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addRoomHere->set_image($img_addRoomHere);
$item_addRoomHere->signal_connect('activate' => sub {
my $roomObj;
# The 'Add room at click' operation from the main menu resets the value of
# ->freeClickMode; we must do the same here
$self->reset_freeClickMode();
# Create the room
$roomObj = $self->mapObj->createNewRoom(
$self->currentRegionmap,
$clickXPosBlocks,
$clickYPosBlocks,
$self->currentRegionmap->currentLevel,
);
# When using the 'Add room at block' menu item, the new room is selected to make it
# easier to see where it was drawn. To make things consistent, select this new room,
# too
if ($roomObj) {
$self->setSelectedObj(
[$roomObj, 'room'],
FALSE, # Select this object; unselect all other objects
);
}
});
$menu_canvas->append($item_addRoomHere);
$menu_canvas->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addLabelHere = Gtk3::ImageMenuItem->new('Add _label here');
my $img_addLabelHere = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_addLabelHere->set_image($img_addLabelHere);
$item_addLabelHere->signal_connect('activate' => sub {
$self->addLabelAtClickCallback($clickXPosPixels, $clickYPosPixels);
});
$menu_canvas->append($item_addLabelHere);
$menu_canvas->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_centreMap = Gtk3::MenuItem->new('_Centre map here');
$item_centreMap->signal_connect('activate' => sub {
$self->centreMapOverRoom(
undef, # Centre the map, not over a room...
$clickXPosBlocks, # ...but over this gridblock
$clickYPosBlocks,
);
});
$menu_canvas->append($item_centreMap);
$menu_canvas->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editRegionmap = Gtk3::ImageMenuItem->new('_Edit regionmap...');
my $img_editRegionmap = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editRegionmap->set_image($img_editRegionmap);
$item_editRegionmap->signal_connect('activate' => sub {
# Open an 'edit' window for the regionmap
$self->createFreeWin(
'Games::Axmud::EditWin::Regionmap',
$self,
$self->session,
'Edit \'' . $self->currentRegionmap->name . '\' regionmap',
$self->currentRegionmap,
FALSE, # Not temporary
);
});
$menu_canvas->append($item_editRegionmap);
my $item_preferences = Gtk3::ImageMenuItem->new('Edit world _model...');
my $img_preferences = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_preferences->set_image($img_preferences);
$item_preferences->signal_connect('activate' => sub {
# Open an 'edit' window for the world model
$self->createFreeWin(
'Games::Axmud::EditWin::WorldModel',
$self,
$self->session,
'Edit world model',
$self->session->worldModelObj,
FALSE, # Not temporary
);
});
$menu_canvas->append($item_preferences);
# Setup complete
$menu_canvas->show_all();
return $menu_canvas;
}
sub enableRoomsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected room
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableRoomsPopupMenu', @_);
}
# Set up the popup menu
my $menu_rooms = Gtk3::Menu->new();
if (! $menu_rooms) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedRoom)
my $item_setCurrentRoom = Gtk3::MenuItem->new('_Set current room');
$item_setCurrentRoom->signal_connect('activate' => sub {
$self->mapObj->setCurrentRoom($self->selectedRoom);
});
$menu_rooms->append($item_setCurrentRoom);
my $item_centreMap = Gtk3::MenuItem->new('_Centre map over room');
$item_centreMap->signal_connect('activate' => sub {
$self->centreMapOverRoom($self->selectedRoom);
});
$menu_rooms->append($item_centreMap);
my $item_executeScripts = Gtk3::MenuItem->new('Run _Axbasic scripts');
$item_executeScripts->signal_connect('activate' => sub {
$self->executeScriptsCallback();
});
$menu_rooms->append($item_executeScripts);
# (Also requires $self->mapObj->currentRoom that's the same as $self->selectedRoom)
if (! $self->mapObj->currentRoom || $self->mapObj->currentRoom ne $self->selectedRoom) {
$item_executeScripts->set_sensitive(FALSE);
}
$menu_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Pathfinding' submenu
my $subMenu_pathFinding = Gtk3::Menu->new();
my $item_highlightPath = Gtk3::MenuItem->new('_Highlight path');
$item_highlightPath->signal_connect('activate' => sub {
$self->processPathCallback('select_room');
});
$subMenu_pathFinding->append($item_highlightPath);
my $item_displayPath = Gtk3::MenuItem->new('_Edit path...');
$item_displayPath->signal_connect('activate' => sub {
$self->processPathCallback('pref_win');
});
$subMenu_pathFinding->append($item_displayPath);
my $item_goToRoom = Gtk3::MenuItem->new('_Go to room');
$item_goToRoom->signal_connect('activate' => sub {
$self->processPathCallback('send_char');
});
$subMenu_pathFinding->append($item_goToRoom);
my $item_pathFinding = Gtk3::MenuItem->new('_Pathfinding');
$item_pathFinding->set_submenu($subMenu_pathFinding);
$menu_rooms->append($item_pathFinding);
# (Also requires $self->mapObj->currentRoom)
if (! $self->mapObj->currentRoom) {
$item_pathFinding->set_sensitive(FALSE);
}
# 'Moves rooms/labels' submenu
my $subMenu_moveRooms = Gtk3::Menu->new();
my $item_moveSelected = Gtk3::MenuItem->new('Move in _direction...');
$item_moveSelected->signal_connect('activate' => sub {
$self->moveSelectedRoomsCallback();
});
$subMenu_moveRooms->append($item_moveSelected);
my $item_moveSelectedToClick = Gtk3::MenuItem->new('Move to _click');
$item_moveSelectedToClick->signal_connect('activate' => sub {
# Set the free clicking mode: $self->mouseClickEvent will move the objects when the
# user next clicks on an empty part of the map
$self->set_freeClickMode('move_room');
});
$subMenu_moveRooms->append($item_moveSelectedToClick);
$subMenu_moveRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Transfer to region' sub-submenu
my $subSubMenu_transferRegion = Gtk3::Menu->new();
if ($self->recentRegionList) {
foreach my $name ($self->recentRegionList) {
my $item_regionName = Gtk3::MenuItem->new($name);
$item_regionName->signal_connect('activate' => sub {
$self->transferSelectedRoomsCallback($name);
});
$subSubMenu_transferRegion->append($item_regionName);
}
} else {
my $item_regionNone = Gtk3::MenuItem->new('(No recent regions)');
$item_regionNone->set_sensitive(FALSE);
$subSubMenu_transferRegion->append($item_regionNone);
}
$subSubMenu_transferRegion->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_transferSelect = Gtk3::MenuItem->new('Select region...');
$item_transferSelect->signal_connect('activate' => sub {
$self->transferSelectedRoomsCallback();
});
$subSubMenu_transferRegion->append($item_transferSelect);
my $item_transferRegion = Gtk3::MenuItem->new('_Transfer to region');
$item_transferRegion->set_submenu($subSubMenu_transferRegion);
$subMenu_moveRooms->append($item_transferRegion);
# (Also requires at least two regions in the world model)
if ($self->worldModelObj->ivPairs('regionmapHash') <= 1) {
$item_transferRegion->set_sensitive(FALSE);
}
$subMenu_moveRooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_mergeRoom = Gtk3::MenuItem->new('_Merge room');
$item_mergeRoom->signal_connect('activate' => sub {
$self->doMerge($self->mapObj->currentRoom);
});
$subMenu_moveRooms->append($item_mergeRoom);
# (Also requires this to be the current room and the automapper being set up to perform
# a merge)
if (
! $self->mapObj->currentRoom
|| $self->mapObj->currentRoom ne $self->selectedRoom
|| ! $self->mapObj->currentMatchFlag
) {
$item_mergeRoom->set_sensitive(FALSE);
}
# 'Compare room' sub-submenu
my $subSubMenu_compareRoom = Gtk3::Menu->new();
my $item_compareRoomRegion = Gtk3::MenuItem->new('...with rooms in region');
$item_compareRoomRegion->signal_connect('activate' => sub {
$self->compareRoomCallback(FALSE);
});
$subSubMenu_compareRoom->append($item_compareRoomRegion);
my $item_compareRoomModel = Gtk3::MenuItem->new('...with rooms in whole world');
$item_compareRoomModel->signal_connect('activate' => sub {
$self->compareRoomCallback(TRUE);
});
$subSubMenu_compareRoom->append($item_compareRoomModel);
my $item_compareRoom = Gtk3::MenuItem->new('_Compare room');
$item_compareRoom->set_submenu($subSubMenu_compareRoom);
$subMenu_moveRooms->append($item_compareRoom);
my $item_moveRooms = Gtk3::MenuItem->new('_Move rooms/labels');
$item_moveRooms->set_submenu($subMenu_moveRooms);
$menu_rooms->append($item_moveRooms);
# 'Add pattern' submenu
my $subMenu_exitPatterns = Gtk3::Menu->new();
my $item_addFailedExitRoom = Gtk3::MenuItem->new('Add _failed exit...');
$item_addFailedExitRoom->signal_connect('activate' => sub {
$self->addFailedExitCallback(FALSE, $self->selectedRoom);
});
$subMenu_exitPatterns->append($item_addFailedExitRoom);
$subMenu_exitPatterns->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addInvoluntaryExitRoom = Gtk3::MenuItem->new('Add _involuntary exit...');
$item_addInvoluntaryExitRoom->signal_connect('activate' => sub {
$self->addInvoluntaryExitCallback($self->selectedRoom);
});
$subMenu_exitPatterns->append($item_addInvoluntaryExitRoom);
my $item_addRepulseExitRoom = Gtk3::MenuItem->new('Add _repulse exit...');
$item_addRepulseExitRoom->signal_connect('activate' => sub {
$self->addRepulseExitCallback($self->selectedRoom);
});
$subMenu_exitPatterns->append($item_addRepulseExitRoom);
$subMenu_exitPatterns->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addSpecialDepartRoom = Gtk3::MenuItem->new('Add _special departure...');
$item_addSpecialDepartRoom->signal_connect('activate' => sub {
$self->addSpecialDepartureCallback($self->selectedRoom);
});
$subMenu_exitPatterns->append($item_addSpecialDepartRoom);
my $item_addUnspecifiedRoom = Gtk3::MenuItem->new('Add _unspecified room pattern...');
$item_addUnspecifiedRoom->signal_connect('activate' => sub {
$self->addUnspecifiedPatternCallback($self->selectedRoom);
});
$subMenu_exitPatterns->append($item_addUnspecifiedRoom);
$menu_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_patterns = Gtk3::MenuItem->new('Add pa_ttern');
$item_patterns->set_submenu($subMenu_exitPatterns);
$menu_rooms->append($item_patterns);
# 'Add to model' submenu
my $subMenu_addToModel = Gtk3::Menu->new();
my $item_addRoomContents = Gtk3::MenuItem->new('Add _contents...');
$item_addRoomContents->signal_connect('activate' => sub {
$self->addContentsCallback(FALSE);
});
$subMenu_addToModel->append($item_addRoomContents);
# (Also requires $self->mapObj->currentRoom that's the same as $self->selectedRoom
if (! $self->mapObj->currentRoom || $self->mapObj->currentRoom ne $self->selectedRoom) {
$item_addRoomContents->set_sensitive(FALSE);
}
my $item_addContentsString = Gtk3::MenuItem->new('Add c_ontents from string...');
$item_addContentsString->signal_connect('activate' => sub {
$self->addContentsCallback(TRUE);
});
$subMenu_addToModel->append($item_addContentsString);
$subMenu_addToModel->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addHiddenObj = Gtk3::MenuItem->new('Add _hidden object...');
$item_addHiddenObj->signal_connect('activate' => sub {
$self->addHiddenObjCallback(FALSE);
});
$subMenu_addToModel->append($item_addHiddenObj);
# (Also requires $self->mapObj->currentRoom that's the same as $self->selectedRoom
if (! $self->mapObj->currentRoom || $self->mapObj->currentRoom ne $self->selectedRoom) {
$item_addHiddenObj->set_sensitive(FALSE);
}
my $item_addHiddenString = Gtk3::MenuItem->new('Add h_idden object from string...');
$item_addHiddenString->signal_connect('activate' => sub {
$self->addHiddenObjCallback(TRUE);
});
$subMenu_addToModel->append($item_addHiddenString);
$subMenu_addToModel->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addSearchResult = Gtk3::MenuItem->new('Add _search result...');
$item_addSearchResult->signal_connect('activate' => sub {
$self->addSearchResultCallback();
});
$subMenu_addToModel->append($item_addSearchResult);
# (Also requires $self->mapObj->currentRoom that's the same as $self->selectedRoom)
if (! $self->mapObj->currentRoom || $self->mapObj->currentRoom ne $self->selectedRoom) {
$item_addSearchResult->set_sensitive(FALSE);
}
my $item_addToModel = Gtk3::MenuItem->new('Add to m_odel');
$item_addToModel->set_submenu($subMenu_addToModel);
$menu_rooms->append($item_addToModel);
$menu_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Add/set exits' submenu
my $subMenu_setExits = Gtk3::Menu->new();
my $item_addExit = Gtk3::MenuItem->new('Add _normal exit...');
$item_addExit->signal_connect('activate' => sub {
$self->addExitCallback(FALSE); # FALSE - not a hidden exit
});
$subMenu_setExits->append($item_addExit);
# (Also requires the selected room's ->wildMode to be 'normal' or 'border')
if ($self->selectedRoom->wildMode eq 'wild') {
$item_addExit->set_sensitive(FALSE);
}
my $item_addHiddenExit = Gtk3::MenuItem->new('Add _hidden exit...');
$item_addHiddenExit->signal_connect('activate' => sub {
$self->addExitCallback(TRUE); # TRUE - a hidden exit
});
$subMenu_setExits->append($item_addHiddenExit);
# (Also requires the selected room's ->wildMode to be 'normal' or 'border')
if ($self->selectedRoom->wildMode eq 'wild') {
$item_addHiddenExit->set_sensitive(FALSE);
}
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addMultiple = Gtk3::MenuItem->new('Add _multiple exits...');
$item_addMultiple->signal_connect('activate' => sub {
$self->addMultipleExitsCallback();
});
$subMenu_setExits->append($item_addMultiple);
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_removeChecked = Gtk3::MenuItem->new('Remove _checked direction...');
$item_removeChecked->signal_connect('activate' => sub {
$self->removeCheckedDirCallback(FALSE);
});
$subMenu_setExits->append($item_removeChecked);
# (Also requires the selected room's ->checkedDirHash to be non-empty)
if (! $self->selectedRoom->checkedDirHash) {
$item_removeChecked->set_sensitive(FALSE);
}
my $item_removeCheckedAll = Gtk3::MenuItem->new('Remove _all checked directions');
$item_removeCheckedAll->signal_connect('activate' => sub {
$self->removeCheckedDirCallback(TRUE);
});
$subMenu_setExits->append($item_removeCheckedAll);
# (Also requires the selected room's ->checkedDirHash to be non-empty)
if (! $self->selectedRoom->checkedDirHash) {
$item_removeCheckedAll->set_sensitive(FALSE);
}
$subMenu_setExits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_markNormal = Gtk3::MenuItem->new('Mark room as n_ormal');
$item_markNormal->signal_connect('activate' => sub {
$self->setWildCallback('normal');
});
$subMenu_setExits->append($item_markNormal);
my $item_markWild = Gtk3::MenuItem->new('Mark room as _wilderness');
$item_markWild->signal_connect('activate' => sub {
$self->setWildCallback('wild');
});
$subMenu_setExits->append($item_markWild);
# (Also requires $self->session->currentWorld->basicMappingFlag to be FALSE)
if ($self->session->currentWorld->basicMappingFlag) {
$item_markWild->set_sensitive(FALSE);
}
my $item_markBorder = Gtk3::MenuItem->new('Mark room as wilderness _border');
$item_markBorder->signal_connect('activate' => sub {
$self->setWildCallback('border');
});
$subMenu_setExits->append($item_markBorder);
# (Also requires $self->session->currentWorld->basicMappingFlag to be FALSE)
if ($self->session->currentWorld->basicMappingFlag) {
$item_markBorder->set_sensitive(FALSE);
}
my $item_setExits = Gtk3::ImageMenuItem->new('Add/set _exits');
my $img_setExits = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_setExits->set_image($img_setExits);
$item_setExits->set_submenu($subMenu_setExits);
$menu_rooms->append($item_setExits);
my $item_selectExit = Gtk3::MenuItem->new('Se_lect exit...');
$item_selectExit->signal_connect('activate' => sub {
$self->selectExitCallback();
});
$menu_rooms->append($item_selectExit);
$menu_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editRoom = Gtk3::ImageMenuItem->new('Ed_it room...');
my $img_editRoom = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editRoom->set_image($img_editRoom);
$item_editRoom->signal_connect('activate' => sub {
if ($self->selectedRoom) {
# Open the room's 'edit' window
$self->createFreeWin(
'Games::Axmud::EditWin::ModelObj::Room',
$self,
$self->session,
'Edit ' . $self->selectedRoom->category . ' model object',
$self->selectedRoom,
FALSE, # Not temporary
);
}
});
$menu_rooms->append($item_editRoom);
# 'Set room text' submenu
my $subMenu_setRoomText = Gtk3::Menu->new();
my $item_setRoomTag = Gtk3::MenuItem->new('Set room _tag...');
$item_setRoomTag->signal_connect('activate' => sub {
$self->setRoomTagCallback();
});
$subMenu_setRoomText->append($item_setRoomTag);
my $item_setGuild = Gtk3::MenuItem->new('Set room _guild...');
$item_setGuild->signal_connect('activate' => sub {
$self->setRoomGuildCallback();
});
$subMenu_setRoomText->append($item_setGuild);
$subMenu_setRoomText->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPositions = Gtk3::MenuItem->new('_Reset text posit_ions');
$item_resetPositions->signal_connect('activate' => sub {
$self->resetRoomOffsetsCallback();
});
$subMenu_setRoomText->append($item_resetPositions);
my $item_setRoomText = Gtk3::MenuItem->new('Set _room text');
$item_setRoomText->set_submenu($subMenu_setRoomText);
$menu_rooms->append($item_setRoomText);
# 'Toggle room flag' submenu
my $subMenu_toggleRoomFlag = Gtk3::Menu->new();
if ($self->worldModelObj->roomFlagShowMode eq 'default') {
# Show all room flags, sorted by filter
foreach my $filter ($axmud::CLIENT->constRoomFilterList) {
# A sub-sub menu for $filter
my $subSubMenu_filter = Gtk3::Menu->new();
my @nameList = $self->worldModelObj->getRoomFlagsInFilter($filter);
foreach my $name (@nameList) {
my $obj = $self->worldModelObj->ivShow('roomFlagHash', $name);
if ($obj) {
my $menuItem = Gtk3::MenuItem->new($obj->descrip);
$menuItem->signal_connect('activate' => sub {
# Toggle the flags for all selected rooms, redraw them and (if the
# flag is one of the hazardous room flags) recalculate the
# regionmap's paths. The TRUE argument tells the world model to
# redraw the rooms
$self->worldModelObj->toggleRoomFlags(
$self->session,
TRUE,
$obj->name,
$self->compileSelectedRooms(),
);
});
$subSubMenu_filter->append($menuItem);
}
}
if (! @nameList) {
my $menuItem = Gtk3::MenuItem->new('(No flags in this filter)');
$menuItem->set_sensitive(FALSE);
$subSubMenu_filter->append($menuItem);
}
my $menuItem = Gtk3::MenuItem->new(ucfirst($filter));
$menuItem->set_submenu($subSubMenu_filter);
$subMenu_toggleRoomFlag->append($menuItem);
}
} else {
# Show selected room flags, sorted only by priority
my %showHash = $self->worldModelObj->getVisibleRoomFlags();
if (%showHash) {
foreach my $obj (sort {$a->priority <=> $b->priority} (values %showHash)) {
my $menuItem = Gtk3::MenuItem->new($obj->descrip);
$menuItem->signal_connect('activate' => sub {
# Toggle the flags for all selected rooms, redraw them and (if the
# flag is one of the hazardous room flags) recalculate the
# regionmap's paths. The TRUE argument tells the world model to
# redraw the rooms
$self->worldModelObj->toggleRoomFlags(
$self->session,
TRUE,
$obj->name,
$self->compileSelectedRooms(),
);
});
$subMenu_toggleRoomFlag->append($menuItem);
}
} else {
my $menuItem = Gtk3::MenuItem->new('(None are marked visible)');
$menuItem->set_sensitive(FALSE);
$subMenu_toggleRoomFlag->append($menuItem);
}
}
my $item_toggleRoomFlag = Gtk3::MenuItem->new('To_ggle room flags');
$item_toggleRoomFlag->set_submenu($subMenu_toggleRoomFlag);
$menu_rooms->append($item_toggleRoomFlag);
# 'Other room features' submenu
my $subMenu_roomFeatures = Gtk3::Menu->new();
# 'Update character visits' sub-submenu
my $subSubMenu_updateVisits = Gtk3::Menu->new();
my $item_increaseSetCurrent = Gtk3::MenuItem->new('Increase & set _current');
$item_increaseSetCurrent->signal_connect('activate' => sub {
$self->updateVisitsCallback('increase');
$self->mapObj->setCurrentRoom($self->selectedRoom);
});
$subSubMenu_updateVisits->append($item_increaseSetCurrent);
$subSubMenu_updateVisits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_increaseVisits = Gtk3::MenuItem->new('_Increase by one');
$item_increaseVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('increase');
});
$subSubMenu_updateVisits->append($item_increaseVisits);
my $item_decreaseVisits = Gtk3::MenuItem->new('_Decrease by one');
$item_decreaseVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('decrease');
});
$subSubMenu_updateVisits->append($item_decreaseVisits);
my $item_manualVisits = Gtk3::MenuItem->new('Set _manually');
$item_manualVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('manual');
});
$subSubMenu_updateVisits->append($item_manualVisits);
my $item_resetVisits = Gtk3::MenuItem->new('_Reset to zero');
$item_resetVisits->signal_connect('activate' => sub {
$self->updateVisitsCallback('reset');
});
$subSubMenu_updateVisits->append($item_resetVisits);
$subSubMenu_updateVisits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_toggleGraffiti = Gtk3::MenuItem->new('Toggle _graffiti');
$item_toggleGraffiti->signal_connect('activate' => sub {
$self->toggleGraffitiCallback();
});
$subSubMenu_updateVisits->append($item_toggleGraffiti);
# (Also requires $self->graffitiModeFlag)
if (! $self->graffitiModeFlag) {
$item_toggleGraffiti->set_sensitive(FALSE);
}
my $item_updateVisits = Gtk3::MenuItem->new('Update character _visits');
$item_updateVisits->set_submenu($subSubMenu_updateVisits);
$subMenu_roomFeatures->append($item_updateVisits);
# 'Room exclusivity' submenu
my $subMenu_exclusivity = Gtk3::Menu->new();
my $item_toggleExclusivity = Gtk3::MenuItem->new('_Toggle exclusivity');
$item_toggleExclusivity->signal_connect('activate' => sub {
$self->toggleExclusiveProfileCallback();
});
$subMenu_exclusivity->append($item_toggleExclusivity);
my $item_addExclusiveProf = Gtk3::MenuItem->new('_Add exclusive profile...');
$item_addExclusiveProf->signal_connect('activate' => sub {
$self->addExclusiveProfileCallback();
});
$subMenu_exclusivity->append($item_addExclusiveProf);
my $item_clearExclusiveProf = Gtk3::MenuItem->new('_Clear exclusive profiles');
$item_clearExclusiveProf->signal_connect('activate' => sub {
$self->resetExclusiveProfileCallback();
});
$subMenu_exclusivity->append($item_clearExclusiveProf);
my $item_exclusivity = Gtk3::MenuItem->new('Room _exclusivity');
$item_exclusivity->set_submenu($subMenu_exclusivity);
$subMenu_roomFeatures->append($item_exclusivity);
# 'Source code' sub-submenu
my $subSubMenu_sourceCode = Gtk3::Menu->new();
my $item_setFilePath = Gtk3::MenuItem->new('_Set file path...');
$item_setFilePath->signal_connect('activate' => sub {
$self->setFilePathCallback();
});
$subSubMenu_sourceCode->append($item_setFilePath);
my $item_setVirtualArea = Gtk3::MenuItem->new('Set virtual _area...');
$item_setVirtualArea->signal_connect('activate' => sub {
$self->setVirtualAreaCallback(TRUE);
});
$subSubMenu_sourceCode->append($item_setVirtualArea);
my $item_resetVirtualArea = Gtk3::MenuItem->new('_Reset virtual area...');
$item_resetVirtualArea->signal_connect('activate' => sub {
$self->setVirtualAreaCallback(FALSE);
});
$subSubMenu_sourceCode->append($item_resetVirtualArea);
$subSubMenu_sourceCode->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_viewSource = Gtk3::MenuItem->new('_View source file...');
$item_viewSource->signal_connect('activate' => sub {
my $flag;
if ($self->selectedRoom) {
if (! $self->selectedRoom->virtualAreaPath) {
$flag = FALSE;
} else {
$flag = TRUE;
}
# Show source code file
$self->quickFreeWin(
'Games::Axmud::OtherWin::SourceCode',
$self->session,
# Config
'model_obj' => $self->selectedRoom,
'virtual_flag' => $flag,
);
}
});
$subSubMenu_sourceCode->append($item_viewSource);
# (Also requires either $self->selectedRoom->sourceCodePath or
# $self->selectedRoom->virtualAreaPath)
if (
! $self->selectedRoom->sourceCodePath
&& ! $self->selectedRoom->virtualAreaPath
) {
$item_viewSource->set_sensitive(FALSE);
}
my $item_editSource = Gtk3::MenuItem->new('Edit so_urce file...');
$item_editSource->signal_connect('activate' => sub {
if ($self->selectedRoom) {
if (! $self->selectedRoom->virtualAreaPath) {
# Edit source code file
$self->editFileCallback();
} else {
# Edit virtual area file
$self->editFileCallback(TRUE);
}
}
});
$subSubMenu_sourceCode->append($item_editSource);
# (Also requires either $self->selectedRoom->sourceCodePath or
# $self->selectedRoom->virtualAreaPath)
if (
! $self->selectedRoom->sourceCodePath
&& ! $self->selectedRoom->virtualAreaPath
) {
$item_editSource->set_sensitive(FALSE);
}
my $item_sourceCode = Gtk3::MenuItem->new('Source _code');
$item_sourceCode->set_submenu($subSubMenu_sourceCode);
$subMenu_roomFeatures->append($item_sourceCode);
$subMenu_roomFeatures->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setInteriorOffsets = Gtk3::MenuItem->new('_Synchronise grid coordinates...');
$item_setInteriorOffsets->signal_connect('activate' => sub {
$self->setInteriorOffsetsCallback();
});
$subMenu_roomFeatures->append($item_setInteriorOffsets);
my $item_resetInteriorOffsets = Gtk3::MenuItem->new('_Reset grid coordinates');
$item_resetInteriorOffsets->signal_connect('activate' => sub {
$self->resetInteriorOffsetsCallback();
});
$subMenu_roomFeatures->append($item_resetInteriorOffsets);
my $item_roomFeatures = Gtk3::MenuItem->new('Ot_her room features');
$item_roomFeatures->set_submenu($subMenu_roomFeatures);
$menu_rooms->append($item_roomFeatures);
$menu_rooms->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteRoom = Gtk3::ImageMenuItem->new('_Delete room');
my $img_deleteRoom = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteRoom->set_image($img_deleteRoom);
$item_deleteRoom->signal_connect('activate' => sub {
$self->deleteRoomsCallback();
});
$menu_rooms->append($item_deleteRoom);
# Setup complete
$menu_rooms->show_all();
return $menu_rooms;
}
sub enableRoomTagsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected room tag
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->enableRoomTagsPopupMenu',
@_,
);
}
# Set up the popup menu
my $menu_tags = Gtk3::Menu->new();
if (! $menu_tags) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedRoomTag)
my $item_editTag = Gtk3::MenuItem->new('_Set room tag...');
$item_editTag->signal_connect('activate' => sub {
$self->setRoomTagCallback();
});
$menu_tags->append($item_editTag);
my $item_resetPosition = Gtk3::MenuItem->new('_Reset position');
$item_resetPosition->signal_connect('activate' => sub {
if ($self->selectedRoomTag) {
$self->worldModelObj->resetRoomOffsets(
TRUE, # Update Automapper windows now
1, # Mode 1 - reset room tag only
$self->selectedRoomTag, # Set to the parent room's blessed reference
);
}
});
$menu_tags->append($item_resetPosition);
# Setup complete
$menu_tags->show_all();
return $menu_tags;
}
sub enableRoomGuildsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected room guild
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->enableRoomGuildsPopupMenu',
@_,
);
}
# Set up the popup menu
my $menu_guilds = Gtk3::Menu->new();
if (! $menu_guilds) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedRoomGuild)
my $item_editGuild = Gtk3::MenuItem->new('_Set room guild...');
$item_editGuild->signal_connect('activate' => sub {
$self->setRoomGuildCallback();
});
$menu_guilds->append($item_editGuild);
my $item_resetPosition = Gtk3::MenuItem->new('_Reset position');
$item_resetPosition->signal_connect('activate' => sub {
if ($self->selectedRoomGuild) {
$self->worldModelObj->resetRoomOffsets(
TRUE, # Update Automapper windows now
2, # Mode 2 - reset room guild only
$self->selectedRoomGuild, # Set to the parent room's blessed reference
);
}
});
$menu_guilds->append($item_resetPosition);
# Setup complete
$menu_guilds->show_all();
return $menu_guilds;
}
sub enableExitsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected exit
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Local variables
my @titleList;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableExitsPopupMenu', @_);
}
# Set up the popup menu
my $menu_exits = Gtk3::Menu->new();
if (! $menu_exits) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedExit)
# 'Allocate map direction' submenu
my $subMenu_setDir = Gtk3::Menu->new();
my $item_changeDir = Gtk3::MenuItem->new('_Change direction...');
$item_changeDir->signal_connect('activate' => sub {
$self->changeDirCallback();
});
$subMenu_setDir->append($item_changeDir);
# (Also requires $self->selectedExit->drawMode is 'primary' or 'perm_alloc'
if (
$self->selectedExit->drawMode ne 'primary'
&& $self->selectedExit->drawMode ne 'perm_alloc'
) {
$item_changeDir->set_sensitive(FALSE);
}
my $item_altDir = Gtk3::MenuItem->new('Set _alternative direction(s)...');
$item_altDir->signal_connect('activate' => sub {
$self->setAltDirCallback();
});
$subMenu_setDir->append($item_altDir);
my $item_setDir = Gtk3::MenuItem->new('Set di_rection');
$item_setDir->set_submenu($subMenu_setDir);
$menu_exits->append($item_setDir);
my $item_setAssisted = Gtk3::MenuItem->new('Set assisted _move...');
$item_setAssisted->signal_connect('activate' => sub {
$self->setAssistedMoveCallback();
});
$menu_exits->append($item_setAssisted);
# (Also requires $self->selectedExit->drawMode 'primary', 'temp_unalloc' or 'perm_unalloc')
if ($self->selectedExit->drawMode eq 'temp_alloc') {
$item_setAssisted->set_sensitive(FALSE);
}
# 'Allocate map direction' submenu
my $subMenu_allocateMapDir = Gtk3::Menu->new();
my $item_allocatePrimary = Gtk3::MenuItem->new('Choose _direction...');
$item_allocatePrimary->signal_connect('activate' => sub {
$self->allocateMapDirCallback();
});
$subMenu_allocateMapDir->append($item_allocatePrimary);
my $item_confirmTwoWay = Gtk3::MenuItem->new('Confirm _two-way exit...');
$item_confirmTwoWay->signal_connect('activate' => sub {
$self->confirmTwoWayCallback();
});
$subMenu_allocateMapDir->append($item_confirmTwoWay);
my $item_allocateMapDir = Gtk3::MenuItem->new('_Allocate map direction...');
$item_allocateMapDir->set_submenu($subMenu_allocateMapDir);
$menu_exits->append($item_allocateMapDir);
# (Also requires $self->selectedExit->drawMode is 'temp_alloc' or 'temp_unalloc')
if (
$self->selectedExit->drawMode ne 'temp_alloc'
&& $self->selectedExit->drawMode ne 'temp_unalloc'
) {
$item_allocateMapDir->set_sensitive(FALSE);
}
my $item_allocateShadow = Gtk3::MenuItem->new('Allocate _shadow...');
$item_allocateShadow->signal_connect('activate' => sub {
$self->allocateShadowCallback();
});
$menu_exits->append($item_allocateShadow);
# (Also requires $self->selectedExit->drawMode is 'temp_alloc' or 'temp_unalloc')
if (
$self->selectedExit->drawMode ne 'temp_alloc'
&& $self->selectedExit->drawMode ne 'temp_unalloc'
) {
$item_allocateShadow->set_sensitive(FALSE);
}
$menu_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_connectExitToClick = Gtk3::MenuItem->new('_Connect to click');
$item_connectExitToClick->signal_connect('activate' => sub {
$self->connectToClickCallback();
});
$menu_exits->append($item_connectExitToClick);
# (Also requires $self->selectedExit->drawMode 'primary', 'temp_unalloc' or 'perm_unalloc')
if ($self->selectedExit->drawMode eq 'temp_alloc') {
$item_connectExitToClick->set_sensitive(FALSE);
}
my $item_disconnectExit = Gtk3::MenuItem->new('D_isconnect exit');
$item_disconnectExit->signal_connect('activate' => sub {
$self->disconnectExitCallback();
});
$menu_exits->append($item_disconnectExit);
$menu_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_addExitBend = Gtk3::MenuItem->new('Add _bend');
$item_addExitBend->signal_connect('activate' => sub {
$self->addBendCallback();
});
$menu_exits->append($item_addExitBend);
# (Also requires a $self->selectedExit that's a one-way or two-way broken exit, not a region
# exit, and also defined values for $self->exitClickXPosn and $self->exitClickYPosn)
if (
(! $self->selectedExit->oneWayFlag && ! $self->selectedExit->twinExit)
|| $self->selectedExit->regionFlag
|| ! defined $self->exitClickXPosn
|| ! defined $self->exitClickYPosn
) {
$item_addExitBend->set_sensitive(FALSE);
}
my $item_removeExitBend = Gtk3::MenuItem->new('Remo_ve bend');
$item_removeExitBend->signal_connect('activate' => sub {
$self->removeBendCallback();
});
$menu_exits->append($item_removeExitBend);
# (Also requires a $self->selectedExit that's a one-way or two-way exit with a bend, and
# also defined values for $self->exitClickXPosn and $self->exitClickYPosn)
if (
(! $self->selectedExit->oneWayFlag && ! $self->selectedExit->twinExit)
|| ! $self->selectedExit->bendOffsetList
|| ! defined $self->exitClickXPosn
|| ! defined $self->exitClickYPosn
) {
$item_removeExitBend->set_sensitive(FALSE);
}
$menu_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Set ornaments' submenu
my $subMenu_setOrnament = Gtk3::Menu->new();
# Create a list of exit ornament types, in groups of two, in the form
# (menu_item_title, exit_ornament_type)
@titleList = (
'_No ornament', 'none',
'_Openable exit', 'open',
'_Lockable exit', 'lock',
'_Pickable exit', 'pick',
'_Breakable exit', 'break',
'_Impassable exit', 'impass',
'_Mystery exit', 'mystery',
);
do {
my ($title, $type);
$title = shift @titleList;
$type = shift @titleList;
my $menuItem = Gtk3::MenuItem->new($title);
$menuItem->signal_connect('activate' => sub {
$self->exitOrnamentCallback($type);
});
$subMenu_setOrnament->append($menuItem);
} until (! @titleList);
$subMenu_setOrnament->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setTwinOrnament = Gtk3::CheckMenuItem->new('Also set _twin exits');
$item_setTwinOrnament->set_active($self->worldModelObj->setTwinOrnamentFlag);
$item_setTwinOrnament->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'setTwinOrnamentFlag',
$item_setTwinOrnament->get_active(),
FALSE, # Don't call $self->redrawRegions
'also_set_twin_exits',
);
}
});
$subMenu_setOrnament->append($item_setTwinOrnament);
my $item_setOrnament = Gtk3::MenuItem->new('Set _ornaments');
$item_setOrnament->set_submenu($subMenu_setOrnament);
$menu_exits->append($item_setOrnament);
# 'Set exit type' submenu
my $subMenu_setExitType = Gtk3::Menu->new();
# 'Set hidden' sub-submenu
my $subSubMenu_setHidden = Gtk3::Menu->new();
my $item_setHiddenExit = Gtk3::MenuItem->new('Mark exit _hidden');
$item_setHiddenExit->signal_connect('activate' => sub {
$self->hiddenExitCallback(TRUE);
});
$subSubMenu_setHidden->append($item_setHiddenExit);
my $item_setNotHiddenExit = Gtk3::MenuItem->new('Mark exit _not hidden');
$item_setNotHiddenExit->signal_connect('activate' => sub {
$self->hiddenExitCallback(FALSE);
});
$subSubMenu_setHidden->append($item_setNotHiddenExit);
my $item_setHidden = Gtk3::MenuItem->new('Set _hidden');
$item_setHidden->set_submenu($subSubMenu_setHidden);
$subMenu_setExitType->append($item_setHidden);
# 'Set broken' sub-submenu
my $subSubMenu_setBroken = Gtk3::Menu->new();
my $item_markBrokenExit = Gtk3::MenuItem->new('_Mark exit as broken');
$item_markBrokenExit->signal_connect('activate' => sub {
$self->markBrokenExitCallback();
});
$subSubMenu_setBroken->append($item_markBrokenExit);
my $item_toggleBrokenExit = Gtk3::MenuItem->new('_Toggle bent broken exit');
$item_toggleBrokenExit->signal_connect('activate' => sub {
$self->worldModelObj->toggleBentExit(
TRUE, # Update Automapper windows now
$self->selectedExit,
);
});
$subSubMenu_setBroken->append($item_toggleBrokenExit);
# (Also requires $self->selectedExit->brokenFlag)
if (! $self->selectedExit->brokenFlag) {
$item_toggleBrokenExit->set_sensitive(FALSE);
}
$subSubMenu_setBroken->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreBrokenExit = Gtk3::MenuItem->new('_Restore unbroken exit');
$item_restoreBrokenExit->signal_connect('activate' => sub {
$self->restoreBrokenExitCallback();
});
$subSubMenu_setBroken->append($item_restoreBrokenExit);
my $item_setBroken = Gtk3::MenuItem->new('Set _broken');
$item_setBroken->set_submenu($subSubMenu_setBroken);
$subMenu_setExitType->append($item_setBroken);
# 'Set one-way' sub-submenu
my $subSubMenu_setOneWay = Gtk3::Menu->new();
my $item_markOneWayExit = Gtk3::MenuItem->new('_Mark exit as one-way');
$item_markOneWayExit->signal_connect('activate' => sub {
$self->markOneWayExitCallback();
});
$subSubMenu_setOneWay->append($item_markOneWayExit);
$subSubMenu_setOneWay->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreUncertainExit = Gtk3::MenuItem->new('Restore _uncertain exit');
$item_restoreUncertainExit->signal_connect('activate' => sub {
$self->restoreOneWayExitCallback(FALSE);
});
$subSubMenu_setOneWay->append($item_restoreUncertainExit);
my $item_restoreTwoWayExit = Gtk3::MenuItem->new('Restore _two-way exit');
$item_restoreTwoWayExit->signal_connect('activate' => sub {
$self->restoreOneWayExitCallback(TRUE);
});
$subSubMenu_setOneWay->append($item_restoreTwoWayExit);
$subSubMenu_setOneWay->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setIncomingDir = Gtk3::MenuItem->new('Set incoming _direction...');
$item_setIncomingDir->signal_connect('activate' => sub {
$self->setIncomingDirCallback();
});
$subSubMenu_setOneWay->append($item_setIncomingDir);
# (Also requires either a $self->selectedExit which is a one-way exit)
if (! $self->selectedExit->oneWayFlag) {
$item_setIncomingDir->set_sensitive(FALSE);
}
my $item_setOneWay = Gtk3::MenuItem->new('Set _one-way');
$item_setOneWay->set_submenu($subSubMenu_setOneWay);
$subMenu_setExitType->append($item_setOneWay);
# 'Set retracing' sub-submenu
my $subSubMenu_setRetracing = Gtk3::Menu->new();
my $item_markRetracingExit = Gtk3::MenuItem->new('_Mark exit as retracing');
$item_markRetracingExit->signal_connect('activate' => sub {
$self->markRetracingExitCallback();
});
$subSubMenu_setRetracing->append($item_markRetracingExit);
$subSubMenu_setRetracing->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreRetracingExit = Gtk3::MenuItem->new('_Restore incomplete exit');
$item_restoreRetracingExit->signal_connect('activate' => sub {
$self->restoreRetracingExitCallback();
});
$subSubMenu_setRetracing->append($item_restoreRetracingExit);
my $item_setRetracing = Gtk3::MenuItem->new('Set _retracing');
$item_setRetracing->set_submenu($subSubMenu_setRetracing);
$subMenu_setExitType->append($item_setRetracing);
# 'Set random' sub-submenu
my $subSubMenu_setRandomExit = Gtk3::Menu->new();
my $item_markRandomRegion = Gtk3::MenuItem->new(
'Set random destination in same _region',
);
$item_markRandomRegion->signal_connect('activate' => sub {
$self->markRandomExitCallback('same_region');
});
$subSubMenu_setRandomExit->append($item_markRandomRegion);
my $item_markRandomAnywhere = Gtk3::MenuItem->new(
'Set random destination _anywhere',
);
$item_markRandomAnywhere->signal_connect('activate' => sub {
$self->markRandomExitCallback('any_region');
});
$subSubMenu_setRandomExit->append($item_markRandomAnywhere);
my $item_randomTempRegion = Gtk3::MenuItem->new(
'_Create destination in temporary region',
);
$item_randomTempRegion->signal_connect('activate' => sub {
$self->markRandomExitCallback('temp_region');
});
$subSubMenu_setRandomExit->append($item_randomTempRegion);
my $item_markRandomList = Gtk3::MenuItem->new('_Use list of random destinations');
$item_markRandomList->signal_connect('activate' => sub {
$self->markRandomExitCallback('room_list');
});
$subSubMenu_setRandomExit->append($item_markRandomList);
$subSubMenu_setRandomExit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_restoreRandomExit = Gtk3::MenuItem->new('Restore _incomplete exit');
$item_restoreRandomExit->signal_connect('activate' => sub {
$self->restoreRandomExitCallback();
});
$subSubMenu_setRandomExit->append($item_restoreRandomExit);
my $item_setRandomExit = Gtk3::MenuItem->new('Set r_andom');
$item_setRandomExit->set_submenu($subSubMenu_setRandomExit);
$subMenu_setExitType->append($item_setRandomExit);
# 'Set super' sub-submenu
my $subSubMenu_setSuperExit = Gtk3::Menu->new();
my $item_markSuper = Gtk3::MenuItem->new('Mark exit as _super-region exit');
$item_markSuper->signal_connect('activate' => sub {
$self->markSuperExitCallback(FALSE);
});
$subSubMenu_setSuperExit->append($item_markSuper);
my $item_markSuperExcl = Gtk3::MenuItem->new(
'Mark exit as _exclusive super-region exit',
);
$item_markSuperExcl->signal_connect('activate' => sub {
$self->markSuperExitCallback(TRUE);
});
$subSubMenu_setSuperExit->append($item_markSuperExcl);
$subSubMenu_setSuperExit->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_markNotSuper = Gtk3::MenuItem->new('Mark exit as _normal region exit');
$item_markNotSuper->signal_connect('activate' => sub {
$self->restoreSuperExitCallback();
});
$subSubMenu_setSuperExit->append($item_markNotSuper);
my $item_setSuperExit = Gtk3::MenuItem->new('Set _super');
$item_setSuperExit->set_submenu($subSubMenu_setSuperExit);
$subMenu_setExitType->append($item_setSuperExit);
# (Also requires $self->selectedExit->regionFlag)
if (! $self->selectedExit->regionFlag) {
$item_setSuperExit->set_sensitive(FALSE);
}
$subMenu_setExitType->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_setExitTwin = Gtk3::MenuItem->new('Set exit _twin...');
$item_setExitTwin->signal_connect('activate' => sub {
$self->setExitTwinCallback();
});
$subMenu_setExitType->append($item_setExitTwin);
# (Also requires either a $self->selectedExit which is either a one-way exit or an
# uncertain exit)
if (
! $self->selectedExit->oneWayFlag
|| ! (
$self->selectedExit->destRoom
&& ! $self->selectedExit->twinExit
&& ! $self->selectedExit->retraceFlag
&& $self->selectedExit->randomType eq 'none'
)
) {
$item_setExitTwin->set_sensitive(FALSE);
}
my $item_setExitType = Gtk3::MenuItem->new('Set _exit type');
$item_setExitType->set_submenu($subMenu_setExitType);
$menu_exits->append($item_setExitType);
# 'Exit tags' submenu
my $subMenu_exitTags = Gtk3::Menu->new();
my $item_editTag = Gtk3::MenuItem->new('_Edit exit tag');
$item_editTag->signal_connect('activate' => sub {
$self->editExitTagCallback();
});
$subMenu_exitTags->append($item_editTag);
my $item_toggleExitTag = Gtk3::MenuItem->new('_Toggle exit tag');
$item_toggleExitTag->signal_connect('activate' => sub {
$self->toggleExitTagCallback();
});
$subMenu_exitTags->append($item_toggleExitTag);
$subMenu_exitTags->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPosition = Gtk3::MenuItem->new('_Reset text position');
$item_resetPosition->signal_connect('activate' => sub {
$self->resetExitOffsetsCallback();
});
$subMenu_exitTags->append($item_resetPosition);
my $item_exitTags = Gtk3::MenuItem->new('Exit _tags');
$item_exitTags->set_submenu($subMenu_exitTags);
$menu_exits->append($item_exitTags);
# (Also requires either a $self->selectedExit which is a region exit)
if (! $self->selectedExit->regionFlag) {
$item_exitTags->set_sensitive(FALSE);
}
$menu_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_editExit = Gtk3::ImageMenuItem->new('Edit e_xit...');
my $img_editExit = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_editExit->set_image($img_editExit);
$item_editExit->signal_connect('activate' => sub {
$self->editExitCallback();
});
$menu_exits->append($item_editExit);
$menu_exits->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteExit = Gtk3::ImageMenuItem->new('_Delete exit');
my $img_deleteExit = Gtk3::Image->new_from_stock('gtk-add', 'menu');
$item_deleteExit->set_image($img_deleteExit);
$item_deleteExit->signal_connect('activate' => sub {
$self->deleteExitCallback();
});
$menu_exits->append($item_deleteExit);
# Setup complete
$menu_exits->show_all();
return $menu_exits;
}
sub enableExitTagsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected exit tag
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->enableExitTagsPopupMenu',
@_,
);
}
# Set up the popup menu
my $menu_tags = Gtk3::Menu->new();
if (! $menu_tags) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedExitTag)
my $item_editTag = Gtk3::MenuItem->new('_Edit exit tag');
$item_editTag->signal_connect('activate' => sub {
$self->editExitTagCallback();
});
$menu_tags->append($item_editTag);
my $item_cancelTag = Gtk3::MenuItem->new('_Cancel exit tag');
$item_cancelTag->signal_connect('activate' => sub {
$self->toggleExitTagCallback();
});
$menu_tags->append($item_cancelTag);
$menu_tags->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_viewDestination = Gtk3::MenuItem->new('_View destination');
$item_viewDestination->signal_connect('activate' => sub {
$self->viewExitDestination();
});
$menu_tags->append($item_viewDestination);
$menu_tags->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_resetPosition = Gtk3::MenuItem->new('_Reset position');
$item_resetPosition->signal_connect('activate' => sub {
$self->resetExitOffsetsCallback();
});
$menu_tags->append($item_resetPosition);
# Setup complete
$menu_tags->show_all();
return $menu_tags;
}
sub enableLabelsPopupMenu {
# Called by $self->canvasObjEventHandler
# Creates a popup-menu for the selected label
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::Menu created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableLabelsPopupMenu', @_);
}
# Set up the popup menu
my $menu_labels = Gtk3::Menu->new();
if (! $menu_labels) {
return undef;
}
# (Everything here assumes $self->currentRegionmap and $self->selectedLabel)
my $item_setLabel = Gtk3::ImageMenuItem->new('_Set label...');
my $img_setLabel = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_setLabel->set_image($img_setLabel);
$item_setLabel->signal_connect('activate' => sub {
$self->setLabelCallback(FALSE)
});
$menu_labels->append($item_setLabel);
my $item_customiseLabel = Gtk3::ImageMenuItem->new('_Customise label...');
my $img_customiseLabel = Gtk3::Image->new_from_stock('gtk-edit', 'menu');
$item_customiseLabel->set_image($img_customiseLabel);
$item_customiseLabel->signal_connect('activate' => sub {
$self->setLabelCallback(TRUE);
});
$menu_labels->append($item_customiseLabel);
$menu_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
# 'Set label style' submenu
my $subMenu_setStyle = Gtk3::Menu->new();
foreach my $style (
sort {lc($a) cmp lc($b)} ($self->worldModelObj->ivKeys('mapLabelStyleHash'))
) {
my $item_thisStyle = Gtk3::MenuItem->new($style);
$item_thisStyle->signal_connect('activate' => sub {
$self->setLabelDirectCallback($style);
});
$subMenu_setStyle->append($item_thisStyle);
}
my $item_setStyle = Gtk3::MenuItem->new('S_et label style');
$item_setStyle->set_submenu($subMenu_setStyle);
$menu_labels->append($item_setStyle);
# (Also requires at least one label style)
if (! $self->worldModelObj->mapLabelStyleHash) {
$item_setStyle->set_sensitive(FALSE);
}
$menu_labels->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $item_deleteLabel = Gtk3::ImageMenuItem->new('_Delete label');
my $img_deleteLabel = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_deleteLabel->set_image($img_deleteLabel);
$item_deleteLabel->signal_connect('activate' => sub {
if ($self->selectedLabel) {
$self->worldModelObj->deleteLabels(
TRUE, # Update Automapper windows now
$self->selectedLabel,
);
}
});
$menu_labels->append($item_deleteLabel);
my $item_quickDelete = Gtk3::ImageMenuItem->new('_Quick label deletion...');
my $img_quickDelete = Gtk3::Image->new_from_stock('gtk-delete', 'menu');
$item_quickDelete->set_image($img_quickDelete);
$item_quickDelete->signal_connect('activate' => sub {
$self->session->pseudoCmd('quicklabeldelete', $self->pseudoCmdMode);
});
$menu_labels->append($item_quickDelete);
# Setup complete
$menu_labels->show_all();
return $menu_labels;
}
# Toolbar widget methods
sub enableToolbar {
# Called by $self->drawWidgets
# Sets up the Automapper window's Gtk3::Toolbar widget(s)
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if one of the widgets can't be created
# Otherwise returns a list of Gtk3::Toolbar widgets created
my ($self, $check) = @_;
# Local variables
my (
$flag,
@emptyList, @setList, @widgetList,
%checkHash,
);
# Check for improper arguments
if (defined $check) {
$axmud::CLIENT->writeImproper($self->_objClass . '->enableToolbar', @_);
return @emptyList;
}
# Import the list of button sets from the world model
# Remove 'default' (which shouldn't be there) and also remove any duplicates or unrecognised
# sets
foreach my $set ($self->worldModelObj->buttonSetList) {
if (
$set ne $self->constToolbarDefaultSet
&& ! exists $checkHash{$set}
&& $self->ivExists('buttonSetHash', $set)
) {
push (@setList, $set);
# Watch out for duplicates
$checkHash{$set} = undef;
}
}
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$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) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addToolbar', @_);
}
# Get a list of button sets that aren't already visible
# NB The 'default' set can only be viewed in the original (first) toolbar, so it's not added
# to this list
foreach my $set ($self->constButtonSetList) {
my $descrip = $self->ivShow('constButtonDescripHash', $set);
if ($set ne $self->constToolbarDefaultSet && ! $self->ivShow('buttonSetHash', $set)) {
push (@list, $descrip);
$hash{$descrip} = $set;
}
}
if (! @list) {
# All button sets are visible (this shouldn't happen)
return undef;
}
# Set up the popup menu
my $popupMenu = Gtk3::Menu->new();
if (! $popupMenu) {
return undef;
}
# Add a title menu item, which does nothing
my $title_item = Gtk3::MenuItem->new('Add button set:');
$title_item->signal_connect('activate' => sub {
return undef;
});
$title_item->set_sensitive(FALSE);
$popupMenu->append($title_item);
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
# Fill the popup menu with button sets
foreach my $descrip (@list) {
my $menu_item = Gtk3::MenuItem->new($descrip);
$menu_item->signal_connect('activate' => sub {
# Add the set to the world model's list of button sets...
$self->worldModelObj->add_buttonSet($hash{$descrip});
# ...then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
});
$popupMenu->append($menu_item);
}
# Also add a 'Cancel' menu item, which does nothing
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $cancel_item = Gtk3::MenuItem->new('Cancel');
$cancel_item->signal_connect('activate' => sub {
return undef;
});
$popupMenu->append($cancel_item);
# Display the popup menu
$popupMenu->popup(
undef, undef, undef, undef,
1, # Left mouse button
Gtk3::get_current_event_time(),
);
$popupMenu->show_all();
# Operation complete. Now wait for the user's response
return 1;
}
sub removeToolbar {
# Called by a ->signal_connect in $self->drawToolbar whenever the user clicks on the remove
# button in any toolbar except the original one
# Removes the specified toolbar and updates IVs
#
# Expected arguments
# $toolbar - The toolbar widget to be removed
#
# Return values
# 'undef' on improper arguments or if there's an error
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my (
$set,
@modList,
);
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->removeToolbar', @_);
}
# Check the toolbar widget still exists (no reason it shouldn't, but it doesn't hurt to
# check)
if (! $self->ivExists('toolbarHash', $toolbar)) {
return undef;
} else {
# Get the button set that was drawn in this toolbar
$set = $self->ivShow('toolbarHash', $toolbar);
}
# Add the set to the world model's list of button sets...
$self->worldModelObj->del_buttonSet($set);
# ...then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
return 1;
}
sub chooseButtonSet {
# Called by $self->drawToolbar and ->switchToolbarButtons
# Calls the right function for the specified button set, and returns the result
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
# $set - The button set to use (one of the items in $self->constButtonSetList)
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
return $self->drawDefaultButtonSet($toolbar);
} elsif ($set eq 'exits') {
return $self->drawExitsButtonSet($toolbar);
} elsif ($set eq 'painting') {
return $self->drawPaintingButtonSet($toolbar);
} elsif ($set eq 'quick') {
return $self->drawQuickButtonSet($toolbar);
} elsif ($set eq 'background') {
return $self->drawBackgroundButtonSet($toolbar);
} elsif ($set eq 'tracking') {
return $self->drawTrackingButtonSet($toolbar);
} elsif ($set eq 'misc') {
return $self->drawMiscButtonSet($toolbar);
} elsif ($set eq 'flags') {
return $self->drawFlagsButtonSet($toolbar);
} elsif ($set eq 'interiors') {
return $self->drawInteriorsButtonSet($toolbar);
} else {
return @emptyList;
}
}
sub drawDefaultButtonSet {
# Called by $self->chooseButtonSet, which in turn was called by $self->drawToolbar or
# ->switchToolbarButtons
# Draws buttons for this button set, and adds them to the toolbar
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my @buttonList;
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->drawDefaultButtonSet', @_);
}
# Radio button for 'wait mode'
my $radioButton_waitMode = Gtk3::RadioToolButton->new(undef);
if ($self->mode eq 'wait') {
$radioButton_waitMode->set_active(TRUE);
}
$radioButton_waitMode->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_wait.png')
);
$radioButton_waitMode->set_label('Wait mode');
$radioButton_waitMode->set_tooltip_text('Wait mode');
$radioButton_waitMode->signal_connect('toggled' => sub {
# (To stop the equivalent menu item from being toggled by the call to ->setMode, make
# use of $self->ignoreMenuUpdateFlag)
if ($radioButton_waitMode->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('wait');
}
});
push (@buttonList, $radioButton_waitMode);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_set_wait_mode', $radioButton_waitMode);
# Radio button for 'follow mode'
my $radioButton_followMode = Gtk3::RadioToolButton->new_from_widget($radioButton_waitMode);
if ($self->mode eq 'follow') {
$radioButton_followMode->set_active(TRUE);
}
$radioButton_followMode->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_follow.png')
);
$radioButton_followMode->set_label('Follow mode');
$radioButton_followMode->set_tooltip_text('Follow mode');
$radioButton_followMode->signal_connect('toggled' => sub {
if ($radioButton_followMode->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('follow');
}
});
push (@buttonList, $radioButton_followMode);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_set_follow_mode', $radioButton_followMode);
# Radio button for 'update' mode
my $radioButton_updateMode = Gtk3::RadioToolButton->new_from_widget(
$radioButton_followMode,
);
if ($self->mode eq 'update') {
$radioButton_updateMode->set_active(TRUE);
}
$radioButton_updateMode->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_update.png')
);
$radioButton_updateMode->set_label('Update mode');
$radioButton_updateMode->set_tooltip_text('Update mode');
$radioButton_updateMode->signal_connect('toggled' => sub {
if ($radioButton_updateMode->get_active && ! $self->ignoreMenuUpdateFlag) {
$self->setMode('update');
}
});
push (@buttonList, $radioButton_updateMode);
# (Requires $self->currentRegionmap, GA::Obj::WorldModel->disableUpdateModeFlag set to
# FALSE and a session not in 'connect offline' mode
$self->ivAdd('menuToolItemHash', 'icon_set_update_mode', $radioButton_updateMode);
# Separator
my $separator = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator);
# Toolbutton for 'move up level'
my $toolButton_moveUpLevel = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_move_up.png'),
'Move up level',
);
$toolButton_moveUpLevel->set_tooltip_text('Move up level');
$toolButton_moveUpLevel->signal_connect('clicked' => sub {
$self->setCurrentLevel($self->currentRegionmap->currentLevel + 1);
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
});
push (@buttonList, $toolButton_moveUpLevel);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_move_up_level', $toolButton_moveUpLevel);
# Toolbutton for 'move down level'
my $toolButton_moveDownLevel = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_move_down.png'),
'Move down level',
);
$toolButton_moveDownLevel->set_tooltip_text('Move down level');
$toolButton_moveDownLevel->signal_connect('clicked' => sub {
$self->setCurrentLevel($self->currentRegionmap->currentLevel - 1);
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
});
push (@buttonList, $toolButton_moveDownLevel);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_move_down_level', $toolButton_moveDownLevel);
# Separator
my $separator2 = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator2);
# Toolbutton for 'reset locator'
my $toolButton_resetLocator = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_reset_locator.png'),
'Reset Locator task',
);
$toolButton_resetLocator->set_tooltip_text('Reset locator task');
$toolButton_resetLocator->signal_connect('clicked' => sub {
$self->resetLocatorCallback();
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$toolButton_connectClick->set_tooltip_text('Connect selected exit to room');
$toolButton_connectClick->signal_connect('clicked' => sub {
$self->connectToClickCallback();
});
push (@buttonList, $toolButton_connectClick);
# (Requires $self->currentRegionmap, $self->selectedExit and
# $self->selectedExit->drawMode is 'primary', 'temp_unalloc' or 'perm_alloc')
$self->ivAdd('menuToolItemHash', 'icon_connect_click', $toolButton_connectClick);
# Toolbutton for 'take screenshot'
my $toolButton_visibleScreenshot = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_take_screenshot.png'),
'Take screenshot of visible map',
);
$toolButton_visibleScreenshot->set_tooltip_text('Take screenshot of visible map');
$toolButton_visibleScreenshot->signal_connect('clicked' => sub {
$self->regionScreenshotCallback('visible');
});
push (@buttonList, $toolButton_visibleScreenshot);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_visible_screenshot', $toolButton_visibleScreenshot);
return @buttonList;
}
sub drawExitsButtonSet {
# Called by $self->chooseButtonSet, which in turn was called by $self->drawToolbar or
# ->switchToolbarButtons
# Draws buttons for this button set, and adds them to the toolbar
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my @buttonList;
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->drawExitsButtonSet', @_);
}
# Radio button for 'use region exit settings' mode
my $radioButton_deferDrawExits = Gtk3::RadioToolButton->new(undef);
$radioButton_deferDrawExits->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_use_region.png'),
);
$radioButton_deferDrawExits->set_label('Use region exit settings');
$radioButton_deferDrawExits->set_tooltip_text('Use region exit settings');
$radioButton_deferDrawExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_deferDrawExits->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'ask_regionmap', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_defer_exits',
'icon_draw_defer_exits',
);
}
});
push (@buttonList, $radioButton_deferDrawExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_draw_defer_exits', $radioButton_deferDrawExits);
# Radio button for 'draw no exits' mode
my $radioButton_drawNoExits = Gtk3::RadioToolButton->new_from_widget(
$radioButton_deferDrawExits,
);
if ($self->worldModelObj->drawExitMode eq 'no_exit') {
$radioButton_drawNoExits->set_active(TRUE);
}
$radioButton_drawNoExits->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_draw_none.png'),
);
$radioButton_drawNoExits->set_label('Draw no exits');
$radioButton_drawNoExits->set_tooltip_text('Draw no exits');
$radioButton_drawNoExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_drawNoExits->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'no_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_no_exits',
'icon_draw_no_exits',
);
}
});
push (@buttonList, $radioButton_drawNoExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_draw_no_exits', $radioButton_drawNoExits);
# Radio button for 'draw simple exits' mode
my $radioButton_drawSimpleExits = Gtk3::RadioToolButton->new_from_widget(
$radioButton_drawNoExits,
);
if ($self->worldModelObj->drawExitMode eq 'simple_exit') {
$radioButton_drawSimpleExits->set_active(TRUE);
}
$radioButton_drawSimpleExits->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_draw_simple.png'),
);
$radioButton_drawSimpleExits->set_label('Draw simple exits');
$radioButton_drawSimpleExits->set_tooltip_text('Draw simple exits');
$radioButton_drawSimpleExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_drawSimpleExits->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'simple_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_simple_exits',
'icon_draw_simple_exits',
);
}
});
push (@buttonList, $radioButton_drawSimpleExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_draw_simple_exits', $radioButton_drawSimpleExits);
# Radio button for 'draw complex exits' mode
my $radioButton_drawComplexExits = Gtk3::RadioToolButton->new_from_widget(
$radioButton_drawSimpleExits,
);
if ($self->worldModelObj->drawExitMode eq 'complex_exit') {
$radioButton_drawComplexExits->set_active(TRUE);
}
$radioButton_drawComplexExits->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_draw_complex.png'),
);
$radioButton_drawComplexExits->set_label('Draw complex exits');
$radioButton_drawComplexExits->set_tooltip_text('Draw complex exits');
$radioButton_drawComplexExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_drawComplexExits->get_active()) {
$self->worldModelObj->switchMode(
'drawExitMode',
'complex_exit', # New value of ->drawExitMode
TRUE, # Do call $self->redrawRegions
'draw_complex_exits',
'icon_draw_complex_exits',
);
}
});
push (@buttonList, $radioButton_drawComplexExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_draw_complex_exits', $radioButton_drawComplexExits);
# Toggle button for 'obscure unimportant exits'
my $toggleButton_obscuredExits = Gtk3::ToggleToolButton->new();
$toggleButton_obscuredExits->set_active($self->worldModelObj->obscuredExitFlag);
$toggleButton_obscuredExits->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_obscured_exits.png'),
);
$toggleButton_obscuredExits->set_label('Obscure unimportant exits');
$toggleButton_obscuredExits->set_tooltip_text('Obscure unimportant exits');
$toggleButton_obscuredExits->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'obscuredExitFlag',
$toggleButton_obscuredExits->get_active(),
TRUE, # Do call $self->redrawRegions
'obscured_exits',
'icon_obscured_exits',
);
}
});
push (@buttonList, $toggleButton_obscuredExits);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_obscured_exits', $toggleButton_obscuredExits);
# Toggle button for 'auto-redraw obscured exits'
my $toggleButton_autoRedraw = Gtk3::ToggleToolButton->new();
$toggleButton_autoRedraw->set_active($self->worldModelObj->obscuredExitRedrawFlag);
$toggleButton_autoRedraw->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_auto_redraw.png'),
);
$toggleButton_autoRedraw->set_label('Auto-redraw obscured exits');
$toggleButton_autoRedraw->set_tooltip_text('Auto-redraw obscured exits');
$toggleButton_autoRedraw->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'obscuredExitRedrawFlag',
$toggleButton_autoRedraw->get_active(),
TRUE, # Do call $self->redrawRegions
'auto_redraw_obscured',
'icon_auto_redraw_obscured',
);
}
});
push (@buttonList, $toggleButton_autoRedraw);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_auto_redraw_obscured', $toggleButton_autoRedraw);
# Toolbutton for 'obscure exits in radius'
my $toolButton_obscuredRadius = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_obscured_radius.png'),
'Obscure exits in radius',
);
$toolButton_obscuredRadius->set_tooltip_text('Obscure exits in radius');
$toolButton_obscuredRadius->signal_connect('clicked' => sub {
$self->obscuredRadiusCallback();
});
push (@buttonList, $toolButton_obscuredRadius);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_obscured_radius', $toolButton_obscuredRadius);
# Separator
my $separator = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator);
# Toolbutton for 'horizontal exit length'
my $toolButton_horizontalLengths = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR
. '/icons/map/icon_horizontal_lengths.png'),
'Horizontal exit length',
);
$toolButton_horizontalLengths->set_tooltip_text('Horizontal exit length');
$toolButton_horizontalLengths->signal_connect('clicked' => sub {
$self->setExitLengthCallback('horizontal');
});
push (@buttonList, $toolButton_horizontalLengths);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_horizontal_lengths', $toolButton_horizontalLengths);
# Toolbutton for 'vertical exit length'
my $toolButton_verticalLengths = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR
. '/icons/map/icon_vertical_lengths.png'),
'Vertical exit length',
);
$toolButton_verticalLengths->set_tooltip_text('Vertical exit length');
$toolButton_verticalLengths->signal_connect('clicked' => sub {
$self->setExitLengthCallback('vertical');
});
push (@buttonList, $toolButton_verticalLengths);
# (Requires $self->currentRegionmap)
$self->ivAdd('menuToolItemHash', 'icon_vertical_lengths', $toolButton_verticalLengths);
# Separator
my $separator2 = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator2);
# Toggle button for 'draw exit ornaments'
my $toggleButton_drawExitOrnaments = Gtk3::ToggleToolButton->new();
$toggleButton_drawExitOrnaments->set_active($self->worldModelObj->drawOrnamentsFlag);
$toggleButton_drawExitOrnaments->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_draw_ornaments.png'),
);
$toggleButton_drawExitOrnaments->set_label('Draw exit ornaments');
$toggleButton_drawExitOrnaments->set_tooltip_text('Draw exit ornaments');
$toggleButton_drawExitOrnaments->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'drawOrnamentsFlag',
$toggleButton_drawExitOrnaments->get_active(),
TRUE, # Do call $self->redrawRegions
'draw_ornaments',
'icon_draw_ornaments',
);
}
});
push (@buttonList, $toggleButton_drawExitOrnaments);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_draw_ornaments', $toggleButton_drawExitOrnaments);
# Toolbutton for 'no ornament'
my $toolButton_noOrnament = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_no_ornament.png'),
'Set no ornament',
);
$toolButton_noOrnament->set_tooltip_text('Set no ornament');
$toolButton_noOrnament->signal_connect('clicked' => sub {
$self->exitOrnamentCallback('none');
});
push (@buttonList, $toolButton_noOrnament);
# (Requires $self->currentRegionmap & either $self->selectedExit or
# $self->selectedExitHash)
$self->ivAdd('menuToolItemHash', 'icon_no_ornament', $toolButton_noOrnament);
# Separator
my $separator3 = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator3);
# Toolbutton for 'openable exit'
my $toolButton_openableExit = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_openable_exit.png'),
'Set openable exit',
);
$toolButton_openableExit->set_tooltip_text('Set openable exit');
$toolButton_openableExit->signal_connect('clicked' => sub {
$self->exitOrnamentCallback('open');
});
push (@buttonList, $toolButton_openableExit);
# (Requires $self->currentRegionmap & either $self->selectedExit or
# $self->selectedExitHash)
$self->ivAdd('menuToolItemHash', 'icon_openable_exit', $toolButton_openableExit);
# Toolbutton for 'lockable exit'
my $toolButton_lockableExit = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_lockable_exit.png'),
'Set lockable exit',
);
$toolButton_lockableExit->set_tooltip_text('Set lockable exit');
$toolButton_lockableExit->signal_connect('clicked' => sub {
$self->exitOrnamentCallback('lock');
});
push (@buttonList, $toolButton_lockableExit);
# (Requires $self->currentRegionmap & either $self->selectedExit or
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$self->centreMapOverRoom($self->selectedRoom);
});
push (@buttonList, $toolButton_centreSelectedRoom);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd(
'menuToolItemHash',
'icon_centre_map_selected_room',
$toolButton_centreSelectedRoom,
);
# Toolbutton for 'centre map on last known room'
my $toolButton_centreLastKnownRoom = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_centre_last.png'),
'Centre map on last known room',
);
$toolButton_centreLastKnownRoom->set_tooltip_text('Centre map on last known room');
$toolButton_centreLastKnownRoom->signal_connect('clicked' => sub {
$self->centreMapOverRoom($self->mapObj->lastKnownRoom);
});
push (@buttonList, $toolButton_centreLastKnownRoom);
# (Requires $self->currentRegionmap & $self->mapObj->lastknownRoom)
$self->ivAdd(
'menuToolItemHash',
'icon_centre_map_last_known_room',
$toolButton_centreLastKnownRoom,
);
# Toolbutton for 'centre map on middle of grid'
my $toolButton_centreMiddleGrid = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_centre_middle.png'),
'Centre map on middle of grid',
);
$toolButton_centreMiddleGrid->set_tooltip_text('Centre map on middle of grid');
$toolButton_centreMiddleGrid->signal_connect('clicked' => sub {
$self->setMapPosn(0.5, 0.5);
});
push (@buttonList, $toolButton_centreMiddleGrid);
# (Requires $self->currentRegionmap)
$self->ivAdd(
'menuToolItemHash',
'icon_centre_map_middle_grid',
$toolButton_centreMiddleGrid,
);
# Separator
my $separator = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator);
# Toggle button for 'track current room'
my $toggleButton_trackCurrentRoom = Gtk3::ToggleToolButton->new();
$toggleButton_trackCurrentRoom->set_active($self->worldModelObj->trackPosnFlag);
$toggleButton_trackCurrentRoom->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_track_room.png'),
);
$toggleButton_trackCurrentRoom->set_label('Track current room');
$toggleButton_trackCurrentRoom->set_tooltip_text('Track current room');
$toggleButton_trackCurrentRoom->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'trackPosnFlag',
$toggleButton_trackCurrentRoom->get_active(),
FALSE, # Don't call $self->redrawRegions
'track_current_room',
'icon_track_current_room',
);
}
});
push (@buttonList, $toggleButton_trackCurrentRoom);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_track_current_room', $toggleButton_trackCurrentRoom);
# Radio button for 'always track position'
my $radioButton_trackAlways = Gtk3::RadioToolButton->new(undef);
if (
$self->worldModelObj->trackingSensitivity != 0.33
&& $self->worldModelObj->trackingSensitivity != 0.66
&& $self->worldModelObj->trackingSensitivity != 1
) {
# Only the sensitivity values 0, 0.33, 0.66 and 1 are curently allowed; act as
# though the IV was set to 0
$radioButton_trackAlways->set_active(TRUE);
}
$radioButton_trackAlways->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_track_always.png'),
);
$radioButton_trackAlways->set_label('Always track position');
$radioButton_trackAlways->set_tooltip_text('Always track position');
$radioButton_trackAlways->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_trackAlways->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0);
}
});
push (@buttonList, $radioButton_trackAlways);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_track_always', $radioButton_trackAlways);
# Radio button for 'track position near centre'
my $radioButton_trackNearCentre = Gtk3::RadioToolButton->new_from_widget(
$radioButton_trackAlways,
);
if ($self->worldModelObj->trackingSensitivity == 0.33) {
$radioButton_trackNearCentre->set_active(TRUE);
}
$radioButton_trackNearCentre->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_track_centre.png'),
);
$radioButton_trackNearCentre->set_label('Track position near centre');
$radioButton_trackNearCentre->set_tooltip_text('Track position near centre');
$radioButton_trackNearCentre->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_trackNearCentre->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0.33);
}
});
push (@buttonList, $radioButton_trackNearCentre);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_track_near_centre', $radioButton_trackNearCentre);
# Radio button for 'track near edge'
my $radioButton_trackNearEdge = Gtk3::RadioToolButton->new_from_widget(
$radioButton_trackNearCentre,
);
if ($self->worldModelObj->trackingSensitivity == 0.66) {
$radioButton_trackNearEdge->set_active(TRUE);
}
$radioButton_trackNearEdge->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_track_edge.png'),
);
$radioButton_trackNearEdge->set_label('Track position near edge');
$radioButton_trackNearEdge->set_tooltip_text('Track position near edge');
$radioButton_trackNearEdge->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_trackNearEdge->get_active()) {
$self->worldModelObj->setTrackingSensitivity(0.66);
}
});
push (@buttonList, $radioButton_trackNearEdge);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_track_near_edge', $radioButton_trackNearEdge);
# Radio button for 'track if not visible'
my $radioButton_trackNotVisible = Gtk3::RadioToolButton->new_from_widget(
$radioButton_trackNearEdge,
);
if ($self->worldModelObj->trackingSensitivity == 1) {
$radioButton_trackNotVisible->set_active(TRUE);
}
$radioButton_trackNotVisible->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_track_visible.png'),
);
$radioButton_trackNotVisible->set_label('Track if not visible');
$radioButton_trackNotVisible->set_tooltip_text('Track position if not visible');
$radioButton_trackNotVisible->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton_trackNotVisible->get_active()) {
$self->worldModelObj->setTrackingSensitivity(1);
}
});
push (@buttonList, $radioButton_trackNotVisible);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_track_not_visible', $radioButton_trackNotVisible);
return @buttonList;
}
sub drawMiscButtonSet {
# Called by $self->chooseButtonSet, which in turn was called by $self->drawToolbar or
# ->switchToolbarButtons
# Draws buttons for this button set, and adds them to the toolbar
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my @buttonList;
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->drawMiscButtonSet', @_);
}
# Toolbutton for 'increase visits and set current'
my $toolButton_incVisitsCurrent = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file(
$axmud::SHARE_DIR . '/icons/map/icon_inc_visits_current.png',
),
'Increase visits and set current',
);
$toolButton_incVisitsCurrent->set_tooltip_text('Increase visits and set current');
$toolButton_incVisitsCurrent->signal_connect('clicked' => sub {
$self->updateVisitsCallback('increase');
$self->mapObj->setCurrentRoom($self->selectedRoom);
});
push (@buttonList, $toolButton_incVisitsCurrent);
# (Requires $self->currentRegionmap & $self->selectedRoom)
$self->ivAdd('menuToolItemHash', 'icon_inc_visits_current', $toolButton_incVisitsCurrent);
# Toolbutton for 'increase visits by one'
my $toolButton_incVisits = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_inc_visits.png'),
'Increase visits by one',
);
$toolButton_incVisits->set_tooltip_text('Increase visits by one');
$toolButton_incVisits->signal_connect('clicked' => sub {
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
});
push (@buttonList, $toolButton_addQuickWords);
# Toolbutton for 'edit dictionary'
my $toolButton_editDictionary = Gtk3::ToolButton->new(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_edit_dict.png'),
'Edit current dictionary',
);
$toolButton_editDictionary->set_tooltip_text('Edit current dictionary');
$toolButton_editDictionary->signal_connect('clicked' => sub {
# Open an 'edit' window for the current dictionary
$self->createFreeWin(
'Games::Axmud::EditWin::Dict',
$self,
$self->session,
'Edit \'' . $self->session->currentDict->name . '\' dictionary',
$self->session->currentDict,
FALSE, # Not temporary
);
});
push (@buttonList, $toolButton_editDictionary);
return @buttonList;
}
sub drawFlagsButtonSet {
# Called by $self->chooseButtonSet, which in turn was called by $self->drawToolbar or
# ->switchToolbarButtons
# Draws buttons for this button set, and adds them to the toolbar
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my @buttonList;
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->drawFlagsButtonSet', @_);
}
# Toggle button for 'release all filters'
my $radioButton_releaseAllFilters = Gtk3::ToggleToolButton->new();
$radioButton_releaseAllFilters->set_active($self->worldModelObj->allRoomFiltersFlag);
$radioButton_releaseAllFilters->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/icon_all_filters.png'),
);
$radioButton_releaseAllFilters->set_label('Release all filters');
$radioButton_releaseAllFilters->set_tooltip_text('Release all filters');
$radioButton_releaseAllFilters->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFlag(
'allRoomFiltersFlag',
$radioButton_releaseAllFilters->get_active(),
TRUE, # Do call $self->redrawRegions
'release_all_filters',
'icon_release_all_filters',
);
}
});
push (@buttonList, $radioButton_releaseAllFilters);
# (Never desensitised)
$self->ivAdd(
'menuToolItemHash',
'icon_release_all_filters',
$radioButton_releaseAllFilters,
);
# Separator
my $separator = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator);
# Filter icons
foreach my $filter ($axmud::CLIENT->constRoomFilterList) {
# Filter button
my $toolButton_filter = Gtk3::ToggleToolButton->new();
$toolButton_filter->set_active(
$self->worldModelObj->ivShow('roomFilterApplyHash', $filter),
);
$toolButton_filter->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag) {
$self->worldModelObj->toggleFilter(
$filter,
$toolButton_filter->get_active(),
);
}
});
# If it's one of the standard filters, we can use one of the existing icons;
# otherwise, use a spare icon
my $iconFile = $axmud::SHARE_DIR . '/icons/map/icon_' . $filter . '.png';
if (! -e $iconFile) {
$iconFile = $axmud::SHARE_DIR . '/icons/map/icon_spare_filter.png'
}
$toolButton_filter->set_icon_widget(
Gtk3::Image->new_from_file($iconFile)
);
$toolButton_filter->set_label('Toggle ' . $filter . ' filter');
$toolButton_filter->set_tooltip_text('Toggle ' . $filter . ' filter');
push (@buttonList, $toolButton_filter);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_' . $filter . '_filter', $toolButton_filter);
}
return @buttonList;
}
sub drawInteriorsButtonSet {
# Called by $self->chooseButtonSet, which in turn was called by $self->drawToolbar or
# ->switchToolbarButtons
# Draws buttons for this button set, and adds them to the toolbar
#
# Expected arguments
# $toolbar - The toolbar widget on which the buttons are drawn
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $toolbar, $check) = @_;
# Local variables
my (
$lastButton,
@initList, @interiorList, @buttonList,
%interiorHash, %iconHash,
);
# Check for improper arguments
if (! defined $toolbar || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->drawInteriorsButtonSet', @_);
}
@initList = (
'none',
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
'profile_count',
'Draw exclusive profiles',
'icon_draw_exclusive.png',
'title_descrip',
'Draw titles/descriptions',
'icon_draw_descrips.png',
'exit_pattern',
'Draw exit patterns',
'icon_draw_patterns.png',
'source_code',
'Draw room source code',
'icon_draw_code.png',
'vnum',
'Draw world\'s room _vnum',
'icon_draw_vnum.png',
'grid_posn',
'Draw grid position',
'icon_draw_grid_posn.png',
);
do {
my ($mode, $descrip, $icon);
$mode = shift @initList;
$descrip = shift @initList;
$icon = shift @initList;
push (@interiorList, $mode);
$interiorHash{$mode} = $descrip;
$iconHash{$mode} = $icon;
} until (! @initList);
for (my $count = 0; $count < (scalar @interiorList); $count++) {
my ($icon, $mode);
$mode = $interiorList[$count];
# (For $count = 0, $buttonGroup is 'undef')
my $radioButton;
if ($mode eq 'none') {
$radioButton = Gtk3::RadioToolButton->new(undef);
} else {
$radioButton = Gtk3::RadioToolButton->new_from_widget($lastButton);
}
if ($self->worldModelObj->roomInteriorMode eq $mode) {
$radioButton->set_active(TRUE);
}
$radioButton->set_icon_widget(
Gtk3::Image->new_from_file($axmud::SHARE_DIR . '/icons/map/' . $iconHash{$mode}),
);
$radioButton->set_label($interiorHash{$mode});
$radioButton->set_tooltip_text($interiorHash{$mode});
$radioButton->signal_connect('toggled' => sub {
if (! $self->ignoreMenuUpdateFlag && $radioButton->get_active()) {
$self->worldModelObj->switchRoomInteriorMode($mode);
}
});
push (@buttonList, $radioButton);
# (Never desensitised)
$self->ivAdd('menuToolItemHash', 'icon_interior_mode_' . $mode, $radioButton);
$lastButton = $radioButton;
# (Add a separator after the first toolbar button)
if ($mode eq 'none') {
# Separator
my $separator = Gtk3::SeparatorToolItem->new();
push (@buttonList, $separator);
}
}
return @buttonList;
}
sub addRoomFlagButton {
# Called by a ->signal_connect in $self->drawPaintingButtonSet whenever the user clicks the
# 'add room flag' button in the 'painting' button set
# Creates a popup menu containing all room flags, then implements 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 %checkHash;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addRoomFlagButton', @_);
}
# Compile a hash of existing preferred room flags (we don't want the user to add the same
# room flag twice)
foreach my $roomFlag ($self->worldModelObj->preferRoomFlagList) {
$checkHash{$roomFlag} = undef;
}
# Set up the popup menu
my $popupMenu = Gtk3::Menu->new();
if (! $popupMenu) {
return undef;
}
# Add a title menu item, which does nothing
my $title_item = Gtk3::MenuItem->new('Add preferred room flag:');
$title_item->signal_connect('activate' => sub {
return undef;
});
$title_item->set_sensitive(FALSE);
$popupMenu->append($title_item);
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
# Fill the popup menu with room flags
foreach my $filter ($axmud::CLIENT->constRoomFilterList) {
# A sub-sub menu for $filter
my $subSubMenu_filter = Gtk3::Menu->new();
my @nameList = $self->worldModelObj->getRoomFlagsInFilter($filter);
foreach my $name (@nameList) {
my $obj = $self->worldModelObj->ivShow('roomFlagHash', $name);
if ($obj) {
my $menuItem = Gtk3::MenuItem->new($obj->descrip);
$menuItem->signal_connect('activate' => sub {
# Add the room flag to the world model's list of preferred room flags...
$self->worldModelObj->add_preferRoomFlag($name);
# ...then redraw the window component containing the toolbar(s), toggling
# the button for the new room flag
$self->redrawWidgets('toolbar');
});
$subSubMenu_filter->append($menuItem);
}
}
if (! @nameList) {
my $menuItem = Gtk3::MenuItem->new('(No flags in this filter)');
$menuItem->set_sensitive(FALSE);
$subSubMenu_filter->append($menuItem);
}
my $menuItem = Gtk3::MenuItem->new(ucfirst($filter));
$menuItem->set_submenu($subSubMenu_filter);
$popupMenu->append($menuItem);
}
# Also add a 'Cancel' menu item, which does nothing
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $cancel_item = Gtk3::MenuItem->new('Cancel');
$cancel_item->signal_connect('activate' => sub {
return undef;
});
$popupMenu->append($cancel_item);
# Display the popup menu
$popupMenu->popup(
undef, undef, undef, undef,
1, # Left mouse button
Gtk3::get_current_event_time(),
);
$popupMenu->show_all();
# Operation complete. Now wait for the user's response
return 1;
}
sub removeRoomFlagButton {
# Called by a ->signal_connect in $self->drawPaintingButtonSet whenever the user clicks the
# 'remove room flag' button in the 'painting' button set
# Removes the specified room flag from the toolbar and updates IVs
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if there's an error
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->removeRoomFlagButton', @_);
}
# Set up the popup menu
my $popupMenu = Gtk3::Menu->new();
if (! $popupMenu) {
return undef;
}
# Add a title menu item, which does nothing
my $title_item = Gtk3::MenuItem->new('Remove preferred room flag:');
$title_item->signal_connect('activate' => sub {
return undef;
});
$title_item->set_sensitive(FALSE);
$popupMenu->append($title_item);
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
# Fill the popup menu with room flags
foreach my $roomFlag ($self->worldModelObj->preferRoomFlagList) {
my $menu_item = Gtk3::MenuItem->new($roomFlag);
$menu_item->signal_connect('activate' => sub {
# Remove the room flag from the world model's list of preferred room flags...
$self->worldModelObj->del_preferRoomFlag($roomFlag);
# ...and from the painter object iself...
$self->worldModelObj->painterObj->ivDelete('roomFlagHash', $roomFlag);
# ...then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
});
$popupMenu->append($menu_item);
}
# Add a 'remove all' menu item
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $remove_all_item = Gtk3::MenuItem->new('Remove all');
$remove_all_item->signal_connect('activate' => sub {
my ($total, $choice);
$total = scalar $self->worldModelObj->preferRoomFlagList;
# If there's more than one colour, prompt the user for confirmation
if ($total > 1) {
$choice = $self->showMsgDialogue(
'Remove all room flag buttons',
'question',
'Are you sure you want to remove all ' . $total . ' room flag buttons?',
'yes-no',
);
} else {
$choice = 'yes';
}
if (defined $choice && $choice eq 'yes') {
# Reset the world model's list of preferred room flags
$self->worldModelObj->reset_preferRoomFlagList();
# Update the painter object (which might contain room flags not added with these
# tools)
foreach my $roomFlag ($self->worldModelObj->preferRoomFlagList) {
$self->worldModelObj->ivDelete('roomFlagHash', $roomFlag);
}
# Then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
}
});
$popupMenu->append($remove_all_item);
# Also add a 'Cancel' menu item, which does nothing
my $cancel_item = Gtk3::MenuItem->new('Cancel');
$cancel_item->signal_connect('activate' => sub {
return undef;
});
$popupMenu->append($cancel_item);
# Display the popup menu
$popupMenu->popup(
undef, undef, undef, undef,
1, # Left mouse button
Gtk3::get_current_event_time(),
);
$popupMenu->show_all();
# Operation complete. Now wait for the user's response
return 1;
}
sub addBGColourButton {
# Called by a ->signal_connect in $self->drawBackgroundButtonSet whenever the user clicks
# the 'add background colour' button in the 'background' button set
# Prompts the user for a new RGB colour tag, then implements 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 $colour;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addBGColourButton', @_);
}
$colour = $self->showColourSelectionDialogue('Add preferred background colour');
if (defined $colour) {
# Add the room flag to the world model's list of preferred background colours...
$self->worldModelObj->add_preferBGColour($colour);
# ...then redraw the window component containing the toolbar(s), selecting the new
# colour
$self->ivPoke('bgColourChoice', $colour);
$self->redrawWidgets('toolbar');
}
return 1;
}
sub removeBGColourButton {
# Called by a ->signal_connect in $self->drawBackgroundButtonSet whenever the user clicks
# the 'remove background colour' button in the 'background' button set
# Removes the specified colour from the toolbar and updates IVs
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if there's an error
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->removeBGColourButton', @_);
}
# Set up the popup menu
my $popupMenu = Gtk3::Menu->new();
if (! $popupMenu) {
return undef;
}
# Add a title menu item, which does nothing
my $title_item = Gtk3::MenuItem->new('Remove preferred background colour:');
$title_item->signal_connect('activate' => sub {
return undef;
});
$title_item->set_sensitive(FALSE);
$popupMenu->append($title_item);
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
# Fill the popup menu with colours
foreach my $colour ($self->worldModelObj->preferBGColourList) {
my $menu_item = Gtk3::MenuItem->new($colour);
$menu_item->signal_connect('activate' => sub {
# Remove the colour from the world model's list of preferred background colours...
$self->worldModelObj->del_preferBGColour($colour);
# ...then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
});
$popupMenu->append($menu_item);
}
# Add a 'remove all' menu item
$popupMenu->append(Gtk3::SeparatorMenuItem->new()); # Separator
my $remove_all_item = Gtk3::MenuItem->new('Remove all');
$remove_all_item->signal_connect('activate' => sub {
my ($total, $choice);
$total = scalar $self->worldModelObj->preferBGColourList;
# If there's more than one colour, prompt the user for confirmation
if ($total > 1) {
$choice = $self->showMsgDialogue(
'Remove all colour buttons',
'question',
'Are you sure you want to remove all ' . $total . ' colour buttons?',
'yes-no',
);
} else {
$choice = 'yes';
}
if (defined $choice && $choice eq 'yes') {
# Reset the world model's list of preferred background colour...
$self->worldModelObj->reset_preferBGColourList();
# ...then redraw the window component containing the toolbar(s)
$self->redrawWidgets('toolbar');
}
});
$popupMenu->append($remove_all_item);
# Also add a 'Cancel' menu item, which does nothing
my $cancel_item = Gtk3::MenuItem->new('Cancel');
$cancel_item->signal_connect('activate' => sub {
return undef;
});
$popupMenu->append($cancel_item);
# Display the popup menu
$popupMenu->popup(
undef, undef, undef, undef,
1, # Left mouse button
Gtk3::get_current_event_time(),
);
$popupMenu->show_all();
# Operation complete. Now wait for the user's response
return 1;
}
# Treeview widget methods
sub enableTreeView {
# Called by $self->drawWidgets
# Sets up the Automapper window's treeview widget
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the widget can't be created
# Otherwise returns the Gtk3::ScrolledWindow containing the Gtk3::TreeView created
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->enableTreeView', @_);
}
# Create the treeview
my $objectModel = Gtk3::TreeStore->new( ['Glib::String'] );
my $treeView = Gtk3::TreeView->new($objectModel);
if (! $objectModel || ! $treeView) {
return undef;
}
# No interactive searches required
$treeView->set_enable_search(FALSE);
# Append a single column to the treeview
$treeView->append_column(
Gtk3::TreeViewColumn->new_with_attributes(
'Regions',
Gtk3::CellRendererText->new,
markup => 0,
)
);
# Make the treeview scrollable
my $treeViewScroller = Gtk3::ScrolledWindow->new;
$treeViewScroller->add($treeView);
$treeViewScroller->set_policy(qw/automatic automatic/);
# Make the branches of the list tree clickable, so the rows can be expanded and collapsed
$treeView->signal_connect('row_activated' => sub {
my ($treeView, $path, $column) = @_;
$self->treeViewRowActivatedCallback();
});
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
} elsif (! defined $xPosBlocks || ! defined $yPosBlocks) {
# Can't do anything without arguments
return undef;
}
# Convert that position into canvas coordinates, and centre the map at that position
($blockCentreXPosPixels, $blockCentreYPosPixels) = $self->getBlockCentre(
$roomObj->xPosBlocks,
$roomObj->yPosBlocks,
);
$self->setMapPosn(
($blockCentreXPosPixels / $self->currentRegionmap->mapWidthPixels),
($blockCentreYPosPixels / $self->currentRegionmap->mapHeightPixels),
);
return 1;
}
sub doZoom {
# Called by $self->worldModelObj->setMagnification
# Zooms the map in or out, depending on the new value of
# $self->currentRegionmap->magnification
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if no arguments are specified at all
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
@redrawList,
%newHash,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->doZoom', @_);
}
# Set the visible map's size. Each GooCanvas2::Canvas automatically takes care of its
# position, so that the same part of the map is visible in the window
foreach my $canvasWidget ($self->currentParchment->ivValues('canvasWidgetHash')) {
$canvasWidget->set_scale($self->currentRegionmap->magnification);
}
# Sensitise/desensitise menu bar/toolbar items, depending on current conditions
$self->restrictWidgets();
return 1;
}
# Menu bar/toolbar widget sensitisers
sub restrictWidgets {
# Many menu bar and toolbar items can be sensitised, or desensitised, depending on
# conditions
# This function can be called by anything, any time one of those conditions changes, so that
# every menu bar/toolbar item can be sensitised or desensitised correctly
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$regionObj,
@list, @sensitiseList, @desensitiseList, @magList,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->restrictWidgets', @_);
}
# Modified v1.0.150 - anything that requires the current regionmap, also requires
# the character to be logged in (with a handful of exceptions)
# Modified v1.0.363 - we now allow zooming and a few other things from the 'View' menu
# when the character isn't logged in
# Menu items that require a current regionmap AND a logged in character
@list = (
'select', 'unselect_all',
'selected_objs',
'set_follow_mode', 'icon_set_follow_mode',
'screenshots', 'icon_visible_screenshot',
'drag_mode', 'icon_drag_mode',
'graffiti_mode', 'icon_graffiti_mode',
'edit_region',
'edit_regionmap',
'current_region',
'redraw_region',
'recalculate_paths',
'exit_tags',
'exit_options',
'empty_region',
'delete_region',
'add_room',
'add_label_at_click',
'add_label_at_block',
'room_text',
'other_room_features',
'select_label',
'report_region',
'report_visits_2',
'report_guilds_2',
'report_flags_2',
'report_flags_4',
'report_rooms_2',
'report_exits_2',
'report_checked_2',
'reset_locator', 'icon_reset_locator',
);
if ($self->currentRegionmap && $self->session->loginFlag) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap BUT NOT a logged in character
@list = (
'zoom_sub',
'level_sub',
'centre_map_middle_grid', 'icon_centre_map_middle_grid',
'centre_map_sub',
'move_up_level', 'icon_move_up_level',
'move_down_level', 'icon_move_down_level',
'this_region_scheme',
'exit_lengths', 'icon_horizontal_lengths', 'icon_vertical_lengths',
);
if ($self->currentRegionmap) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, GA::Obj::WorldModel->disableUpdateModeFlag
# set to FALSE and a session not in 'connect offline' mode
@list = (
'set_update_mode', 'icon_set_update_mode',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ! $self->worldModelObj->disableUpdateModeFlag
&& $self->session->status ne 'offline'
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap for a region that doesn't have a parent region
@list = (
'move_region_top',
);
if ($self->currentRegionmap) {
$regionObj
= $self->worldModelObj->ivShow('regionModelHash', $self->currentRegionmap->number);
}
if ($regionObj && ! $regionObj->parent) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a current room
@list = (
'centre_map_current_room', 'icon_centre_map_current_room',
'add_room_contents',
'add_hidden_object',
'add_search_result',
'unset_current_room',
'update_locator',
'repaint_current',
'execute_scripts',
'add_failed_room',
'add_involuntary_exit',
'add_repulse_exit',
'add_special_depart',
'add_unspecified_pattern',
'icon_fail_exit',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->mapObj->currentRoom) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected room
@list = (
'centre_map_selected_room', 'icon_centre_map_selected_room',
'set_current_room', 'icon_set_current_room',
'select_exit',
'increase_set_current',
'edit_room',
'set_file_path',
'add_contents_string',
'add_hidden_string',
'add_exclusive_prof',
'icon_inc_visits_current',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->selectedRoom) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and either a single selected room or a single
# selected room tag
@list = (
'set_room_tag',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomTag)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, a current room and a single selected room
# (the current room and selected room shouldn't be the same)
@list = (
'path_finding_highlight',
'path_finding_edit',
'path_finding_go',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->mapObj->currentRoom
&& $self->selectedRoom
&& $self->mapObj->currentRoom ne $self->selectedRoom
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and either a current room or a single selected
# room
@list = (
'add_to_model',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->mapObj->currentRoom || $self->selectedRoom)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected room with one or more
# checked directions
@list = (
'remove_checked', 'remove_checked_all',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedRoom
&& $self->selectedRoom->checkedDirHash
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected room with
# ->sourceCodePath set, but ->virtualAreaPath not set
@list = (
'view_source_code',
'edit_source_code',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedRoom
&& $self->selectedRoom->sourceCodePath
&& ! $self->selectedRoom->virtualAreaPath
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected room with
# ->virtualAreaPath set
@list = (
'view_virtual_area',
'edit_virtual_area',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedRoom
&& $self->selectedRoom->virtualAreaPath
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected room whose ->wildMode
# is not set to 'wild' (the value 'border' is ok, though)
@list = (
'add_normal_exit', 'add_hidden_exit',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedRoom
&& $self->selectedRoom->wildMode ne 'wild'
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, one or more selected rooms and
# $self->graffitiModeFlag set to TRUE
@list = (
'toggle_graffiti', 'icon_toggle_graffiti',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomHash)
&& $self->graffitiModeFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and one or more selected rooms
@list = (
'move_rooms_dir', 'move_rooms_click',
'icon_move_to_click',
'toggle_room_flag_sub',
'reset_positions',
'room_exclusivity', 'room_exclusivity_sub',
'set_exits',
'add_multiple_exits',
'wilderness_normal',
'update_visits',
'delete_room',
'repaint_selected',
'set_virtual_area',
'reset_virtual_area',
'toggle_exclusivity',
'clear_exclusive_profs',
'connect_adjacent',
'icon_inc_visits', 'icon_dec_visits', 'icon_set_visits', 'icon_reset_visits',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomHash)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and either one or more selected rooms or one
# or more selected room guilds (or a mixture of both)
@list = (
'set_room_guild',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& (
$self->selectedRoom || $self->selectedRoomHash || $self->selectedRoomGuild
|| $self->selectedRoomGuildHash
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and EITHER one or more selected rooms OR a
# current room
@list = (
'identify_room',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomHash || $self->mapObj->currentRoom)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, one or more selected rooms and at least two
# regions in the world model
@list = (
'transfer_to_region',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomHash)
&& $self->worldModelObj->ivPairs('regionmapHash') > 1
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, a current room and the automapper object
# being set up to perform a merge operation
@list = (
'move_merge_rooms',
);
if (
$self->currentRegionmap
&& $self->mapObj->currentRoom
&& $self->mapObj->currentMatchFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and EITHER one or more selected rooms OR a
# current room and the automapper being set up to perform a merge)
@list = (
'move_rooms_labels',
);
if (
$self->currentRegionmap
&& (
$self->selectedRoom
|| $self->selectedRoomHash
|| ($self->mapObj->currentRoom && $self->mapObj->currentMatchFlag)
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and an empty
# $self->currentRegionmap->gridRoomHash
@list = (
'add_first_room',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ! $self->currentRegionmap->gridRoomHash
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Meny items that require a current regionmap and a non-empty
# $self->currentRegionmap->gridRoomHash
@list = (
'recalculate_in_region',
'locate_room_in_current',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->currentRegionmap->gridRoomHash
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit
@list = (
'set_exit_dir',
'edit_exit',
'disconnect_exit',
'delete_exit',
'set_exit_type',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->selectedExit) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and one or more selected exits
@list = (
'set_ornament_sub',
'icon_no_ornament', 'icon_openable_exit', 'icon_lockable_exit',
'icon_pickable_exit', 'icon_breakable_exit', 'icon_impassable_exit',
'icon_mystery_exit',
'identify_exit',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedExit || $self->selectedExitHash)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, a single selected exit and
# $self->selectedExit->drawMode is 'temp_alloc' or 'temp_unalloc'
@list = (
'allocate_map_dir',
'allocate_shadow',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& (
$self->selectedExit->drawMode eq 'temp_alloc'
|| $self->selectedExit->drawMode eq 'temp_unalloc'
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, a single selected exit and
# $self->selectedExit->drawMode is 'primary' or 'perm_alloc'
@list = (
'change_direction',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& (
$self->selectedExit->drawMode eq 'primary'
|| $self->selectedExit->drawMode eq 'perm_alloc'
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, a single selected exit and
# $self->selectedExit->drawMode is 'primary', 'temp_unalloc' or 'perm_alloc'
@list = (
'connect_to_click',
'set_assisted_move',
'icon_connect_click',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& $self->selectedExit->drawMode ne 'temp_alloc'
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit which is a broken
# exit
@list = (
'toggle_bent_exit',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& $self->selectedExit->brokenFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit which is a region
# exit
@list = (
'set_super_sub',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& $self->selectedExit->regionFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and either a single selected exit which is a
# region exit, or a single selected exit tag
@list = (
'toggle_exit_tag',
'edit_tag_text',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& (
($self->selectedExit && $self->selectedExit->regionFlag)
|| $self->selectedExitTag
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and one or more selected exits or selected
# exit tags
@list = (
'reset_exit_tags',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& (
$self->selectedExit || $self->selectedExitHash
|| $self->selectedExitTag || $self->selectedExitTagHash
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit which is a
# super-region exit
@list = (
'recalculate_from_exit',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& $self->selectedExit->superFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit which is an
# uncertain exit or a one-way exit
@list = (
'set_exit_twin',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& (
$self->selectedExit->oneWayFlag
|| (
$self->selectedExit->destRoom
&& ! $self->selectedExit->twinExit
&& ! $self->selectedExit->retraceFlag
&& $self->selectedExit->randomType eq 'none'
)
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected exit which is a one-way
# exit
@list = (
'set_incoming_dir',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->selectedExit
&& $self->selectedExit->oneWayFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a single selected label
@list = (
'set_label',
'customise_label',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->selectedLabel) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and one or more selected labels
@list = (
'delete_label',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedLabel || $self->selectedLabelHash)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a selected region (in the treeview)
@list = (
'identify_region',
);
if ($self->treeViewSelectedLine) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, and $self->currentRegionmap->magnification
# to be within a certain range of values
@magList = $self->constMagnifyList;
@list = (
'zoom_out',
);
# (Don't try to zoom out, if already zoomed out to the maximum extent)
if (
$self->currentRegionmap
&& $self->currentRegionmap->magnification > $magList[0]
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
@list = (
'zoom_in',
);
# (Don't try to zoom in, if already zoomed in to the maximum extent)
if (
$self->currentRegionmap
&& $self->currentRegionmap->magnification < $magList[-1]
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and $self->worldModelObj->drawExitMode is
# 'ask_regionmap'
@list = (
'draw_region_exits',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& $self->worldModelObj->drawExitMode eq 'ask_regionmap'
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current character profile
@list = (
'report_visits_3',
);
if ($self->session->currentChar) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a current character profile
@list = (
'report_visits_4',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->session->currentChar) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current guild profile
@list = (
'report_guilds_3',
);
if ($self->session->currentGuild) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap whose ->gridColourBlockHash and/or
# ->gridColourObjHash is not empty)
@list = (
'empty_bg_colours',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& (
$self->currentRegionmap->gridColourBlockHash
|| $self->currentRegionmap->gridColourObjHash
)
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and a current guild profile
@list = (
'report_guilds_4',
);
if ($self->currentRegionmap && $self->session->loginFlag && $self->session->currentGuild) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require assisted moves to be turned on
@list = (
'allow_protected_moves',
'allow_super_protected_moves',
);
if ($self->worldModelObj->assistedMovesFlag) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require protected moves to be turned off
@list = (
'allow_crafty_moves',
);
if (! $self->worldModelObj->protectedMovesFlag) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require basic mapping mode to be turned off
@list = (
'paint_wild', 'icon_paint_wild',
'paint_border', 'icon_paint_border',
);
if (! $self->session->currentWorld->basicMappingFlag) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap, one or more selected rooms and basic mapping
# mode to be turned off
@list = (
'wilderness_wild', 'wilderness_border',
);
if (
$self->currentRegionmap
&& $self->session->loginFlag
&& ($self->selectedRoom || $self->selectedRoomHash)
&& ! $self->session->currentWorld->basicMappingFlag
) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a non-empty list of preferred room flags
@list = (
'icon_remove_room_flag', 'icon_remove_room_flag_2',
);
if ($self->worldModelObj->preferRoomFlagList) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a non-empty list of preferred background colours
@list = (
'icon_bg_remove',
);
if ($self->worldModelObj->preferBGColourList) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap and at least one non-default colour scheme
@list = (
'attach_region_scheme',
);
if ($self->currentRegionmap && $self->worldModelObj->ivPairs('regionSchemeHash') > 1) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require a current regionmap with a non-default region scheme attached
@list = (
'detach_region_scheme',
);
if ($self->currentRegionmap && defined $self->currentRegionmap->regionScheme) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Menu items that require at least one map label style
@list = (
'edit_style',
);
if ($self->worldModelObj->mapLabelStyleHash) {
push (@sensitiseList, @list);
} else {
push (@desensitiseList, @list);
}
# Sensitise and desensitise menu items and toolbar buttons, as required
$self->sensitiseWidgets(@sensitiseList);
$self->desensitiseWidgets(@desensitiseList);
return 1;
}
sub sensitiseWidgets {
# Called by anything. Frequently called by $self->restrictWidgets
# Given a list of Gtk3 widgets (all of them menu/toolbar items), sets them as sensitive
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# @widgetList - A list of widgets - keys in the hash $self->menuToolItemHash
# (e.g. 'move_up_level')
#
# Return values
# 1
my ($self, @widgetList) = @_;
# (No improper arguments to check)
foreach my $widgetName (@widgetList) {
my $widget = $self->ivShow('menuToolItemHash', $widgetName);
if ($widget) {
$widget->set_sensitive(TRUE);
}
}
return 1;
}
sub desensitiseWidgets {
# Called by anything. Frequently called by $self->restrictWidgets
# Given a list of Gtk3 widgets (all of them menu/toolbar items), sets them as insensitive
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# @widgetList - A list of widgets - keys in the hash $self->menuToolItemHash
# (e.g. 'move_up_level')
#
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Can be called by anything, but mostly called by functions in GA::Obj::WorldModel that want
# to set a menu bar or toolbar item as active (or not)
#
# Expected arguments
# $widgetName - The widget's name, a key in the hash $self->menuToolItemHash
#
# Optional arguments
# $flag - Any TRUE value to set the menu bar/toolbar item as active, any FALSE value
# (including 'undef') to set the item as not active
#
# Return values
# 'undef' on improper arguments or if $widgetName doesn't appear in
# $self->menuToolItemHash
# 1 otherwise
my ($self, $widgetName, $flag, $check) = @_;
# Local variables
my $widget;
# Check for improper arguments
if (! defined $widgetName || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setActiveItem', @_);
}
$widget = $self->ivShow('menuToolItemHash', $widgetName);
if (! defined $widget) {
return undef;
} else {
if (! $flag) {
$widget->set_active(FALSE);
} else {
$widget->set_active(TRUE);
}
return 1;
}
}
sub restrictUpdateMode {
# Called by $self->setMode
# Sensitises or desensitises the menu and toolbar buttons that allow the user to switch to
# update mode, depending on the value of GA::Obj::WorldModel->disableUpdateModeFlag and
# GA::Session->status
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($radioMenuItem, $toolbarButton);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->restrictUpdateMode', @_);
}
# Mark the radio/toolbar buttons for 'update mode' as sensitive, or not
$radioMenuItem = $self->ivShow('menuToolItemHash', 'set_update_mode');
$toolbarButton = $self->ivShow('menuToolItemHash', 'icon_set_update_mode');
if ($self->worldModelObj->disableUpdateModeFlag || $self->session->status eq 'offline') {
if ($radioMenuItem) {
$radioMenuItem->set_sensitive(FALSE);
}
if ($toolbarButton) {
$toolbarButton->set_sensitive(FALSE);
}
} else {
if ($radioMenuItem) {
$radioMenuItem->set_sensitive(TRUE);
}
if ($toolbarButton) {
$toolbarButton->set_sensitive(TRUE);
}
}
return 1;
}
# Pause windows handlers
sub showPauseWin {
# Can be called by anything
# Makes the pause window visible (a 'dialogue' window used only by this automapper)
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->showPauseWin', @_);
}
if (! $axmud::CLIENT->busyWin) {
# Show the window widget
$self->showBusyWin(
$axmud::SHARE_DIR . '/icons/system/mapper.png',
'Working...',
);
}
return 1;
}
sub hidePauseWin {
# Can be called by anything
# Makes the pause window invisible
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Continue the drag operation by re-drawing the object(s) at their new position
$self->continueDrag($event, $event->x_root, $event->y_root);
}
});
$canvasObj->signal_connect('enter_notify_event' => sub {
my ($item, $target, $event) = @_;
if ($modelObj && $self->worldModelObj->showTooltipsFlag && ! $self->canvasTooltipObj) {
# Show the tooltips window
$self->showTooltips($type, $canvasObj, $modelObj);
}
});
$canvasObj->signal_connect('leave_notify_event' => sub {
my ($item, $target, $event) = @_;
if (
$modelObj
&& $self->canvasTooltipFlag
&& $self->canvasTooltipObj eq $canvasObj
&& $self->canvasTooltipObjType eq $type
) {
# Hide the tooltips window
$self->hideTooltips();
}
});
# Setup complete
return 1;
}
sub canvasEventHandler {
# Handles events on the map background (i.e. clicking on an empty part of the background
# which doesn't contain a room, room tag, room guild, exit, exit tag, label, or checked
# direction)
# The calling function, an anonymous sub defined in $self->setupCanvasEvent, filters out the
# signals we don't want
# At the moment, the signals let through the filter are:
# button_press, 2button_press, 3button_press, button_release
#
# Expected arguments
# $canvasObj - The canvas object which intercepted an event signal
# $event - The Gtk3::Gdk::Event that caused the signal
#
# Return values
# 'undef' on improper arguments, if there is no region map or if the signal $event is one
# that this function doesn't handle
# 1 otherwise
my ($self, $canvasObj, $event, $check) = @_;
# Local variables
my (
$clickXPosPixels, $clickYPosPixels, $clickType, $button, $shiftFlag, $ctrlFlag,
$clickXPosBlocks, $clickYPosBlocks, $newRoomObj, $roomNum, $roomObj, $exitObj, $listRef,
$result, $twinExitObj, $result2, $popupMenu,
);
# Check for improper arguments
if (! defined $canvasObj || ! defined $event || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->canvasEventHandler', @_);
}
# Don't do anything if there is no current regionmap
if (! $self->currentRegionmap) {
return undef;
}
# In case the previous click on the canvas was a right-click on an exit, we no longer need
# the coordinates of the click
$self->ivUndef('exitClickXPosn');
$self->ivUndef('exitClickYPosn');
# Get the coordinates on the map of the clicked pixel. If the map is magnified we might get
# fractional values, so we need to use int()
($clickXPosPixels, $clickYPosPixels) = (int($event->x), int($event->y));
# For mouse button clicks, get the click type and whether or not the SHIFT and/or CTRL keys
# were held down
($clickType, $button, $shiftFlag, $ctrlFlag) = $self->checkMouseClick($event);
if (! $clickType) {
# Not an event in which we're interested
return undef;
}
# Work out which gridblock is underneath the mouse click
($clickXPosBlocks, $clickYPosBlocks) = $self->findGridBlock(
$clickXPosPixels,
$clickYPosPixels,
$self->currentRegionmap,
);
# If $self->freeClickMode and/or $self->bgColourMode aren't set to 'default', left-clicking
# on empty space causes something unusual to happen
if (
$clickType eq 'single'
&& $button eq 'left'
&& ($self->freeClickMode ne 'default' || $self->bgColourMode ne 'default')
) {
# Free click mode 'add_room' - 'Add room at click' menu option
# (NB If this code is altered, the equivalent code in ->enableCanvasPopupMenu must also
# be altered)
if ($self->freeClickMode eq 'add_room') {
# Only add one new room
$self->reset_freeClickMode();
$newRoomObj = $self->mapObj->createNewRoom(
$self->currentRegionmap,
$clickXPosBlocks,
$clickYPosBlocks,
$self->currentRegionmap->currentLevel,
);
# When using the 'Add room at block' menu item, the new room is selected to make it
# easier to see where it was drawn
# To make things consistent, select this new room, too
$self->setSelectedObj(
[$newRoomObj, 'room'],
FALSE, # Select this object; unselect all other objects
);
# Free click mode 'connect_exit' - 'Connect exit to click' menu option
# Free click mode 'merge_room' - 'Merge/move rooms' menu option
} elsif (
$self->freeClickMode eq 'connect_exit'
|| $self->freeClickMode eq 'merge_room'
) {
# If the user has selected the either of these menu option, $self->freeClickMode has
# been set and we're waiting for a click on a room; since this part of the grid is
# not occupied by a room, we can cancel it now
$self->reset_freeClickMode();
# Free click mode 'add_label' - 'Add label at click' menu option
} elsif ($self->freeClickMode eq 'add_label') {
$self->addLabelAtClickCallback($clickXPosPixels, $clickYPosPixels);
# Only add one new label
$self->reset_freeClickMode();
# Free click mode 'move_room' - 'Move selected rooms to click' menu option
} elsif ($self->freeClickMode eq 'move_room') {
$self->moveRoomsToClick($clickXPosBlocks, $clickYPosBlocks);
# Only do it once
$self->reset_freeClickMode();
# Background colour mode 'square_start' (no menu option)
} elsif ($self->freeClickMode eq 'default' && $self->bgColourMode eq 'square_start') {
$self->setColouredSquare($clickXPosBlocks, $clickYPosBlocks);
# Background colour mode 'rect_start' (no menu option)
} elsif ($self->freeClickMode eq 'default' && $self->bgColourMode eq 'rect_start') {
# Store the coordinates of the click, and wait for the second click
$self->ivPoke('bgColourMode', 'rect_stop');
$self->ivPoke('bgRectXPos', $clickXPosBlocks);
$self->ivPoke('bgRectYPos', $clickYPosBlocks);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$clickXPosPixels,
$clickYPosPixels,
$roomObj,
$self->currentRegionmap,
);
if ($exitObj) {
if ($button eq 'left' && $event->state =~ m/mod5-mask/) {
# This is a drag operation on the nearby exit
$listRef = $self->currentParchment->getDrawnExit($exitObj);
if (defined $listRef) {
$self->startDrag(
'exit',
$$listRef[0], # The exit's canvas object
$exitObj,
$event,
$clickXPosPixels,
$clickYPosPixels,
);
}
} elsif ($button eq 'left') {
# If this exit (and/or its twin) is a selected exit, unselect them
$result = $self->unselectObj($exitObj);
if ($exitObj->twinExit) {
$twinExitObj
= $self->worldModelObj->ivShow('exitModelHash', $exitObj->twinExit);
if ($twinExitObj) {
$result2 = $self->unselectObj($twinExitObj);
}
}
if (! $result && ! $result2) {
# The exit wasn't already selected, so select it
$self->setSelectedObj(
[$exitObj, 'exit'],
# Retain other selected objects if CTRL key held down
$ctrlFlag,
);
}
} elsif ($button eq 'right') {
# Select the exit, unselecting all other selected objects
$self->setSelectedObj(
[$exitObj, 'exit'],
FALSE, # Select this object; unselect all other objects
);
# Create the popup menu
if ($self->selectedExit) {
$popupMenu = $self->enableExitsPopupMenu();
if ($popupMenu) {
$popupMenu->popup(
undef, undef, undef, undef,
$event->button,
$event->time,
);
}
}
}
return 1;
}
}
# Otherwise, the user clicked in open space
# If it was a right-click, open a popup menu
if ($clickType eq 'single' && $button eq 'right') {
$popupMenu = $self->enableCanvasPopupMenu(
$clickXPosPixels,
$clickYPosPixels,
$clickXPosBlocks,
$clickYPosBlocks,
);
if ($popupMenu) {
$popupMenu->popup(
undef, undef, undef, undef,
$event->button,
$event->time,
);
}
# If it was a left-click, it's potentially a selection box operation
} elsif ($clickType eq 'single' && $button eq 'left') {
# The selection box isn't actually drawn until the user moves their mouse. If they
# release the button instead, at that point we unselect all selected objects
$self->startSelectBox($clickXPosPixels, $clickYPosPixels);
# If it's a mouse button release, handle the end of any selection box operation
} elsif ($clickType eq 'release' && $button eq 'left' && $self->selectBoxFlag) {
$self->stopSelectBox($event, $clickXPosPixels, $clickYPosPixels);
# Otherwise, if it's a button click (not a button release), just unselect all selected
# objects
} elsif ($clickType ne 'release') {
$self->setSelectedObj();
}
return 1;
}
sub canvasObjEventHandler {
# Handles events on canvas object (i.e. clicking on a room, room tag, room guild, exit,
# exit tag or label). Note that clicks on canvas objects for checked directions are
# ignored; they are not handled by this function nor by $self->canvasEventHandler
# The calling function, an anonymous sub defined in $self->setupCanvasObjEvent, filters out
# the signals we don't want
# At the moment, the signals let through the filter are:
# button_press, 2button_press
#
# Expected arguments
# $objType - 'room', 'room_tag', 'room_guild', 'exit', 'exit_tag' or 'label'
# $canvasObj - The canvas object which intercepted an event signal
# $modelObj - The GA::ModelObj::Room, GA::Obj::Exit or GA::Obj::MapLabel which is
# represented by this canvas object
# $event - The Gtk3::Gdk::Event that caused the signal
#
# Return values
# 'undef' on improper arguments or if the signal $event is one that this function doesn't
# handle
# 1 otherwise
my ($self, $objType, $canvasObj, $modelObj, $event, $check) = @_;
# Local variables
my (
$clickType, $button, $shiftFlag, $ctrlFlag, $selectFlag, $clickTime, $otherRoomObj,
$startX, $stopX, $startY, $stopY, $result, $twinExitObj, $result2, $popupMenu,
);
# Check for improper arguments
if (
! defined $objType || ! defined $canvasObj || ! defined $modelObj || ! defined $event
|| defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->canvasObjEventHandler', @_);
}
# In case the previous click on the canvas was a right-click on an exit, we no longer need
# the coordinates of the click
$self->ivUndef('exitClickXPosn');
$self->ivUndef('exitClickYPosn');
# If $self->freeClickMode has been set to 'add_room' or 'add_label' by the 'Add room at
# click' or 'Add label at click' menu options, since this part of the grid is already
# occupied, we can go back to normal
if ($self->freeClickMode eq 'add_room' || $self->freeClickMode eq 'add_label') {
$self->reset_freeClickMode();
}
# For mouse button clicks, get the click type and whether or not the SHIFT and/or CTRL keys
# were held down
($clickType, $button, $shiftFlag, $ctrlFlag) = $self->checkMouseClick($event);
if (! $clickType) {
# Not an event in which we're interested
return undef;
}
# Various parts of the function check that these hashes contain at least one item between
# them
if (
$self->selectedRoomHash || $self->selectedRoomTagHash || $self->selectedRoomGuildHash
|| $self->selectedExitHash || $self->selectedExitTagHash || $self->selectedLabelHash
) {
$selectFlag = TRUE;
}
# For capturing double-clicks on rooms, we need to compare the times at which each click is
# received
$clickTime = $axmud::CLIENT->getTime();
# Process single left clicks
if ($clickType eq 'single' && $button eq 'left') {
# Process a left-clicked room differently, if ->freeClickMode has been set to
# 'connect_exit' by the 'Connect to click' menu option (ignoring the SHIFT/CTRL keys)
if ($self->freeClickMode eq 'connect_exit' && $objType eq 'room') {
# Occasionally get an error, when there's no selected exit. $self->freeClickMode
# should get reset, but not in these situations
if (! $self->selectedExit) {
$self->reset_freeClickMode();
} else {
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
}
}
# Process right-clicks
} elsif ($clickType eq 'single' && $button eq 'right') {
if ($objType eq 'exit') {
# For twin exits - which share a canvas object - use the exit whose parent room is
# closest to the click
$modelObj = $self->chooseClickedExit($modelObj, int($event->x), int($event->y));
}
# If a group of things are already selected, unselect them all and select the object
# that was clicked
if ($selectFlag) {
# Select this room/label, unselecting all other objects
$self->setSelectedObj(
[$modelObj, $objType],
# Retain other selected objects if CTRL key held down
$ctrlFlag,
);
} else {
# If this object isn't already selected, select it (but don't unselect something
# as we would for a left-click)
if ($objType eq 'room_tag') {
$self->setSelectedObj(
[$modelObj, 'room_tag'],
FALSE, # Select this object; unselect all other objects
);
} elsif ($objType eq 'room_guild') {
$self->setSelectedObj(
[$modelObj, 'room_guild'],
FALSE, # Select this object; unselect all other objects
);
} elsif ($objType eq 'exit_tag') {
$self->setSelectedObj(
[$modelObj, 'exit_tag'],
FALSE, # Select this object; unselect all other objects
);
} else {
$self->setSelectedObj(
[$modelObj, $objType],
FALSE, # Select this object; unselect all other objects
);
}
}
# Create the popup menu
if ($objType eq 'room' && $self->selectedRoom) {
$popupMenu = $self->enableRoomsPopupMenu();
} elsif ($objType eq 'room_tag' && $self->selectedRoomTag) {
$popupMenu = $self->enableRoomTagsPopupMenu();
} elsif ($objType eq 'room_guild' && $self->selectedRoomGuild) {
$popupMenu = $self->enableRoomGuildsPopupMenu();
} elsif ($objType eq 'exit_tag' && $self->selectedExitTag) {
$popupMenu = $self->enableExitTagsPopupMenu();
} elsif ($objType eq 'exit' && $self->selectedExit) {
# Store the position of the right-click, in case the user wants to add a bend from
# the popup menu
$self->ivPoke('exitClickXPosn', int($event->x));
$self->ivPoke('exitClickYPosn', int($event->y));
# Now we can open the poup menu
$popupMenu = $self->enableExitsPopupMenu();
} elsif ($objType eq 'label' && $self->selectedLabel) {
$popupMenu = $self->enableLabelsPopupMenu();
}
if ($popupMenu) {
$popupMenu->popup(undef, undef, undef, undef, $event->button, $event->time);
}
}
return 1;
}
sub deleteCanvasObj {
# Called by numerous functions
#
# When a region object, room object, room tag, room guild, exit, exit tag or label is being
# drawn, redrawn or deleted from the world model, this function must be called
# The function checks whether the model object is currently drawn on a map as one or more
# canvas objects and, if it is, destroys the canvas objects
#
# This function also handles coloured blocks and rectangles on the background map, details
# of which are stored in the regionmap object (GA::Obj::Regionmap), not the world model
# The function checks whether a canvas object for the coloured block/rectangle is currently
# displayed on the map as a canvas object and, if so, destroys the canvas object
#
# Expected arguments
# $type - Set to 'region', 'room', 'room_tag', 'room_guild', 'exit', 'exit_tag' or
# 'label' for world model objects, 'checked_dir' for checked directions
# and 'square', 'rect' for coloured blocks/rectangles
# $modelObj - The GA::ModelObj::Region, GA::ModelObj::Room, GA::Obj::Exit or
# GA::Obj::MapLabel being drawn /redrawn / deleted
# - For checked directions, the GA::ModelObj::Room in which the checked
# direction is stored
# - For coloured squares, it's not a blessed reference, but a coordinate in
# the form 'x_y' (to delete canvas objects on all levels), or 'x_y_z' (to
# delete the canvas object on one level)
# - For coloured rectangles, it's not a blessed reference, but a key in the
# form 'object-number' (to delete canvas objects on all levels), or
# 'object-number_level' (to delete the canvas object on one level)
#
# Optional arguments
# $regionmapObj, $parchmentObj
# - The regionmap and parchment object for $modelObj. If not set, this
# function fetches them. Both must be specified if $type is 'square' or
# 'rect')
# $deleteFlag - Set to TRUE if the object is being deleted from the world model, FALSE
# (or 'undef') if not. Never TRUE for coloured blocks/rectangles which
# are not stored in the world model
#
# Return values
# 'undef' on improper arguments, if there's an error or if there are no canvas objects to
# destroy
# 1 otherwise
my ($self, $type, $modelObj, $regionmapObj, $parchmentObj, $deleteFlag, $check) = @_;
# Local variables
my (
$roomObj,
@redrawList,
%redrawHash,
);
# Check for improper arguments
if (! defined $type || ! defined $modelObj || defined $check) {
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Expected arguments
# $clickRoomObj - The room that was left-clicked by the user
#
# Return values
# 'undef' on improper arguments or if none of the buttons in the quick painting toolbar
# are selected
# 1 otherwise
my ($self, $clickRoomObj, $check) = @_;
# Local variables
my @roomList;
# Check for improper arguments
if (! defined $clickRoomObj || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->doQuickPaint', @_);
}
# Do nothing if none of the colour buttons in the quick painting toolbar are selected
if (! $self->toolbarQuickPaintColour) {
return undef;
}
# If the room is a selected room, room flags should be toggled in all rooms
if (
($self->selectedRoom && $self->selectedRoom eq $clickRoomObj)
|| $self->ivExists('selectedRoomHash', $clickRoomObj->number)
) {
push (@roomList, $self->compileSelectedRooms());
} else {
# Just toggle room flags in the clicked room
push (@roomList, $clickRoomObj);
}
# Toggle the room flag in those rooms
$self->worldModelObj->toggleRoomFlags(
$self->session,
TRUE, # Update automapper windows
$self->toolbarQuickPaintColour,
@roomList,
);
if (! $self->worldModelObj->quickPaintMultiFlag) {
# User wants the choice of room flag to reset after clicking on a room
$self->ivUndef('toolbarQuickPaintColour');
}
return 1;
}
sub doMerge {
# Called by $self->canvasEventHandler when a double-click is detected on the current room
# and the automapper object is set up to perform a merge (i.e.
# GA::Map::Obj->currentMatchFlag is TRUE)
# Also called by $self->enableRoomsColumnm ->enableRoomsPopupMenu and
# ->canvasObjEventHandler
#
# Prepares a call to GA::Obj::WorldModel->mergeMap, then makes the call
#
# Expected arguments
# $currentRoomObj - The room that is definitely to be merged with another room (at the
# moment, it's always the automapper object's current room)
#
# Optional arguments
# $targetRoomObj - When called by $self->canvasObjEventHandler, because
# GA::Obj::Map->currentMatchList specifies several rooms that match
# the current room, then this variable is the room that was clicked
# $noConfirmFlag - TRUE if the confirmation dialogue window should not be shown; FALSE
# (or 'undef') if it should be shown as usual
#
# Return values
# 'undef' on improper arguments, if the user declines to perform the operation after a
# prompt or if the merge operation fails
# 1 otherwise
my ($self, $currentRoomObj, $targetRoomObj, $noConfirmFlag, $check) = @_;
# Local variables
my (
$autoRescueFlag, $regionmapObj, $response,
@selectList, @otherRoomList, @labelList,
);
# Check for improper arguments
if (! defined $currentRoomObj || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->doMerge', @_);
}
if ($self->mapObj->ivNumber('currentMatchList') > 1 && ! $targetRoomObj) {
# GA::Obj::Map->currentMatchList specifies multiple rooms which match the current
# room (which are all selected), so allow the user to click on one of those rooms,
# after which this function is called again by $self->canvasObjEventHandler
$self->set_freeClickMode('merge_room');
# After a double-click on the current room, none of the matching rooms will be selected,
# so select them again
if (! $self->selectedRoom && ! $self->selectedRoomHash) {
foreach my $roomObj ($self->mapObj->currentMatchList) {
push (@selectList, $roomObj, 'room');
}
$self->setSelectedObj(\@selectList, TRUE);
}
} else {
# If $targetRoomObj was set by the calling function, then GA::Obj::Map->currentMatchList
# specifies multiple rooms which match the current room, and the user has clicked one
# of them
if (! $targetRoomObj) {
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
if ($modelObj->destRoom) {
$destRoomObj = $self->worldModelObj->ivShow('modelHash', $modelObj->destRoom);
$label .= "\n Destination room #" . $destRoomObj->number;
}
if ($modelObj->twinExit) {
$twinExitObj = $self->worldModelObj->ivShow('exitModelHash', $modelObj->twinExit);
$label .= "\n Twin exit #" . $twinExitObj->number . " \'" . $twinExitObj->dir
. "\'";
}
if (defined $modelObj->altDir) {
$label .= "\n Alternative directions:\n " . $modelObj->altDir;
}
if ($modelObj->exitInfo) {
$label .= "\n Info: " . $modelObj->exitInfo;
}
} elsif ($type eq 'exit_tag') {
$label = "Exit tag \'" . $modelObj->exitTag . "\'";
$label .= "\n Exit #" . $modelObj->number . " \'" . $modelObj->dir . "\'";
} elsif ($type eq 'label') {
$label = "Label #" . $modelObj->number;
# Convert the label's coordinates in pixels to gridblocks
$xPos = int($modelObj->xPosPixels / $self->currentRegionmap->blockWidthPixels);
$yPos = int($modelObj->yPosPixels / $self->currentRegionmap->blockHeightPixels);
$label .= " (" . $xPos . ", " . $yPos . ", " . $modelObj->level . ")";
if (! defined $modelObj->style) {
$label .= "\nStyle: <custom>";
} else {
$label .= "\nStyle: \'" . $modelObj->style . "\'";
}
# (The text can include a lot of empty space and newline characters, so strip all of
# that)
$modText = $modelObj->name;
$modText =~ s/^[\s\n]*//;
$modText =~ s/[\s\n]*$//;
$modText =~ s/[\s\n]+/ /g;
$label .= "\nText: \'" . $modText . "\'";
} else {
# Failsafe: empty string
$label = "";
}
return $label;
}
# Menu 'File' column callbacks
sub importModelCallback {
# Called by $self->enableFileColumn
# Imports a world model file specified by the user and (if successful) loads it into memory
# (a combination of ';importfiles' and ';load -m')
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->importModelCallback', @_);
}
# (No standard callback checks for this function)
# Watch out for file operation failures
$axmud::CLIENT->set_fileFailFlag(FALSE);
# Allow a world model, associated with a world profile with a different name, to be imported
# into the current world's file structures (but only if the archive file contains only a
# world model)
$self->session->set_transferWorldModelFlag(TRUE);
# Import a file, specified by the user
if (
$self->session->pseudoCmd('importfiles')
&& ! $axmud::CLIENT->fileFailFlag
) {
# The world model data has been incorporated into Axmud's data files, but not loaded
# into memory. Load it into memory now
if (
$self->session->pseudoCmd('load -m')
&& ! $axmud::CLIENT->fileFailFlag
) {
# Make sure the world model object has the right parent world set, after the file
# import
$self->session->worldModelObj->{_parentWorld} = $self->session->currentWorld->name;
# Save the world model, to make sure the file has the right parent world set, too
$self->session->pseudoCmd('save -f -m');
}
}
# Reset the flag
$self->session->set_transferWorldModelFlag(FALSE);
return 1;
}
sub exportModelCallback {
# Called by $self->enableFileColumn
# Saves the current world model and (if successful) exports the 'worldmodel' file to a
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($fileObj, $choice);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->exportModelCallback', @_);
}
# (No standard callback checks for this function)
# If the world model data in memory is unsaved, prompt whether to save it first
$fileObj = $self->session->ivShow('sessionFileObjHash', 'worldmodel');
if ($fileObj && $fileObj->modifyFlag) {
# Watch out for file operation failures
$axmud::CLIENT->set_fileFailFlag(FALSE);
# Prompt the user
$choice = $self->showMsgDialogue(
'Unsaved world model',
'question',
'The world model in memory is not saved. Do you want to save it before exporting?'
. ' (If you choose \'No\', the previously saved world model file will be exported'
. ' instead)',
'yes-no',
);
if ($choice eq 'yes') {
# Save the world model
$self->session->pseudoCmd('save -m', 'win_error');
if ($axmud::CLIENT->fileFailFlag) {
# Something went wrong; don't attempt to export anything
return 1;
}
}
}
# Export the world model data file
$self->session->pseudoCmd(
'exportfiles -m ' . $self->session->currentWorld->name,
'win_error',
);
return 1;
}
# Menu 'Edit' column callbacks
sub selectInRegionCallback {
# Called by $self->enableEditColumn
# Selects rooms, exits, room tags, room guilds or labels (or everything) in the current
# region
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# $type - Set to 'room', 'exit', 'room_tag', 'room_guild', or 'label'. If not defined,
# selects everything
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $type, $check) = @_;
# Local variables
my (
$count,
@roomList, @exitList, @roomTagList, @roomGuildList, @labelList,
%roomHash, %exitHash, %roomTagHash, %roomGuildHash, %labelHash,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->selectInRegionCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap) {
return undef;
}
# Make sure there are no rooms, exits, room tags or labels selected
$self->ivUndef('selectedRoom');
$self->ivEmpty('selectedRoomHash');
$self->ivUndef('selectedExit');
$self->ivEmpty('selectedExitHash');
$self->ivUndef('selectedRoomTag');
$self->ivEmpty('selectedRoomTagHash');
$self->ivUndef('selectedRoomGuild');
$self->ivEmpty('selectedRoomGuildHash');
$self->ivUndef('selectedLabel');
$self->ivEmpty('selectedLabelHash');
# Select all rooms, exits, room tags, room guilds and/or labels
if (! defined $type || $type eq 'room') {
# $self->currentRegionmap->gridRoomHash contains all the rooms in the regionmap
# Get a list of world model numbers for each room
@roomList = $self->currentRegionmap->ivValues('gridRoomHash');
}
if (! defined $type || $type eq 'exit') {
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
my $roomObj = $self->worldModelObj->ivShow('modelHash', $roomNum);
$roomCount++;
foreach my $char ($roomObj->ivKeys('visitHash')) {
my $profObj = $self->session->ivShow('profHash', $char);
if (! $profObj || $profObj->category ne 'char') {
# The character which visited this room no longer exists as a character
# profile
$self->worldModelObj->resetVisitCount(
TRUE, # Update Automapper windows now
$roomObj,
$char,
);
$deleteCount++;
}
}
}
}
# Deal with profile characters
} else {
foreach my $regionmapObj (@regionList) {
foreach my $roomNum ($regionmapObj->ivValues('gridRoomHash')) {
my $roomObj = $self->worldModelObj->ivShow('modelHash', $roomNum);
$roomCount++;
foreach my $char (@charList) {
if ($roomObj->ivExists('visitHash', $char)) {
# Remove this character's visits from the room
$self->worldModelObj->resetVisitCount(
TRUE, # Update Automapper windows now
$roomObj,
$char,
);
$deleteCount++;
}
}
}
}
}
# Show confirmation
return $self->showMsgDialogue(
'Reset character visits',
'info',
'Operation complete (rooms: ' . $roomCount . ', records deleted: ' . $deleteCount . ')',
'ok',
);
}
# Menu 'View' column callbacks
sub changeCharDrawnCallback {
# Called by $self->enableViewColumn
# In GA::Obj::WorldModel->roomInteriorMode 'visit_count', changes which character's visits
# are drawn
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$currentString, $choice, $redrawFlag, $choiceObj,
@profList, @sortedList, @comboList,
%comboHash,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->changeCharDrawnCallback',
@_,
);
}
# (No standard callback checks for this function)
# Get a sorted list of character profiles, not including the current character (if any)
foreach my $profObj ($self->session->ivValues('profHash')) {
if (
$profObj->category eq 'char'
&& (! $self->session->currentChar || $self->session->currentChar ne $profObj)
) {
push (@profList, $profObj);
}
}
@sortedList = sort {lc($a->name) cmp lc($b->name)} (@profList);
# Prepare a list to show in a combo box. At the same time, compile a hash in the form:
# $hash{combo_box_string} = blessed_reference_of_equivalent_profile
foreach my $profObj (@sortedList) {
push (@comboList, $profObj->name);
$comboHash{$profObj->name} = $profObj;
}
# Add the current character (if there is one) to top of the combo
if ($self->session->currentChar) {
$currentString = '<Use current character>';
unshift (@comboList, $currentString);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Set the new magnification; the called function updates every Automapper window using the
# current worldmodel
$self->worldModelObj->setMagnification($self, $newMag);
return 1;
}
sub changeLevelCallback {
# Called by $self->enableViewColumn
# Prompts the user for a new level in the current regionmap, then sets it as the currently-
# displayed level
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $level;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->changeLevelCallback', @_);
}
# (No standard callback checks for this function)
# Prompt the user for a new level
$level = $self->showEntryDialogue(
'Change level',
'Enter the new level number (\'ground\' level is 0)',
);
if (defined $level) {
# Check that $level is a valid integer (positive, negative or 0)
if (! ($level =~ m/^-?\d+$/)) {
return $self->showMsgDialogue(
'Change level',
'error',
'Invalid level \'' . $level . '\' - you must use an integer',
'ok',
);
}
# Set the new current level, which redraws the map
$self->setCurrentLevel($level);
}
return 1;
}
# Menu 'Mode' column callbacks
sub verboseCharsCallback {
# Called by $self->enableModeColumn
# Sets the number of characters at the beginning of a verbose description that are checked
# to match a world model room with the Locator's current room
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $number;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->verboseCharsCallback', @_);
}
# (No standard callback checks for this function)
# Prompt for a new number of verbose characters to match
$number = $self->showEntryDialogue(
'Match verbose description',
'Enter number of initial characters to match (0 = match whole description)',
undef,
$self->worldModelObj->matchDescripCharCount,
);
if ($axmud::CLIENT->intCheck($number, 0)) {
$self->worldModelObj->set_matchDescripCharCount($number);
}
return 1;
}
sub repaintSelectedRoomsCallback {
# Called by $self->enableModeColumn
# 'Repaints' the selected room(s) by copying the values of certain IVs stored in the world
# model's painter object (a non-model GA::ModelObj::Room) to each selected room
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (@roomList, @redrawList);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Prompt for a new maximum
$number = $self->showEntryDialogue(
'Set limit on room comparisons',
'When comparing the Locator task\'s current room against rooms in the model, set the'
. ' maximum number of rooms to compare (0 - no limit)',
undef,
$self->worldModelObj->autoCompareMax,
);
if ($axmud::CLIENT->intCheck($number, 0)) {
$self->worldModelObj->set_autoCompareMax($number);
}
return 1;
}
sub autoSlideMaxCallback {
# Called by $self->enablemodecolumn
# Sets the maximum distance for auto-slide operations
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $number;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->autoSlideMaxCallback', @_);
}
# (No standard callback checks for this function)
# Prompt for a new maximum
$number = $self->showEntryDialogue(
'Set limit on slide distance',
'When sliding a new room into an unoccupied gridblock, set the maximum slide distance'
. ' (minimum value: 1)',
undef,
$self->worldModelObj->autoSlideMax,
);
if ($axmud::CLIENT->intCheck($number, 1)) {
$self->worldModelObj->set_autoSlideMax($number);
}
return 1;
}
# Menu 'Regions' column callbacks
sub newRegionCallback {
# Called by $self->enableRegionsColumn
# Adds a new region to the world model
#
# Expected arguments
# $tempFlag - If set to TRUE, the new region is a temporary region (that should be
# deleted, the next time the world model is loaded from file)
#
# Return values
# 'undef' on improper arguments, if the new model object can't be created or if the user
# cancels the operation
# 1 otherwise
my ($self, $tempFlag, $check) = @_;
# Local variables
my (
$successFlag, $name, $parentName, $width, $height, $parentNumber, $regionObj, $title,
$regionmapObj,
);
# Check for improper arguments
if (! defined $tempFlag || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->newRegionCallback', @_);
}
# (No standard callback checks for this function)
# Prompt the user for a region name, parent region name and map size
($successFlag, $name, $parentName, $width, $height) = $self->promptNewRegion($tempFlag);
if (! $successFlag) {
# User cancelled the operation
return undef;
} else {
# Check the name is not already in use
if (defined $name && $self->worldModelObj->ivExists('regionmapHash', $name)) {
if ($tempFlag) {
$title = 'New temporary region';
} else {
$title = 'New region';
}
$self->showMsgDialogue(
$title,
'error',
'There is already a region called \'' . $name . '\'',
'ok',
);
return undef;
}
# If a parent was specified, find its world model number
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
'The world model doesn\'t contain any temporary regions',
'ok',
);
return undef;
} else {
# Give the user a chance to change their minds, before emptying the region
if (@tempList == 1) {
$msg = 'There is 1 temporary region in the world model. Are you sure you want to'
. ' delete it?';
} else {
$msg = 'There are ' . scalar @tempList . ' temporary regions in the world model.'
. ' Are you sure you want to delete them all?'
}
$result = $self->showMsgDialogue(
'Delete temporary regions',
'question',
$msg,
'yes-no',
);
if ($result ne 'yes') {
return undef;
}
}
# Work out roughly how many rooms and labels will be deleted. If it's a lot, show a pause
# window
$total = 0;
foreach my $regionObj (@tempList) {
my $regionmapObj = $self->worldModelObj->ivShow('regionmapHash', $regionObj->name);
$total += $regionmapObj->ivPairs('gridRoomHash');
$total += $regionmapObj->ivPairs('gridLabelHash');
}
if ($total > $self->worldModelObj->drawPauseNum) {
$self->showPauseWin();
}
# Delete each temporary region in turn
$self->worldModelObj->deleteTempRegions(
$self->session,
TRUE, # Update Automapper windows now
);
# Make the pause window invisible
$self->hidePauseWin();
return 1;
}
# Menu 'Rooms' column callbacks
sub resetLocatorCallback {
# Called by $self->enableRoomsColumn
# Resets the Locator task, and marks the automapper as lost
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->resetLocatorCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap) {
return undef;
}
# Reset the Locator task
$self->session->pseudoCmd('resetlocatortask', $self->pseudoCmdMode);
# The call to ;resetlocatortask should mark the automapper as lost - but, if it's not, do it
# from here
if ($self->mapObj->currentRoom) {
return $self->mapObj->setCurrentRoom();
}
# Display an explanatory message, if necessary
if ($self->worldModelObj->explainGetLostFlag) {
$self->session->writeText('MAP: Lost because of a Locator reset');
}
return 1;
}
sub setFacingCallback {
# Called by $self->enableRoomsColumn
# Sets the direction the character is facing
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# (For convenience, put the longest directions at the end)
@longList = qw(
north northeast east southeast south southwest west northwest up down
northnortheast eastnortheast eastsoutheast southsoutheast
southsouthwest westsouthwest westnorthwest northnorthwest
);
if ($self->worldModelObj->showAllPrimaryFlag) {
@dirList = @longList;
} else {
@dirList = @shortList;
}
# Get a list of (custom) primary directions, in the standard order
foreach my $key (@dirList) {
push (@customList, $dictObj->ivShow('primaryDirHash', $key));
}
# Prompt the user for a distance and a direction
($distance, $choice) = $self->showEntryComboDialogue(
'Move selected rooms',
'Enter a distance (in gridblocks)',
'Select the direction of movement',
\@customList,
);
# If the 'cancel' button was clicked, $distance will be 'undef'. The user might also have
# entered the distance 0. In either case, we don't move anything
if (! $distance) {
# Operation cancelled
return undef;
} else {
# Check that the distance is a positive integer
if (! $axmud::CLIENT->intCheck($distance, 1)) {
# Open a 'dialogue' window to explain the problem
$self->showMsgDialogue(
'Move selected rooms',
'error',
'The distance must be a positive integer',
'ok',
);
return undef;
}
# $dir is a custom primary direction; convert it into the standard primary direction
$standardDir = $dictObj->ivShow('combRevDirHash', $choice);
# Move the selected room(s)
return $self->moveRoomsInDir($distance, $standardDir);
}
}
sub transferSelectedRoomsCallback {
# Called by $self->enableEditColumn and ->enableRoomsPopupMenu
# Transfers the selected rooms (and any selected labels, if there is at least one selected
# room) to the same location in a specified region
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# $regionName - The name of the region into which the rooms/labels should be
# transferred. All selected rooms/labels must be in the same region,
# and that region must not be the same as $regionName. If 'undef', the
# user is prompted to select a region
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the move
# operation fails
# 1 otherwise
my ($self, $regionName, $check) = @_;
# Local variables
my @comboList;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->transferSelectedRoomsCallback',
@_,
);
}
# Standard callback check
if (! $self->currentRegionmap || (! $self->selectedRoom && ! $self->selectedRoomHash)) {
return undef;
}
# Make sure any free click mode operations, like connecting exits or moving rooms, are
# cancelled
$self->reset_freeClickMode();
# Prompt the user to select a region, if no region was specified by the calling function
if (! defined $regionName) {
# Get a sorted list of region names
@comboList = sort {lc($a) cmp lc($b)} ($self->worldModelObj->ivKeys('regionmapHash'));
# Prompt the user for a region name
$regionName = $self->showComboDialogue(
'Select region',
'Select the destination region',
\@comboList,
);
if (! defined $regionName) {
return undef;
}
}
# Move the selected rooms/labels
return $self->transferRoomsToRegion($regionName);
}
sub compareRoomCallback {
# Called by $self->->enableRoomsPopupMenu
# Compares the selected room with rooms in the region or the whole world model, and selects
# any matching rooms
#
# Expected arguments
# $wholeFlag - FALSE to compare rooms in the same region, TRUE to compare rooms in the
# whole world model
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the move
# operation fails
# 1 otherwise
my ($self, $wholeFlag, $check) = @_;
# Local variables
my (
$wmObj, $selectObj, $regionmapObj, $string,
@roomList, @matchList, @selectList,
);
# Check for improper arguments
if (! defined $wholeFlag || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->compareRoomCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || ! $self->selectedRoom) {
return undef;
}
# Import the world model object and the selected room (for speed)
$wmObj = $self->worldModelObj;
$selectObj = $self->selectedRoom;
# Get a list of rooms which should be compared with the selected room
if (! $wholeFlag) {
$regionmapObj = $self->findRegionmap($self->selectedRoom->parent);
foreach my $roomNum ($regionmapObj->ivValues('gridRoomHash')) {
push (@roomList, $wmObj->ivShow('modelHash', $roomNum));
}
} else {
push (@roomList, $wmObj->ivValues('roomModelHash'));
}
# Compare rooms in each region, one by one
foreach my $thisObj (@roomList) {
my $result;
if ($thisObj ne $selectObj) {
($result) = $wmObj->compareRooms($self->session, $selectObj, $thisObj);
if ($result) {
push (@matchList, $thisObj);
push (@selectList, $thisObj, 'room');
}
}
}
if (! @matchList) {
# Show a confirmation
return $self->showMsgDialogue(
'Compare room',
'error',
'No matching rooms found',
'ok',
);
} else {
# Unselect the currently-selected room...
$self->setSelectedObj();
# ...so we can select all matching rooms. The TRUE argument means to select multiple
# objects
$self->setSelectedObj(\@selectList, TRUE);
if ((scalar @matchList) == 1) {
$string = '1 room';
} else {
$string = (scalar @matchList) . ' rooms';
}
# Show a confirmation
return $self->showMsgDialogue(
'Compare room',
'info',
'Found ' . $string . ' matching room #' . $selectObj->number,
'ok',
);
}
}
sub executeScriptsCallback {
# Called by $self->enableRoomsPopupMenu
# Executes Axbasic scripts for the current room, as if the character had just arrived
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->executeScriptsCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || ! $self->mapObj->currentRoom) {
return undef;
}
# If there are no Axbasic scripts for the current room, display a warning
if (! $self->mapObj->currentRoom->arriveScriptList) {
return $self->showMsgDialogue(
'Run ' . $axmud::BASIC_NAME . ' scripts',
'warning',
'The current room has not been assigned any ' . $axmud::BASIC_NAME . ' scripts',
'ok',
);
}
# Otherwise, execute the scripts
foreach my $scriptName ($self->mapObj->currentRoom->arriveScriptList) {
$self->session->pseudoCmd('runscript ' . $scriptName);
}
return 1;
}
sub addFirstRoomCallback {
# Called by $self->enableRoomsColumn. Also called by Axbasic ADDFIRSTROOM function
# For an empty region, draws a room in the centre of the grid and marks it as the current
# room
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails, if the Locator task
# isn't running or if it is still expecting room statements or if the new room can't
# be created
# 1 otherwise
my ($self, $check) = @_;
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
'Failed to add one or more exits (internal error)',
'ok',
);
return undef;
}
# Mark it as a hidden exit, if necessary
if ($hiddenFlag) {
$self->worldModelObj->setHiddenExit(
FALSE, # Don't redraw the map yet...
$exitObj,
TRUE, # Exit is now hidden
);
}
# Mark the room to be redrawn
push (@drawList, 'room', $roomObj);
# Now, if there are any incoming 1-way exits whose ->mapDir is the opposite
# of the exit we've just added, the incoming exit should be marked as an
# uncertain exit
$self->worldModelObj->modifyIncomingExits(
$self->session,
TRUE, # Redraw any modified incoming exit
$roomObj,
$exitObj,
);
}
}
}
# Redraw the selected room(s) in every window
$self->worldModelObj->updateMaps(@drawList);
return 1;
} else {
# No exits were selected
return undef;
}
}
sub addFailedExitCallback {
# Called by $self->enableRoomsColumn
# When the character fails to move, and it's not a recognised failed exit pattern, the map
# gets messed up
# This is a convenient way to deal with it. Adds a new failed exit string to the current
# world profile or to the specified room, and empties the Locator's move list
#
# Expected arguments
# $worldFlag - If set to TRUE, a failed exit pattern is added to the world profile. If
# set to FALSE, the pattern is added to the room
#
# Optional arguments
# $roomObj - If $worldFlag is FALSE, the room to which the pattern should be added.
# When called by $self->enableRoomsColumn, it will be the current room;
# when called by ->enableRoomsPopupMenu, it will be the selected room
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# doesn't supply a pattern
# 1 otherwise
my ($self, $worldFlag, $roomObj, $check) = @_;
# Local variables
my (
$pattern, $type, $worldObj, $iv, $descrip, $taskObj,
@comboList,
);
# Check for improper arguments
if (! defined $worldFlag || (! $worldFlag && ! defined $roomObj) || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addFailedExitCallback', @_);
}
# Standard callback check
if (
$roomObj
&& (
! $self->currentRegionmap
|| (! $self->mapObj->currentRoom && ! $self->selectedRoom)
)
) {
return undef;
}
if (! $worldFlag) {
# Prompt the user for a new failed exit pattern to add to the room
$pattern = $self->showEntryDialogue(
'Add failed exit to room',
'Enter a pattern to match the failed exit',
);
if (! $pattern) {
return undef;
} else {
$self->worldModelObj->addExitPattern($roomObj, 'fail', $pattern);
}
} else {
# Import the current world profile
$worldObj = $self->session->currentWorld;
# Prompt the user for a new failed exit pattern to add to the world profile
@comboList = ('Closed door', 'Locked door', 'Other failed exit');
($pattern, $type) = $self->showEntryComboDialogue(
'Add failed exit to world',
'Enter a pattern to match the failed exit',
'Which kind of failed exit was it?',
\@comboList,
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
return undef;
} else {
# Check that the pattern isn't already in the list
if ($type eq 'Closed door') {
$iv = 'doorPatternList';
$descrip = 'a closed door pattern';
} elsif ($type eq 'Locked door') {
$iv = 'lockedPatternList';
$descrip = 'a locked door pattern';
} else {
$iv = 'failExitPatternList';
$descrip = 'a failed exit pattern';
}
if ($worldObj->ivMatch($iv, $pattern)) {
$self->showMsgDialogue(
'Add failed exit to world',
'error',
'The current world profile already has ' . $descrip . ' pattern matching \''
. $pattern . '\'',
'ok',
);
return undef;
} else {
# Add the pattern
$worldObj->ivPush($iv, $pattern);
}
}
}
# Import the Locator task
$taskObj = $self->session->locatorTask;
if ($taskObj) {
# Empty the Locator's move list IVs and update its task window
$taskObj->resetMoveList();
}
return 1;
}
sub addInvoluntaryExitCallback {
# Called by $self->enableRoomsColumn
# This callback adds an involuntary exit pattern to the specified room and empties the
# Locator task's move list
#
# Expected arguments
# $roomObj - The room to which the pattern should be added. When called by
# $self->enableRoomsColumn, it will be the current room; when called by
# ->enableRoomsPopupMenu, it will be the selected room
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# doesn't supply a pattern
# 1 otherwise
my ($self, $roomObj, $check) = @_;
# Local variables
my ($pattern, $otherVal, $taskObj);
# Check for improper arguments
if (! defined $roomObj || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addInvoluntaryExitCallback',
@_,
);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (! $self->mapObj->currentRoom && ! $self->selectedRoom)
) {
return undef;
}
# Prompt the user for a new involuntary exit pattern to add to the room
($pattern, $otherVal) = $self->showDoubleEntryDialogue(
'Add involuntary exit to room',
'Enter a pattern to match the involuntary exit',
'(Optional) add a direction or a destination room',
);
if (! defined $pattern || $pattern eq '') {
return undef;
} else {
# Use 'undef' rather than an empty string
if ($otherVal eq '') {
$otherVal = undef;
}
$self->worldModelObj->addInvoluntaryExit($roomObj, $pattern, $otherVal);
# Import the Locator task
$taskObj = $self->session->locatorTask;
if ($taskObj) {
# Empty the Locator's move list IVs and update its task window
$taskObj->resetMoveList();
}
}
return 1;
}
sub addRepulseExitCallback {
# Called by $self->enableRoomsColumn
# This callback adds a repulse exit pattern to the specified room and empties the Locator
# task's move list
#
# Expected arguments
# $roomObj - The room to which the pattern should be added. When called by
# $self->enableRoomsColumn, it will be the current room; when called by
# ->enableRoomsPopupMenu, it will be the selected room
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# doesn't supply a pattern
# 1 otherwise
my ($self, $roomObj, $check) = @_;
# Local variables
my ($pattern, $otherVal, $taskObj);
# Check for improper arguments
if (! defined $roomObj || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addRepulseExitCallback',
@_,
);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (! $self->mapObj->currentRoom && ! $self->selectedRoom)
) {
return undef;
}
# Prompt the user for a new repulse exit pattern to add to the room
($pattern, $otherVal) = $self->showDoubleEntryDialogue(
'Add repulse exit to room',
'Enter a pattern to match the repulse exit',
'(Optional) add a direction or a destination room',
);
if (! defined $pattern || $pattern eq '') {
return undef;
} else {
# Use 'undef' rather than an empty string
if ($otherVal eq '') {
$otherVal = undef;
}
$self->worldModelObj->addRepulseExit($roomObj, $pattern, $otherVal);
# Import the Locator task
$taskObj = $self->session->locatorTask;
if ($taskObj) {
# Empty the Locator's move list IVs and update its task window
$taskObj->resetMoveList();
}
}
return 1;
}
sub addSpecialDepartureCallback {
# Called by $self->enableRoomsColumn
# When the character moves using an exit which doesn't send a room statement upon arrival
# in the new room - usually after some kind of faller - the pattern sent by the world to
# confirm arrival (such as 'You land in a big heap!') should be interpreted by the
# Locator task as a special kind of room statement
# This callback adds a special departure pattern to the specified room and empties the
# Locator task's move list
#
# Expected arguments
# $roomObj - The room to which the pattern should be added. When called by
# $self->enableRoomsColumn, it will be the current room; when called by
# ->enableRoomsPopupMenu, it will be the selected room
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# doesn't supply a pattern
# 1 otherwise
my ($self, $roomObj, $check) = @_;
# Local variables
my ($pattern, $taskObj);
# Check for improper arguments
if (! defined $roomObj || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addSpecialDepartureCallback',
@_,
);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (! $self->mapObj->currentRoom && ! $self->selectedRoom)
) {
return undef;
}
# Prompt the user for a new special departure pattern to add to the room
$pattern = $self->showEntryDialogue(
'Add special departure to room',
'Enter a pattern to match the special departure',
);
if (! $pattern) {
return undef;
} else {
$self->worldModelObj->addExitPattern($roomObj, 'special', $pattern);
# Import the Locator task
$taskObj = $self->session->locatorTask;
if ($taskObj) {
# Empty the Locator's move list IVs and update its task window
$taskObj->resetMoveList();
}
}
return 1;
}
sub addUnspecifiedPatternCallback {
# Called by $self->enableRoomsColumn
# GA::Profile::World->unspecifiedRoomPatternList provides a list of patterns that match
# a line in 'unspecified' rooms (those that don't use a recognisable room statement;
# typically a room whose exit list is completely obscured)
# Each room has its own list of patterns that match a line in 'unspecified' rooms; this
# callback adds a pattern to that list
#
# Expected arguments
# $roomObj - The room to which the pattern should be added. When called by
# $self->enableRoomsColumn, it will be the current room; when called by
# ->enableRoomsPopupMenu, it will be the selected room
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# doesn't supply a pattern
# 1 otherwise
my ($self, $roomObj, $check) = @_;
# Local variables
my ($pattern, $taskObj);
# Check for improper arguments
if (! defined $roomObj || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addUnspecifiedPatternCallback',
@_,
);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (! $self->mapObj->currentRoom && ! $self->selectedRoom)
) {
return undef;
}
# Prompt the user for a new unspecified room pattern to add to the room
$pattern = $self->showEntryDialogue(
'Add unspecified room pattern',
'Enter a pattern to match an unspecified room',
);
if (! $pattern) {
return undef;
} else {
$self->worldModelObj->addExitPattern($roomObj, 'unspecified', $pattern);
# Import the Locator task
$taskObj = $self->session->locatorTask;
if ($taskObj) {
# Empty the Locator's move list IVs and update its task window
$taskObj->resetMoveList();
}
}
return 1;
}
sub removeCheckedDirCallback {
# Called by $self->enableRoomsColumn and ->enableRoomsPopupMenu
# Removes one or all checked directions from the selected room
#
# Expected arguments
# $allFlag - If set to TRUE, all checked directions are removed. If set to FALSE, the
# user is prompted to choose an exit
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the user
# clicks 'cancel' on the 'dialogue' window
# 1 otherwise
my ($self, $allFlag, $check) = @_;
# Local variables
my (
$choice,
@comboList, @sortedList,
);
# Check for improper arguments
if (! defined $allFlag || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->removeCheckedDirCallback',
@_,
);
}
# Standard callback check
if (
! $self->currentRegionmap
|| ! $self->selectedRoom
|| ! $self->selectedRoom->checkedDirHash
) {
return undef;
}
if ($allFlag) {
# Delete all checked directions
$self->selectedRoom->ivEmpty('checkedDirHash');
} else {
@comboList = sort {lc($a) cmp lc($b)} ($self->selectedRoom->ivKeys('checkedDirHash'));
@sortedList = $self->session->currentDict->sortExits(@comboList);
# Prompt the user for a checked direction to remove (even if there's only one)
$choice = $self->showComboDialogue(
'Remove checked direction',
'Select the checked direction to remove',
\@comboList,
);
if (! defined $choice) {
return undef;
} else {
$self->selectedRoom->ivDelete('checkedDirHash', $choice);
}
}
# Redraw the selected room in every window
$self->worldModelObj->updateMaps('room', $self->selectedRoom);
return 1;
}
sub setWildCallback {
# Called by $self->enableRoomsColumn and ->enableRoomsPopupMenu
# Sets the selected room(s)' wilderness mode
#
# Expected arguments
# $mode - One of the values for GA::ModelObj::Room->wildMode - 'normal', 'border' or
# 'wild'
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $mode, $check) = @_;
# Local variables
my @drawList;
# Check for improper arguments
if (
! defined $mode
|| ($mode ne 'normal' && $mode ne 'border' && $mode ne 'wild')
|| defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setWildCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap && (! $self->selectedRoom && ! $self->selectedRoomHash)) {
return undef;
}
# For each selected room, convert their wilderness mode. The called function handles
# redrawing
$self->worldModelObj->setWildernessRoom(
$self->session,
TRUE, # Update automapper windows
$mode,
$self->compileSelectedRooms(),
);
return 1;
}
sub selectExitCallback {
# Called by $self->enableRoomsColumn
# Prompts the user to select an exit manually
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails, if there are no
# exits to select, or if the user clicks 'cancel' in the 'dialogue' window
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$choice, $selectExitObj,
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
$roomName = '(unnamed room)';
} elsif (length($roomName) > 31) {
$roomName = substr($roomName, 0, 29) . '...';
}
$msg .= $roomName . "'\n\n";
} else {
$msg = '';
}
if (@reducedList) {
if (scalar @sortedList != scalar @reducedList) {
$msg .= "Selected rooms (first " . $limit . " rooms of " . scalar @sortedList
. ")";
} elsif (scalar @sortedList == 1) {
$msg .= "Selected rooms (1 room)";
} else {
$msg .= "Selected rooms (" . scalar @sortedList . " rooms)";
}
foreach my $obj (@reducedList) {
my $roomName;
$msg .= "\n #" . $obj->number . " '";
$roomName = $obj->name;
if ($roomName eq '<unnamed room>') {
$roomName = '(unnamed room)';
} elsif (length($roomName) > 31) {
$roomName = substr($roomName, 0, 29) . '...';
}
$msg .= $roomName . "'";
}
}
# Display a popup to show the results
$self->showMsgDialogue(
'Identify rooms',
'info',
$msg,
'ok',
undef,
TRUE, # Preserve newline characters in $msg
);
return 1;
}
sub updateVisitsCallback {
# Called by $self->enableRoomsColumn, ->enableRoomsPopupMenu and ->drawMiscButtonSet
# Adjusts the number of character visits shown in the selected room(s)
# Normally, the current character's visits are changed. However, if $self->showChar is set,
# that character's visits are changed
#
# Expected arguments
# $mode - 'increase' to increase the number of visits by one, 'decrease' to decrease the
# visits by one, 'manual' to let the user enter a value manually, 'reset' to
# reset the number to zero
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails, if the user clicks
# the 'cancel' button on a 'dialogue' window or for any other error
# 1 otherwise
my ($self, $mode, $check) = @_;
# Local variables
my (
$char, $current, $result, $matchFlag,
@roomList, @drawList,
);
# Check for improper arguments
if (
! defined $mode
|| ($mode ne 'increase' && $mode ne 'decrease' && $mode ne 'manual' && $mode ne 'reset')
|| defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->updateVisitsCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || (! $self->selectedRoom && ! $self->selectedRoomHash)) {
return undef;
}
# Get a list of selected room(s)
@roomList = $self->compileSelectedRooms();
# Decide which character to use
if ($self->showChar) {
$char = $self->showChar;
} elsif ($self->session->currentChar) {
$char = $self->session->currentChar->name;
} else {
$self->showMsgDialogue(
'Update character visits',
'error',
'Can\'t update the number of visits - there is no current character set',
'ok',
);
return undef;
}
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# ...and then show a confirmation (but only if the selected room is on a different
# level, or in a different region altogether)
if (
$self->selectedRoom->parent != $self->currentRegionmap->number
|| $self->selectedRoom->zPosBlocks != $self->currentRegionmap->currentLevel
) {
$self->showMsgDialogue(
'Update character visits',
'info',
'Visits by \'' . $char . '\' to room #' . $self->selectedRoom->number
. ' set to ' . $current,
'ok',
);
}
} else {
# Check every selected room, stopping when we find one on the same level and in the
# same region
OUTER: foreach my $roomObj (@roomList) {
if (! defined $current) {
# (All the selected rooms now have the same number of visits, so $current only
# needs to be set once)
$current = $roomObj->ivShow('visitHash', $char);
if (! $current) {
$current = 0;
}
}
if (
$roomObj->parent == $self->currentRegionmap->number
&& $roomObj->zPosBlocks == $self->currentRegionmap->currentLevel
) {
$matchFlag = TRUE;
last OUTER;
}
}
if (! $matchFlag) {
# No selected rooms are actually visible, so show the confirmation
$self->showMsgDialogue(
'Update character visits',
'info',
'Visits by \'' . $char . '\' in ' . (scalar @roomList) . ' rooms set to '
. $current,
'ok',
);
}
}
return 1;
}
sub toggleGraffitiCallback {
# Called by $self->enableRoomsColumn, ->enableRoomsPopupMenu and ->drawMiscButtonSet
# Toggles graffiti in the selected room(s)
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (@roomList, @drawList);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->toggleGraffitiCallback', @_);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (! $self->selectedRoom && ! $self->selectedRoomHash)
|| ! $self->graffitiModeFlag
) {
return undef;
}
# Get a list of selected room(s)
@roomList = $self->compileSelectedRooms();
foreach my $roomObj (@roomList) {
push (@drawList, 'room', $roomObj);
if (! $self->ivExists('graffitiHash', $roomObj->number)) {
$self->ivAdd('graffitiHash', $roomObj->number, undef);
} else {
$self->ivDelete('graffitiHash', $roomObj->number);
}
}
# Redraw the room(s) with graffiti on or off
$self->markObjs(@drawList);
$self->doDraw();
# Update room counts in the window's title bar
$self->setWinTitle();
return 1;
}
sub setFilePathCallback {
# Called by $self->enableRoomsColumn
# Sets the file path for the world's source code file (if known) for the selected room
#
# Expected arguments
# (none besides $self)
#
# Return values
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Resets the list of exclusive profiles for the selected rooms
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$msg,
@roomList,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->resetExclusiveProfileCallback',
@_,
);
}
# Standard callback check
if (! $self->currentRegionmap || (! $self->selectedRoom && ! $self->selectedRoomHash)) {
return undef;
}
# Get a list of selected rooms
@roomList = $self->compileSelectedRooms();
# Reset their lists of exclusive profiles
$self->worldModelObj->resetExclusiveProfiles(
TRUE, # Update Automapper windows now
@roomList,
);
# Compose a message to display
$msg = 'Reset exclusive profiles for ';
if ($self->selectedRoom) {
$msg .= '1 room';
} else {
$msg .= scalar @roomList . ' rooms';
}
$self->showMsgDialogue(
'Reset exclusive profiles',
'info',
$msg,
'ok',
);
return 1;
}
# Menu 'Exits' column callbacks
sub changeDirCallback {
# Called by $self->enableExitsColumn
# Changes an existing exit's direction and/or its map direction, prompting the user for the
# new directions
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails, if the user clicks
# 'cancel' on the 'dialogue' window or if the exit directions can't be changed
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($roomObj, $exitObj, $dir, $mapDir, $result);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->changeDirCallback', @_);
}
# Standard callback check
if (
! $self->currentRegionmap
|| ! $self->selectedExit
|| (
$self->selectedExit->drawMode ne 'primary'
&& $self->selectedExit->drawMode ne 'perm_alloc'
)
) {
return undef;
}
# When a user selects an exit, they may be referring either to the exit stored in
# $self->selectedExit, its twin exit (if there is one) or its shadow exit (if there is
# one). Prompt the user to find out which
$exitObj = $self->promptSpecifyExit('Change direction for which exit?');
if (! $exitObj) {
# User clicked the 'cancel' button, or closed the 'dialogue' window
return undef;
}
# Get the parent room object
$roomObj = $self->worldModelObj->ivShow('modelHash', $exitObj->parent);
# If this exit has been allocated a shadow exit, then the 'change direction' operation
# merely reassigns it as an unallocated exit
if ($exitObj->shadowExit) {
$result = $self->worldModelObj->changeShadowExitDir(
$self->session,
TRUE, # Update Automapper windows now
$roomObj,
$exitObj,
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $exitObj;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->toggleExitTagCallback', @_);
}
# Standard callback check
if (
! $self->currentRegionmap
|| (
(! $self->selectedExit || ! $self->selectedExit->regionFlag)
&& ! $self->selectedExitTag
)
) {
return undef;
}
# Get the exit to use
if ($self->selectedExit) {
$exitObj = $self->selectedExit;
} else {
$exitObj = $self->selectedExitTag;
}
# Toggle the exit tag
if (! $exitObj->exitTag) {
$self->worldModelObj->applyExitTag(
TRUE, # Update Automapper windows now
$exitObj,
);
} else {
$self->worldModelObj->cancelExitTag(
TRUE, # Update Automapper windows now
$exitObj,
);
}
# For a selected exit tag - which has now been removed - select the exit instead
$self->setSelectedObj(
[$exitObj, 'exit'],
FALSE, # Select this object; unselect all other objects
);
return 1;
}
sub viewExitDestination {
# Called by $self->enableExitTagsPopupMenu (only)
# For a region exit, selects the destination room and changes the currently displayed region
# (and level) to show it
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $roomObj;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->viewExitDestination', @_);
}
# Standard callback check
if (! $self->currentRegionmap || ! $self->selectedExitTag) {
return undef;
}
# Get the exit's destination room
$roomObj = $self->worldModelObj->ivShow('modelHash', $self->selectedExitTag->destRoom);
# Select the destination room
$self->setSelectedObj(
[$roomObj, 'room'],
FALSE, # Select this object; unselect all other objects
);
# Centre the map over the selected room, changing the currently displayed region and level
# as necessary
$self->centreMapOverRoom($roomObj);
return 1;
}
sub editExitTagCallback {
# Called by $self->enableLabelsColumn
# Prompts the user to enter a new ->exitTag for the selected exit
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($exitObj, $text);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
# Compile a list of exits which could be confused with the currently selected one
($stringListRef, $exitHashRef) = $self->compileExitList();
if (! defined $stringListRef) {
return undef;
}
@stringList = @$stringListRef;
%exitHash = %$exitHashRef;
# If there is more than one exit in the list, prompt the user to specify which one to delete
if (scalar @stringList > 1) {
# Compile the combo list
if (@stringList == 2) {
@comboList = ($bothString, @stringList);
} elsif (@stringList > 2) {
@comboList = ($allString, @stringList);
} else {
@comboList = @stringList;
}
# Prompt the user to choose which exit to delete
$choice = $self->showComboDialogue(
'Select exit',
'Select which exit to delete',
\@comboList,
);
if (! $choice) {
return undef;
} elsif ($choice eq $bothString || $choice eq $allString) {
@finalList = values %exitHash;
} else {
push (@finalList, $exitHash{$choice});
}
} else {
# There's only one exit on which to operate
push (@finalList, $self->selectedExit);
}
# Delete the exit object(s) and instruct the world model to update its Automapper windows
$self->worldModelObj->deleteExits(
$self->session,
TRUE, # Update Automapper windows now
@finalList,
);
return 1;
}
sub addBendCallback {
# Called by $self->enableExitsPopupMenu (only)
# After a right-click on an exit, when the user has selected 'add bend' in the popup menu,
# add a bend at the same position
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the bend is
# not added
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$startXPos, $startYPos, $clickXPos, $clickYPos, $stopXPos, $stopYPos, $resultType,
$twinExitObj,
);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addBendCallback', @_);
}
# Standard callback check
if (
! $self->currentRegionmap
|| ! $self->selectedExit
|| (! $self->selectedExit->oneWayFlag && ! $self->selectedExit->twinExit)
|| $self->selectedExit->regionFlag
|| ! defined $self->exitClickXPosn
|| ! defined $self->exitClickYPosn
) {
return undef;
}
# Get the absolute coordinates of the start of the middle (bending) section of the
# exit
# At the same time, convert the absolute coordinates of the right-mouse click on the exit,
# and the absolute coordinates of the end of the bending section, into coordinates
# relative to the start of the bending section of the eixt
($startXPos, $startYPos, $clickXPos, $clickYPos, $stopXPos, $stopYPos, $resultType)
= $self->findExitClick(
$self->selectedExit,
$self->exitClickXPosn,
$self->exitClickYPosn,
);
# If the click wasn't in the parent room's gridblock, in the destination room's gridblock
# or too close to an existing bend...
if (! $resultType) {
# Add a bend to the exit
$self->worldModelObj->addExitBend(
FALSE, # Don't update Automapper windows yet
$self->selectedExit,
$startXPos, $startYPos,
$clickXPos, $clickYPos,
$stopXPos, $stopYPos,
);
# Repeat the process for the selected exit's twin (if there is one)
if ($self->selectedExit->twinExit) {
$twinExitObj = $self->worldModelObj->ivShow(
'exitModelHash',
$self->selectedExit->twinExit,
);
($startXPos, $startYPos, $clickXPos, $clickYPos, $stopXPos, $stopYPos)
= $self->findExitClick(
$twinExitObj,
$self->exitClickXPosn,
$self->exitClickYPosn,
);
$self->worldModelObj->addExitBend(
FALSE, # Don't update Automapper windows yet
$twinExitObj,
$startXPos, $startYPos,
$clickXPos, $clickYPos,
$stopXPos, $stopYPos,
);
}
# Now we can redraw the exit
$self->worldModelObj->updateMapExit(
$self->selectedExit,
$twinExitObj, # May be 'undef'
);
return 1;
} else {
# If the click was too close to an existing bend, show a message explaining why nothing
# has happened (don't bother showing a message for other values of $resultType, which
# probably can't be returned to this function anyway)
if ($resultType eq 'near_bend') {
$self->showMsgDialogue(
'Add bend',
'error',
'Cannot add a bend - you clicked too close to an existing bend',
'ok',
);
}
return undef;
}
}
sub removeBendCallback {
# Called by $self->enableExitsPopupMenu (only)
# After a right-click on an exit, when the user has selected 'remove bend' in the popup
# menu, remove the bend closest to the clicked position
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails or if the mouse
# click was not near a bend
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($index, $twinExitObj);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->removeBendCallback', @_);
}
# Standard callback check
if (
! $self->currentRegionmap
|| ! $self->selectedExit
|| (! $self->selectedExit->oneWayFlag && ! $self->selectedExit->twinExit)
|| ! $self->selectedExit->bendOffsetList
|| ! defined $self->exitClickXPosn
|| ! defined $self->exitClickYPosn
) {
return undef;
}
# Find the number of the bend which is closest to the the clicked position
$index = $self->findExitBend(
$self->selectedExit,
$self->exitClickXPosn,
$self->exitClickYPosn,
);
if (! defined $index) {
$self->showMsgDialogue(
'Remove bend',
'error',
'Please right-click on the bend that you want to remove',
'ok',
);
return undef;
} else {
# Remove this bend
$self->worldModelObj->removeExitBend(
$self->session,
TRUE, # Update Automapper windows now
$self->selectedExit,
$index, # Remove this bend (first bend is numbered 0)
);
# If there is a twin exit, remove the corresponding bend at the same time
if ($self->selectedExit->twinExit) {
$twinExitObj = $self->worldModelObj->ivShow(
'exitModelHash',
$self->selectedExit->twinExit,
);
$self->worldModelObj->removeExitBend(
$self->session,
TRUE, # Update Automapper windows now
$twinExitObj,
((scalar $self->selectedExit->bendOffsetList / 2) - $index - 1),
);
}
return 1;
}
}
# Menu 'Labels' column callbacks
sub addLabelAtBlockCallback {
# Called by $self->enableLabelsColumn
# Prompts the user to supply a gridblock (via a 'dialogue' window) and creates a label at
# that location
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments, if the standard callback check fails, if the user clicks
# the 'cancel' button on the 'dialogue' window or if the new label can't be created
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my ($xPosBlocks, $yPosBlocks, $zPosBlocks, $text, $style);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addLabelAtBlockCallback',
@_,
);
}
# Standard callback check
if (! $self->currentRegionmap) {
return undef;
}
# Prompt the user for a gridblock
($xPosBlocks, $yPosBlocks, $zPosBlocks) = $self->promptGridBlock();
if (! defined $xPosBlocks) {
# User clicked the 'cancel' button
return undef;
}
# Check that the specified gridblock actually exists
if (
! $self->currentRegionmap->checkGridBlock(
$xPosBlocks,
$yPosBlocks,
$zPosBlocks,
)
) {
$self->showMsgDialogue(
'Add label at block',
'error',
'Invalid gridblock: x=' . $xPosBlocks . ', y=' . $yPosBlocks . ', z=' . $zPosBlocks,
'ok',
);
}
# Prompt the user to specify the label text
($text, $style) = $self->promptConfigLabel();
# Free click mode must be reset (nothing special happens when the user clicks on the map)
$self->reset_freeClickMode();
if (defined $text && $text =~ m/\S/) {
# Create a new label at the specified location
$self->worldModelObj->addLabel(
$self->session,
TRUE, # Update Automapper windows now
$self->currentRegionmap,
($xPosBlocks * $self->currentRegionmap->blockWidthPixels),
($yPosBlocks * $self->currentRegionmap->blockHeightPixels),
$zPosBlocks,
$text,
$style,
);
# The specified style is the preferred one
if (defined $style) {
$self->worldModelObj->set_mapLabelStyle($style);
}
return 1;
} else {
return undef;
}
}
sub addLabelAtClickCallback {
# Called by $self->enableCanvasPopupMenu and ->canvasEventHandler
# Adds a label at a specified location on the current level
#
# Expected arguments
# $xPosPixels, $yPosPixels
# - The grid coordinates at which to create the label
#
# Return values
# 'undef' on improper arguments, if the user clicks the 'cancel' button on the 'dialogue'
# window or if the new label can't be created
# 1 otherwise
my ($self, $xPosPixels, $yPosPixels, $check) = @_;
# Local variables
my ($text, $style);
# Check for improper arguments
if (! defined $xPosPixels || ! defined $yPosPixels || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->addLabelAtClickCallback',
@_,
);
}
# (No standard callback checks for this function)
# Prompt the user to specify the label text
($text, $style) = $self->promptConfigLabel();
# Free click mode must be reset (nothing special happens when the user clicks on the map)
$self->reset_freeClickMode();
if ($text || (defined $text && $text eq '0')) { # '0' is a valid label
# Create a new label at the specified location
$self->worldModelObj->addLabel(
$self->session,
TRUE, # Update Automapper windows now
$self->currentRegionmap,
$xPosPixels,
$yPosPixels,
$self->currentRegionmap->currentLevel,
$text,
$style,
);
# The specified style is the preferred one
if (defined $style) {
$self->worldModelObj->set_mapLabelStyle($style);
}
return 1;
} else {
return undef;
}
}
sub setLabelCallback {
# Called by $self->enableLabelsColumn
# Prompts the user to modify a label's text and style (presenting only a list of map label
# style objects to choose from), using the same 'dialogue' window used to add a label
#
# Expected arguments
# $customiseFlag - If FALSE, the 'dialogue' window only shows label text and style. If
# TRUE, the 'dialogue' window shows all label IVs
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $customiseFlag, $check) = @_;
# Local variables
my ($text, $style);
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setLabelCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || ! $self->selectedLabel) {
return undef;
}
# Prompt the user to mod the label
($text, $style) = $self->promptConfigLabel($self->selectedLabel, $customiseFlag);
if (defined $text && $text =~ m/\S/) {
$self->worldModelObj->updateLabel(
TRUE, # Update automapper windows now
$self->session,
$self->selectedLabel,
$text,
$style,
);
# The specified style is the preferred one
if (defined $style) {
$self->worldModelObj->set_mapLabelStyle($style);
}
return 1;
} else {
return undef;
}
}
sub setLabelDirectCallback {
# Called by $self->enableLabelsPopupMenu (only)
#
# Sets the selected label's label style, without needing to prompt the user any further
#
# Expected arguments
# $style - The name of the label style to use
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $style, $check) = @_;
# Check for improper arguments
if (! defined $style || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setLabelDirectCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || ! $self->selectedLabel) {
return undef;
}
$self->worldModelObj->updateLabel(
TRUE, # Update automapper windows now
$self->session,
$self->selectedLabel,
$self->selectedLabel->name, # The label text remains unchanged
$style,
);
# The specified style is the preferred one
$self->worldModelObj->set_mapLabelStyle($style);
return 1;
}
sub selectLabelCallback {
# Called by $self->enableLabelsColumn
# Prompts the user to select a label, from a combobox listing all the labels in the current
# regionmap
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments or if the standard callback check fails
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my (
$allString, $choice, $labelObj,
@labelList, @sortedList, @comboList, @finalList,
%comboHash,
);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->deleteLabelsCallback', @_);
}
# Standard callback check
if (! $self->currentRegionmap || (! $self->selectedLabel && ! $self->selectedLabelHash)) {
return undef;
}
# Prompt the user for confirmation before deleting multiple labels
if ($self->selectedLabelHash) {
$result = $self->showMsgDialogue(
'Delete labels',
'question',
'Are you sure you want to delete ' . $self->ivPairs('selectedLabelHash')
. ' labels?',
'yes-no',
);
if ($result ne 'yes') {
return undef;
}
}
# Delete the selected label(s)
return $self->worldModelObj->deleteLabels(
TRUE, # Update Automapper windows now
$self->compileSelectedLabels(),
);
}
# IV setting functions
sub setMode {
# Can be called by anything
# Sets the automapper's operating mode and updates other IVs/widgets
# NB If the Locator isn't running, a call to this function always sets the mode to 'wait'
#
# Expected arguments
# $mode - The new mode:
# 'wait' - The automapper isn't doing anything
# 'follow' - The automapper is following the character's position, but not
# updating the world model
# 'update' - The automapper is updating the world model as the character
# moves around
#
# Return values
# 'undef' on improper arguments, or if an attempt to switch to 'update' mode fails because
# the Locator task is expecting room descriptions
# 1 otherwise
my ($self, $mode, $check) = @_;
# Local variables
my (
$taskObj, $title, $oldMode, $menuItemName, $radioMenuItem, $toolbarButtonName,
$toolbarButton,
);
# Check for improper arguments
if (
! defined $mode || ($mode ne 'wait' && $mode ne 'follow' && $mode ne 'update')
|| defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->setMode', @_);
}
# Import the current session's Locator task
$taskObj = $self->session->locatorTask;
# If the Locator isn't running or if there is no current regionmap, the mode must be set to
# 'wait'
if (! $taskObj || ! $self->currentRegionmap) {
$mode = 'wait';
} elsif ($self->mode eq 'update' && $self->worldModelObj->disableUpdateModeFlag) {
# This function is called just after GA::Obj::WorldModel->toggleDisableUpdateModeFlag
# has set ->disableUpdateModeFlag to TRUE. Now that update mode has been disabled,
# switch to 'follow' mode
$mode = 'follow';
} elsif (
($self->mode ne 'update' && $mode eq 'update')
|| ($self->mode eq 'wait' && $mode eq 'follow')
) {
# Don't switch to update mode if it is disabled, or if the session is in 'connect
# offline' mode
if (
$mode eq 'update'
&& (
$self->worldModelObj->disableUpdateModeFlag
|| $self->session->status eq 'offline'
)
) {
# Retain the current mode ('wait' or 'follow')
$mode = $self->mode;
# If we're trying to switch from 'wait' to 'follow' mode, or from 'wait/'follow' to
# 'update' mode, the Locator task must not be expecting room descriptions (doing this
# prevents the map from adding rooms based on junk data, or from getting lost
# immediately because it expected the wrong room)
# If the Locator is expecting descriptions, refuse to switch mode
} elsif ($taskObj->moveList) {
if ($taskObj->moveList == 1) {
$title = 'Set mode (1 missing room statement)';
} else {
$title = 'Set mode (' . scalar $taskObj->moveList . ' missing room statements)';
}
$self->showMsgDialogue(
$title,
'warning',
'The automapper can\'t switch to \'' . $mode . '\' mode until the Locator task'
. ' is no longer expecting any rooms (try: Rooms - Locator task - Reset'
. ' Locator)',
'ok',
);
# Retain the current mode ('wait' or 'follow')
$mode = $self->mode;
}
}
# We need to compare the old/new settings of $self->mode in a moment
$oldMode = $self->mode;
# Set the automapper's new operating mode
$self->ivPoke('mode', $mode);
# Even if $self->mode hasn't changed, it might not match the menu items and the toolbar
# button; so we must make sure the right ones are activated. Use
# $self->ignoreMenuUpdateFlag so that toggling a menu item doesn't toggle a toolbar icon
# (and vice-versa)
$self->ivPoke('ignoreMenuUpdateFlag', TRUE);
# Update radio buttons in the menu (if the menu is visible)
$menuItemName = 'set_'. $mode . '_mode';
if ($self->menuBar && $self->ivExists('menuToolItemHash', $menuItemName)) {
$radioMenuItem = $self->ivShow('menuToolItemHash', $menuItemName);
$radioMenuItem->set_active(TRUE);
}
# Update toolbar buttons in the toolbar (if the toolbar is visible)
$toolbarButtonName = 'icon_set_'. $mode . '_mode';
if ($self->toolbarList && $self->ivExists('menuToolItemHash', $toolbarButtonName)) {
$toolbarButton = $self->ivShow('menuToolItemHash', $toolbarButtonName);
$toolbarButton->set_active(TRUE);
}
# Make sure that the radio/toolbar buttons for 'update mode' are sensitive, or not
$self->restrictUpdateMode();
$self->ivPoke('ignoreMenuUpdateFlag', FALSE);
# In case the automapper object's ghost room gets set to the wrong room, switching to
# 'wait' mode temporarily must reset it
if ($self->mode eq 'wait' && $self->mapObj->ghostRoom) {
$self->mapObj->setGhostRoom(); # Automatically redraws the room
# If switching from 'wait' to 'follow'/'update' mode and there is a current room set, the
# ghost room will not be set, so st it
} elsif (
$oldMode eq 'wait'
&& $self->mode ne 'wait'
&& $self->mapObj->currentRoom
&& ! $self->mapObj->ghostRoom
) {
$self->mapObj->setGhostRoom($self->mapObj->currentRoom);
}
if ($self->mapObj->currentRoom) {
# Redraw the current room in its correct colour (default pink in 'wait' mode, default
# red in 'follow'/'update' mode)
$self->markObjs('room', $self->mapObj->currentRoom);
$self->doDraw();
}
return 1;
}
sub setCurrentRegion {
# Called by $self->treeViewRowActivated and $self->newRegionCallback. Also called by
# GA::Obj::Map->setCurrentRoom
# Sets the new current region and draws its map (if not already drawn)
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# $name - The name of the region (matches a key in
# GA::Obj::WorldModel->regionmapHash). If set to 'undef', there is no
# current region (and an empty map must be displayed)
# $forceFlag - Set to TRUE when called by GA::Obj::Map->setCurrentRoom. Changes the
# $name region's current level to show the current room, if there is one
# (otherwise, the current level is only changed when the automapper is in
# 'follow' or 'update' mode)
#
# Return values
# 'undef' on improper arguments or if a specified region $name doesn't match a known
# regionmap
# 1 otherwise
my ($self, $name, $forceFlag, $check) = @_;
# Local variables
my (
$scrollXPos, $scrollYPos, $oldRegionmapObj, $oldParchmentObj, $count, $destroyFlag,
$index, $regionmapObj, $destroyObj, $parchmentObj, $currentRoom,
@newList,
%occupyHash,
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
my ($self, $mode, $check) = @_;
# Local variables
my $gdkWindow;
# Check for improper arguments
if (! defined $mode || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->set_freeClickMode', @_);
}
$self->ivPoke('freeClickMode', $mode);
if ($self->bgColourMode eq 'rect_stop') {
$self->ivPoke('bgColourMode', 'rect_start');
}
# Set the mouse icon accordingly
$gdkWindow = $self->winWidget->get_window();
if ($gdkWindow) {
if ($mode eq 'add_room' || $mode eq 'add_label') {
$gdkWindow->set_cursor($axmud::CLIENT->constMapAddCursor);
} elsif ($mode eq 'connect_exit' || $mode eq 'move_room') {
$gdkWindow->set_cursor($axmud::CLIENT->constMapConnectCursor);
} elsif ($mode eq 'merge_room') {
$gdkWindow->set_cursor($axmud::CLIENT->constMapMergeCursor);
} else {
$gdkWindow->set_cursor($axmud::CLIENT->constMapCursor);
}
}
return 1;
}
sub reset_freeClickMode {
my ($self, $check) = @_;
# Local variables
my $gdkWindow;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->reset_freeClickMode', @_);
}
$self->ivPoke('freeClickMode', 'default');
# Reset the mouse icon
$gdkWindow = $self->winWidget->get_window();
if ($gdkWindow) {
$gdkWindow->set_cursor($axmud::CLIENT->constMapCursor);
}
return 1;
}
sub set_ignoreMenuUpdateFlag {
my ($self, $flag, $check) = @_;
# Check for improper arguments
if (! defined $flag || defined $check) {
return $axmud::CLIENT->writeImproper(
$self->_objClass . '->set_ignoreMenuUpdateFlag',
@_,
);
}
if ($flag) {
$self->ivPoke('ignoreMenuUpdateFlag', TRUE);
} else {
$self->ivPoke('ignoreMenuUpdateFlag', FALSE);
}
return 1;
}
sub add_graffiti {
my ($self, $roomObj, $check) = @_;
# Check for improper arguments
if (! defined $roomObj || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->add_graffiti', @_);
}
# Update IVs
if ($self->graffitiModeFlag) {
$self->ivAdd('graffitiHash', $roomObj->number);
# Update room counts in the window's title bar
$self->setWinTitle();
}
return 1;
}
sub del_graffiti {
my ($self, @roomList) = @_;
# (No improper arguments to check)
if ($self->graffitiModeFlag) {
foreach my $roomObj (@roomList) {
$self->ivDelete('graffitiHash', $roomObj->number);
}
# Update room counts in the window's title bar
$self->setWinTitle();
}
return 1;
}
sub set_mapObj {
my ($self, $mapObj, $check) = @_;
# Check for improper arguments
if (! defined $mapObj || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->set_mapObj', @_);
}
# Update IVs
$self->ivPoke('mapObj', $mapObj);
lib/Games/Axmud/Win/Map.pm view on Meta::CPAN
sub ctrlKeyFlag
{ $_[0]->{ctrlKeyFlag} }
sub bgColourMode
{ $_[0]->{bgColourMode} }
sub bgColourChoice
{ $_[0]->{bgColourChoice} }
sub bgRectXPos
{ $_[0]->{bgRectXPos} }
sub bgRectYPos
{ $_[0]->{bgRectYPos} }
sub bgAllLevelFlag
{ $_[0]->{bgAllLevelFlag} }
sub exitSensitivity
{ $_[0]->{exitSensitivity} }
sub exitBendSize
{ $_[0]->{exitBendSize} }
sub exitClickXPosn
{ $_[0]->{exitClickXPosn} }
sub exitClickYPosn
{ $_[0]->{exitClickYPosn} }
sub leftClickTime
{ $_[0]->{leftClickTime} }
sub leftClickObj
{ $_[0]->{leftClickObj} }
sub leftClickWaitTime
{ $_[0]->{leftClickWaitTime} }
sub mode
{ $_[0]->{mode} }
sub showChar
{ $_[0]->{showChar} }
sub painterFlag
{ $_[0]->{painterFlag} }
sub graffitiModeFlag
{ $_[0]->{graffitiModeFlag} }
sub graffitiHash
{ my $self = shift; return %{$self->{graffitiHash}}; }
sub constVectorHash
{ my $self = shift; return %{$self->{constVectorHash}}; }
sub constDoubleVectorHash
{ my $self = shift; return %{$self->{constDoubleVectorHash}}; }
sub constArrowVectorHash
{ my $self = shift; return %{$self->{constArrowVectorHash}}; }
sub constPerpVectorHash
{ my $self = shift; return %{$self->{constPerpVectorHash}}; }
sub constSpecialVectorHash
{ my $self = shift; return %{$self->{constSpecialVectorHash}}; }
sub constTriangleCornerHash
{ my $self = shift; return %{$self->{constTriangleCornerHash}}; }
sub constGtkAnchorHash
{ my $self = shift; return %{$self->{constGtkAnchorHash}}; }
sub constMagnifyList
{ my $self = shift; return @{$self->{constMagnifyList}}; }
sub constShortMagnifyList
{ my $self = shift; return @{$self->{constShortMagnifyList}}; }
sub ignoreMenuUpdateFlag
{ $_[0]->{ignoreMenuUpdateFlag} }
sub dragModeFlag
{ $_[0]->{dragModeFlag} }
sub dragFlag
{ $_[0]->{dragFlag} }
sub dragContinueFlag
{ $_[0]->{dragContinueFlag} }
sub dragCanvasObj
{ $_[0]->{dragCanvasObj} }
sub dragCanvasObjList
{ my $self = shift; return @{$self->{dragCanvasObjList}}; }
sub dragModelObj
{ $_[0]->{dragModelObj} }
sub dragModelObjType
{ $_[0]->{dragModelObjType} }
sub dragInitXPos
{ $_[0]->{dragInitXPos} }
sub dragInitYPos
{ $_[0]->{dragInitYPos} }
sub dragCurrentXPos
{ $_[0]->{dragCurrentXPos} }
sub dragCurrentYPos
{ $_[0]->{dragCurrentYPos} }
sub dragFakeRoomList
{ my $self = shift; return @{$self->{dragFakeRoomList}}; }
sub dragBendNum
{ $_[0]->{dragBendNum} }
sub dragBendInitXPos
{ $_[0]->{dragBendInitXPos} }
sub dragBendInitYPos
{ $_[0]->{dragBendInitYPos} }
sub dragBendTwinNum
{ $_[0]->{dragBendTwinNum} }
sub dragBendTwinInitXPos
{ $_[0]->{dragBendTwinInitXPos} }
sub dragBendTwinInitYPos
{ $_[0]->{dragBendTwinInitYPos} }
sub dragExitDrawMode
{ $_[0]->{dragExitDrawMode} }
sub dragExitOrnamentsFlag
{ $_[0]->{dragExitOrnamentsFlag} }
sub selectBoxFlag
{ $_[0]->{selectBoxFlag} }
sub selectBoxCanvasObj
{ $_[0]->{selectBoxCanvasObj} }
sub selectBoxInitXPos
{ $_[0]->{selectBoxInitXPos} }
sub selectBoxInitYPos
{ $_[0]->{selectBoxInitYPos} }
sub selectBoxCurrentXPos
{ $_[0]->{selectBoxCurrentXPos} }
sub selectBoxCurrentYPos
{ $_[0]->{selectBoxCurrentYPos} }
}
# Package must return a true value
1