def on_edit_layer(self, event): if self.layer_selected is None: cjr.show_error_message( "Please select a layer to edit." ) else: self.layer_selected.edit_layer()
def on_duplicate(self, event): """Ask for a name and clone the selected object it if it's a non existing name""" source_name = self.list.GetStringSelection() if source_name != "": dlg = wx.TextEntryDialog( None, "Enter the " + self.caption + "'s name:", "Duplicate " + self.caption, source_name ) if dlg.ShowModal() == wx.ID_OK: # Clone the object only if there isn't another object with the same name yet target_name = dlg.GetValue() target_path = format.append_to_path( self.lib_path, target_name ) try: # Lookup will fail if it's a new name (name not found) pynebula.lookup( target_path ) msg = "Another " + self.caption + " named '" + dlg.GetValue() + "' already exists." cjr.show_error_message(msg) except: # Clone object, save it to disk and add it to list source_path = format.append_to_path( self.lib_path, source_name ) source_obj = pynebula.lookup( source_path ) target_obj = source_obj.clone( str(target_path) ) self.save_object( target_obj ) self.list.Append( target_name ) dlg.Destroy()
def on_delete_cmd(self, event): # Ask for delete confirmation cmd_name = self.list_cmds.GetStringSelection() if cmd_name == "": return msg = "Deleting a command cannot be undone.\n\n" \ "Are you sure that you want to delete the " \ "command '%s'?" % cmd_name should_delete = cjr.warn_yes_no(self, msg) # Delete the command if the user has confirmed they want to if should_delete == wx.ID_YES: # Delete the script file class_name = self.tree_classes.get_selected_class_name() cmd_path = self.__get_cmd_path(class_name, cmd_name) os.remove( cmd_path ) # Delete the class directory if there's no commmands left class_path = self.__get_class_path(class_name) if len( filedlg.get_file_list( class_path, ['lua'] ) ) == 0: try: os.rmdir( class_path ) except: cjr.show_error_message( "Unable to delete the class commands directory '" + class_path + "'.\n" \ "Maybe is it not empty or is another application using it?\n" \ "Please, remove it manually." ) # Delete the command from the nclass in memory servers.get_script_server().refreshclass( str(class_name) ) # Remove the command from the commands list self.list_cmds.Delete( self.list_cmds.GetSelection() ) self.__update_buttons()
def on_select_lightmap_light(self, event): # get light num_entities = app.get_object_state().getselectioncount() lightid = -1 for i in xrange(num_entities): entity = app.get_object_state().getselectedentity(i) if entity.isa("nelight") : lightid = entity.getid() break # if light not found if lightid == -1 : cjr.show_error_message( "No nelight instance found as lightmap light source" ) return # if found create in the level app.get_level().setentityname( lightid, "terrain_lightmap_light" ) cjr.show_information_message( "Terrain lightmap light selected" )
def on_ok_button_clicked(self, event): result_list = self.get_selected_entities() if result_list: if self.has_valid_path_name(): #we need to save the entity id counter to avoid conflicts servers.get_entity_object_server().saveconfig() object_instancer = pynebula.new('nobjectinstancer') object_instancer.init( len(result_list), len(result_list) ) object_instancer.setentityobjecttype( CJR_NORMAL_ENTITY_TYPE ) for each_entity in result_list: entity_id_as_string = str( each_entity.getid() ) object_instancer.appendwithname( each_entity, entity_id_as_string ) object_instancer.saveas( self.get_path_name() ) pynebula.delete(object_instancer) self.Close() else: cjr.show_error_message( "Please enter a valid path name" ) else: cjr.show_error_message( "Please select at least one entity to export" )
def on_copy_material(self, event): material = self.material_selected.material # Ask for material name dlg = wx.TextEntryDialog( self, "This will create a copy of the '%s' material.\n\n" \ "Enter a name for the new material." % material.getname(), "Create a copy of an existing grass material" ) if dlg.ShowModal() == wx.ID_OK: name = str( dlg.GetValue() ) if name.strip() == "": cjr.show_error_message( "Please enter a name for the new grass material." ) else: # Validate name terrain = app.get_outdoor() if terrain.hasgrowthmaterialwithname(name): cjr.show_error_message( "There is already a grass material called '%s'." % name ) else: # Add copy of material terrain.addcopyofgrowthmaterial( material, name ) self.__build_material_list() dlg.Destroy()
def on_save_temp_mesh(self, event): """Show a file browser and save the temporary mesh to the selected file""" dlg = wx.FileDialog( self.get_frame(), message="Enter a file name", wildcard="Navigation mesh ASCII file (*.txt)|*.txt|" \ "Navigation mesh binary file (*.nav)|*.nav|" \ "Navigation mesh compressed file (*.rle)|*.rle", style=wx.SAVE | wx.OVERWRITE_PROMPT | wx.CHANGE_DIR ) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() # Append extension if needed if dlg.GetFilterIndex() == 0 and not path.endswith(".txt"): path = path + ".txt" elif dlg.GetFilterIndex() == 1 and not path.endswith(".nav"): path = path + ".nav" elif dlg.GetFilterIndex() == 2 and not path.endswith(".rle"): path = path + ".rle" # Save the navigation mesh navbuilder = app.get_navbuilder() if not navbuilder.savenavmesh( str(dlg.GetPath()) ): msg = "Unable to save the navigation mesh file '%s'" % dlg.GetPath() cjr.show_error_message(msg) dlg.Destroy()
def on_area_stats(self, event): """Get stats and budget for loading area""" # select an area and retrieve stats information for it dlg = nodelibdlg.NodeLibDialog( self.get_frame(), nodelibdlg.OPEN, 'area', 'Area', "/usr/areas" ) if dlg.ShowModal() == wx.ID_OK: # Check that's an existing area if not dlg.node_exists(): msg = "There is no area called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # show log of resources for the area dlg2 = waitdlg.WaitDialog( self.get_frame(), "Analyzing area ..." ) if not dlg.get_node().logdebugstats(): msg = "No stats available for this area, "\ "you need to load it first" cjr.show_error_message(msg) dlg2.Destroy() dlg.Destroy()
def add_emitter( particle_system, emitter_name, texture_name = 'home:export/textures/materials/rauch.dds' ): particle_system_name = particle_system.getname() root_node = particle_system.getrootnode() # check there isn't already one with the same name for each_child in root_node.getchildren(): if each_child.getname() == emitter_name: cjr.show_error_message( "There is already an emitter "\ "called '%s'." % emitter_name ) return False particle_NOH = root_node.getfullname() + '/' + emitter_name # force particle instances to release resources before # adding new emiiter particle_system.refresh() particle_node = pynebula.new( 'nparticleshapenode2', particle_NOH ) if particle_node is None: return False else: set_default_options( particle_node, texture_name ) particle_node.binddirtydependence(root_node) particle_node.setobjectdirty(True) return True
def on_remove_stream(self, event): """Remove geometry stream""" if not pynebula.exists( str("/usr/streams") ): app.get_state("geometrystream").loadstreamlibrary() dlg = nodelibdlg.NodeLibDialog( self.get_frame(), nodelibdlg.OPEN, 'stream', 'Stream', "/usr/streams" ) if dlg.ShowModal() == wx.ID_OK: # Check that's an existing stream if not dlg.node_exists(): msg = "There is no stream called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # remove the stream dlg2 = waitdlg.WaitDialog( self.get_frame(), "Removing stream '%s' ..." % dlg.get_guiname() ) dlg.get_node().removestream() dlg2.Destroy() dlg.Destroy()
def on_new_indoor_area(self, event): """Create new indoor loading area""" # Create a new indoor area dlg = nodelibdlg.NodeLibDialog( self.get_frame(), nodelibdlg.NEW, 'area', 'Area', "/usr/areas" ) if dlg.ShowModal() == wx.ID_OK: # Check that's a new stream name if dlg.node_exists(): msg = "There's already an area named" msg = msg + " '" + dlg.get_guiname() + "'.\n" msg = msg + "You should enter a new area name." cjr.show_error_message(msg) else: # create the new loading area obj = servers.get_loader_server().createloadarea( "nindoorarea", str( dlg.get_guiname() ) ) win = objdlg.create_window( wx.GetApp().GetTopWindow(), obj.getfullname() ) win.display() dlg.Destroy()
def on_open_stream(self, event): """Open geometry stream""" # Ask for the stream name if not pynebula.exists( str("/usr/streams") ): app.get_state("geometrystream").loadstreamlibrary() dlg = nodelibdlg.NodeLibDialog( self.get_frame(), nodelibdlg.OPEN, 'stream', 'Stream', "/usr/streams" ) if dlg.ShowModal() == wx.ID_OK: # Check that's an existing stream if not dlg.node_exists(): msg = "There is no stream called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # open the stream for editing win = objdlg.create_window( wx.GetApp().GetTopWindow(), dlg.get_node().getfullname() ) win.display() dlg.Destroy()
def on_create_stream(self, event): """Create geometry stream""" # Ask for the new stream name if not pynebula.exists( str("/usr/streams") ): app.get_state("geometrystream").loadstreamlibrary() dlg = nodelibdlg.NodeLibDialog( self.get_frame(), nodelibdlg.NEW, 'stream', 'Stream', "/usr/streams" ) if dlg.ShowModal() == wx.ID_OK: # Check that's a new stream name if dlg.node_exists(): msg = "There's already a stream named" msg = msg + " '" + dlg.get_guiname() + "'.\n" msg = msg + "You should enter a new stream name." cjr.show_error_message(msg) else: # create the new stream obj = app.get_state("geometrystream").createstream( str( dlg.get_guiname() ) ) win = objdlg.create_window( wx.GetApp().GetTopWindow(), obj.getfullname() ) win.display() dlg.Destroy()
def import_materials_to_outdoor(self, outdoor): terrain_class_name = self.get_selected_terrain_class_as_string() ec_server = servers.get_entity_class_server() source_outdoor = ec_server.getentityclass( terrain_class_name ) number_of_materials = source_outdoor.getnumberofgrowthmaterials() material_list = [] for each_index in range(number_of_materials): material = source_outdoor.getgrowthmaterialbyid(each_index) # do NOT add the default grass material since it cannot be imported if material.getname() != "Default": material_list.append(material) if len(material_list) == 0: cjr.show_error_message( "'%s' outdoor has no grass materials suitable for import." % terrain_class_name ) result = False else: dlg = MaterialsForImportSelectionDialog( self, outdoor, material_list ) result = ( dlg.ShowModal() == wx.ID_OK ) dlg.Destroy() return result
def on_ok(self, event): if not self.__has_valid_class_name(): cjr.show_error_message( "Invalid class name." ) return False new_name = self.__get_class_name().capitalize() global_lightmap_size = self.get_global_lightmap_resolution() dlg = waitdlg.WaitDialog( self.GetParent(), "Creating global terrain lightmap..." ) terrain = trn.get_terrain_module() result = terrain.createterraingloballightmap( new_name, global_lightmap_size ) # Closes dialog reporting OK dlg.Destroy() if result: cjr.show_information_message( "Successfully created global terrain lightmap %s" % new_name ) self.EndModal(wx.ID_OK) else: cjr.show_error_message( "Unable to create the global terrain lightmap" ) self.EndModal(wx.ID_OK)
def on_save_outdoor(self, event): """Save the outdoor's navigation mesh on a user specified file""" outdoor = app.get_outdoor_obj() if outdoor == None: cjr.show_error_message( "The current level doesn't have an outdoor" ) return dlg = wx.FileDialog( self.get_frame(), message="Enter a file name", wildcard="Navigation mesh ASCII file (*.txt)|*.txt|" \ "Navigation mesh binary file (*.nav)|*.nav|" \ "Navigation mesh compressed file (*.rle)|*.rle", defaultDir=format.mangle_path( "level:ai/" + \ hex(outdoor.getid())[2:] ), defaultFile="navmesh", style=wx.SAVE | wx.OVERWRITE_PROMPT ) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() # Append extension if needed if dlg.GetFilterIndex() == 0 and not path.endswith(".txt"): path = path + ".txt" elif dlg.GetFilterIndex() == 1 and not path.endswith(".nav"): path = path + ".nav" elif dlg.GetFilterIndex() == 2 and not path.endswith(".rle"): path = path + ".rle" # Save the navigation mesh navbuilder = app.get_navbuilder() if not navbuilder.saveoutdoornavmesh( str(dlg.GetPath()) ): msg = "Unable to save the navigation mesh file '%s'" % dlg.GetPath() cjr.show_error_message(msg) dlg.Destroy()
def edit_layer(self): if self.is_layer_locked(): cjr.show_error_message( "Unable to edit locked layer." ) else: result = self.handle_edit_layer_request()
def on_new_cmd(self, event): # Ask for a command prototype dlg = newcmddlg.NewCommandDialog(self) result_ok = dlg.ShowModal() == wx.ID_OK if result_ok: cmd_proto = dlg.get_command_prototype() dlg.Destroy() # Create and add the new command to the selected class if result_ok: # Get the class name for the new command class_name = self.tree_classes.get_selected_class_name() if class_name is None: cjr.show_error_message( "Cannot add commands to the selected class" ) return # Create an empty command for the selected class from a template self.__add_command( class_name, 'command', cmd_proto ) # Add the new command to the command list self.list_cmds.Append( cmd_proto ) servers.get_script_server().refreshclass( str(class_name) ) # Open for editing the new command script cmd_unpath = self.__get_cmd_path(class_name, cmd_proto, True) win = scripteditordlg.create_window( app.get_top_window(), cmd_unpath ) win.display()
def on_custom_texture(self, event): # Let the user choose a file from the shared textures mangled_shared_dir = format.mangle_path( "wc:export/textures" ) directory = guisettings.Repository.getsettingvalue( guisettings.ID_BrowserPath_SharedMaterial ) if directory == "": directory = mangled_shared_dir dlg = wx.FileDialog( self, message="Choose an image file", defaultDir = directory, wildcard="Image files (*.dds)|*.dds", style=wx.OPEN ) if dlg.ShowModal() == wx.ID_OK: mangled_path = format.mangle_path( dlg.GetPath() ) if not mangled_path.startswith( mangled_shared_dir ): msg = "You should choose a texture file from the" \ " directory 'wc:export/textures' or below." cjr.show_error_message(msg) else: self.set_custom_texture( format.get_relative_path( mangled_shared_dir, mangled_path ) ) # Record last directory directory = format.get_directory(mangled_path) guisettings.Repository.setsettingvalue( guisettings.ID_BrowserPath_SharedMaterial, directory ) dlg.Destroy()
def on_new_level(self, event): """Create a new level replacing the old one, if user confirms""" # Ask for the level's name dlg = filedlg.FileDialog( self.get_frame(), filedlg.NEW, 'level', 'Level', "wc:levels", ["n2"] ) if dlg.ShowModal() == wx.ID_OK: # Check that's a new filename if dlg.file_exists(): msg = "There is already a level called '%s'.\n\n" \ "Please enter a new level name." % dlg.get_guiname() cjr.show_error_message(msg) else: # Ask for final confirmation msg = "Any previous unsaved level data will be lost.\n\n" \ "Are you sure you want to create the new level '%s'?"\ % dlg.get_guiname() result = cjr.warn_yes_no( self.get_frame(), msg ) if result == wx.ID_YES: # Finally create the new level if prelevel_process(True): servers.get_conjurer().newlevel( dlg.get_path_as_string() ) postlevel_process(True) dlg.Destroy()
def on_add(self, event): event = self.text_event.GetValue() material = self.text_material.GetValue() sound_id = self.list_ids.GetStringSelection() parent = self.GetParent() for index in range( parent.list.GetItemCount() ): if parent.list.GetItem(index, parent.Col_Event).GetText() == event and \ parent.list.GetItem(index, parent.Col_Material).GetText() == material: cjr.show_error_message( "There's already another sound event with the" \ " name '" + event + "' and material '" + material + "'." ) return self.sound.safegetsoundtable().addsoundevent( str(event), str(material), str(sound_id) ) servers.get_entity_class_server().setentityclassdirty( self.sound, True ) index = parent.list.InsertStringItem( 0, event ) parent.list.SetStringItem( index, parent.Col_Material, material ) parent.list.SetStringItem( index, parent.Col_SoundId, sound_id ) self.EndModal(wx.ID_OK)
def on_ok(self, event): try: wx.BeginBusyCursor() emitter_name = str( self.get_new_class_name() ) if self.is_use_default_texture_selected(): emitter = particle2.add_emitter( self.particle_system, emitter_name ) else: texture = format.append_to_path( "wc:export/textures", self.get_custom_texture_name() ) emitter = particle2.add_emitter( self.particle_system, emitter_name, str(texture) ) if emitter is None: msg = "Unable to create '%s' particle emitter" % emitter_name cjr.show_error_message(msg) else: self.EndModal(wx.ID_OK) finally: wx.EndBusyCursor()
def on_import_sound(self, event): lib = servers.get_sound_library() groups = [] for index in range( lib.getnumberofsoundgroups() ): groups.append( lib.getsoundgroupname(index) ) dialog = wx.SingleChoiceDialog( self, "Select a group", "Select sound group", groups ) val = dialog.ShowModal() if val == wx.ID_OK: table = self.sound.safegetsoundtable() groupname = dialog.GetStringSelection() suc = table.importsoundgroup( str(groupname) ) if suc: servers.get_entity_class_server().setentityclassdirty( self.sound, True ) self.refresh() else: cjr.show_error_message( "%s group not found" % groupname ) dialog.Destroy()
def __on_ok(self, event): if self.sound_source_class == None: cjr.show_error_message( "Please select a sound source class from the list.") else: # Close dialog reporting OK self.EndModal(wx.ID_OK)
def on_new_material(self, event): # Ask for material name dlg = wx.TextEntryDialog( self, "Enter a material name", "New grass material" ) if dlg.ShowModal() == wx.ID_OK: name = str( dlg.GetValue() ) if name.strip() == "": cjr.show_error_message( "Please enter a name for the new grass material." ) else: # Validate name terrain = app.get_outdoor() if terrain.hasgrowthmaterialwithname(name): cjr.show_error_message( "There is already a grass material called '%s'." % name ) else: # Add new material terrain.creategrowthmaterial(name) self.__build_material_list() dlg.Destroy()
def __check_ai_not_active(self): if app.get_ai_tester().isgameplayupdatingenabled(): cjr.show_error_message( "Please switch off AI before closing Conjurer." ) return False else: return True
def __check_not_in_gameplay_mode(self): if app.is_in_gameplay_mode(): cjr.show_error_message( "Please exit gameplay mode before closing Conjurer." ) return False else: return True
def on_custom_script(self, event): # Try needed due to wxWidgets not removing/updating shortcuts properly try: scriptmgrdlg.run_script( self.custom_scripts[event.GetId()] ) except: cjr.show_error_message( "Please, restart Conjurer to run this script." )
def checkIfContainerObjectIsValid(self): if self.isContainerObjectValid(): return True else: cjr.show_error_message( "Unable to import - invalid object" ) return False
def on_import_entities(self, event): if self.layer_selected is None: cjr.show_error_message("Please select a layer") else: importentity.importEntitiesFromFile( self, self.get_id_for_selected_layer() )
def validate_fsm_name(name): path = format.append_to_path(fsm.get_fsms_lib(), name) try: # Lookup will fail if it's a new name (name not found) pynebula.lookup(path) msg = "Another finite state machine called '%s' already exists." % name cjr.show_error_message(msg) return False except: msg = "Renaming this FSM will invalidate any references to it that " \ "any agent has.\nAre you sure that you want to rename it?" result = cjr.confirm_yes_no(None, msg) return result == wx.ID_YES
def handle_edit_layer_request(self): if self.layer.requires_password(): dlg = wx.PasswordEntryDialog( self, "Enter password for %s" % self.layer.get_name(), "Password required") if dlg.ShowModal() == wx.ID_OK: password = str(dlg.GetValue()) password_ok = self.layer.check_password(password) if not password_ok: cjr.show_error_message("Password incorrect.") return False else: return False return True
def on_add_objective(self, event): dlg = ObjectiveDialog( self ) if dlg.ShowModal() == wx.ID_OK: name = dlg.get_name() desc = dlg.get_description() if self.__name_exists(name): cjr.show_error_message( "There's already an objective named '" \ + name + "'." ) else: self.entity.appendobjective( str(name), str(desc) ) self.list.Append( [name, desc] ) dlg.Destroy()
def on_loadselection(self, event): """Load a saved selection of entities """ dlg = wx.FileDialog(self.get_frame(), message="Choose a file", wildcard="Nebula2 file (*.n2)|*.n2", style=wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if not app.get_object_state().loadselectionfromfile(str(path)): msg = "Unable to load saved selection from file '%s'" % path cjr.show_error_message(msg) dlg.Destroy()
def on_add_to_area(self, event): """Add selection to loading area""" # select an area and add current selection to it dlg = nodelibdlg.NodeLibDialog(self.get_frame(), nodelibdlg.OPEN, 'area', 'Area', "/usr/areas") if dlg.ShowModal() == wx.ID_OK: # Check that's an existing area if not dlg.node_exists(): msg = "There is no area called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # assign selected entities to the area app.get_object_state().addtoloadarea(str(dlg.get_guiname())) dlg.Destroy()
def open_export_dialog(self): """Open an export dialog for the selected entities""" entity_list = self.get_selected_entities_ok_for_export() select_count = len(entity_list) if select_count > 0: dialog = expentdlg.createWindow( app.get_top_window(), entity_list ) dialog.ShowModal() dialog.Destroy() else: cjr.show_error_message( "There are no entities currently selected" )
def on_selected_entities(self, event): """Open a property editor on the selected entities""" entity_list = self.get_selected_entities() select_count = len(entity_list) if select_count > 1: model = scriptingmodelmultiobject.ScriptingModelMultiObject( entity_list) propertyview.create_window(self.get_frame(), model) elif select_count == 1: entity = entity_list[0] entity_id = entity.getid() win = objdlg.create_window(self.get_frame(), entity_id) win.display() else: cjr.show_error_message("There are no entities currently selected")
def on_ok(self, event): try: wx.BeginBusyCursor() new_class_name = str(self.get_new_class_name()) parent_class_name = str(self.get_parent_class_name()) entity_class_created = particle2.create_class( new_class_name, parent_class_name, self.target_library) if entity_class_created: self.EndModal(wx.ID_OK) else: msg = "Unable to create a particle system "\ "class called '%s'" % new_class_name cjr.show_error_message(msg) finally: wx.EndBusyCursor()
def load_windows(self): try: self.__open_input_file() except: cjr.show_error_message("Could not open input file '%s'" % self.file_name) return False try: try: self.__read_data_from_file() except: cjr.show_error_message("Error reading from input file '%s'" % self.file_name) finally: self.__close_input_file()
def on_new(self, event): """Ask for a name and create a new object it if it's a non existing name""" dlg = wx.TextEntryDialog( None, "Enter the " + self.caption + "'s name:", "New " + self.caption ) if dlg.ShowModal() == wx.ID_OK: # Add the object only if there isn't another object with the same name yet obj_path = format.append_to_path( self.lib_path, dlg.GetValue() ) try: # Lookup will fail if it's a new name (name not found) pynebula.lookup( obj_path ) msg = "Another " + self.caption + " named '" + dlg.GetValue() + "' already exists." cjr.show_error_message(msg) except: # Create object, save it to disk and add it to list obj = pynebula.new( str(self.class_name), str(obj_path) ) self.save_object( obj ) self.list.Append( dlg.GetValue() ) dlg.Destroy()
def on_save_level(self, event): """Save the current level, overwritting the old file""" level_name = get_name_of_current_level() if level_name == "default": cjr.show_error_message("The default level cannot be saved.") else: try: try: dlg = waitdlg.WaitDialog( self.get_frame(), "Saving '%s' level..." % level_name) if prelevel_process(False): servers.get_conjurer().savelevel() postlevel_process(False) finally: dlg.Destroy() except: raise # make sure any errors are not hidden
def on_saveselection(self, event): """Save a selection of entities for later use""" dlg = wx.FileDialog(self.get_frame(), message="Enter a file name", wildcard="Nebula2 file (*.n2)|*.n2", style=wx.SAVE | wx.OVERWRITE_PROMPT | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if dlg.GetFilterIndex() == 0 and not path.endswith(".n2"): path = path + ".n2" if not app.get_object_state().saveselectiontofile(str(path)): msg = "Unable to save the selection to file '%s'" % path cjr.show_error_message(msg) dlg.Destroy()
def on_generate_grass_dirty(self, event): """Generate terrain grass, only dirty""" level_manager = servers.get_level_manager() level_name = level_manager.getcurrentlevelobject().getname() if level_name == "default": cjr.show_error_message( "Unable to generate grass for default level.") else: dlg = waitdlg.WaitDialog(self.get_frame(), "Generating grass...") terrain = app.get_outdoor() editing = terrain.isingrowthedition() if not editing: terrain.begingrowthediton() terrain.buildonlydirtygrowth() if not editing: terrain.endgrowtedition(False) dlg.Destroy()
def on_ok(self, event): # Verify that has been given a valid class name name = str(self.text_classname.GetValue().capitalize()) if not servers.get_entity_class_server().checkclassname(name): cjr.show_error_message("Invalid class name.") return # get lightmap size lightmap_size = self.get_lightmap_resolution() # get lightmap size shadowmap_size = self.get_shadowmap_resolution() # get the global lightmap size global_lightmap_size = self.get_global_lightmap_resolution() # get light id lightid = app.get_level().findentity("terrain_lightmap_light") distance = self.text_ctrl_distance.get_value() offset_u = self.text_ctrl_offset_u.get_value() offset_v = self.text_ctrl_offset_v.get_value() aaliasing = self.text_ctrl_aaliasing.get_value() overwrite = self.checkbox_overwrite.IsChecked() # if light not found if lightid == 0: cjr.show_information_message( "Please use the 'Select lightmap light' " \ "option to select the light" ) return # Create the terrain class dlg = waitdlg.WaitDialog(self.GetParent(), "Creating terrain lightmap...") terrain = trn.get_terrain_module() terrain.createterrainlightmaps(name, lightmap_size, shadowmap_size, global_lightmap_size, lightid, overwrite, distance, offset_u, offset_v, aaliasing) # Closes dialog reporting OK dlg.Destroy() self.EndModal(wx.ID_OK)
def select_entity_in_summoner(self, idx): """ Select entity in Summoner. Return true if selected OK, otherwise false.""" entity_id = self.__get_entity_id_for_row(idx) entity = self.__get_entity_with_id(entity_id) if self.can_entity_be_selected_in_summoner(entity): if app.is_terrain_cell_mode_active(): cjr.show_error_message( "Entity %s cannot be selected in Summoner "\ "when in terrain cell mode." % entity_id ) return False else: app.get_object_state().addentitytoselection(entity_id) return True else: return False
def on_open_area(self, event): """Open loading area""" # Ask for the area name if pynebula.exists(str("/usr/areas")): dlg = nodelibdlg.NodeLibDialog(self.get_frame(), nodelibdlg.OPEN, 'area', 'Area', "/usr/areas") if dlg.ShowModal() == wx.ID_OK: # Check that's an existing area if not dlg.node_exists(): msg = "There is no area called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # open the area for edition win = objdlg.create_window(wx.GetApp().GetTopWindow(), dlg.get_node().getfullname()) win.display() dlg.Destroy()
def create_new_lib(self, position): wildcard = "Library files (*.n2)|*.n2" # Show file dialog dlg = wx.FileDialog(self.GetGrandParent(), message="Create library", wildcard=wildcard, style=wx.SAVE | wx.CHANGE_DIR | wx.OVERWRITE_PROMPT, pos=position) # get the selected file if dlg.ShowModal() == wx.ID_OK: root = app.get_libraries() new_library_path = root.getfullname() + "/" + dlg.GetFilename() new_library_path, ext = os.path.splitext(new_library_path) # test extension if ext != ".n2": cjr.show_error_message( "Bad extension: must be .n2. Try again.") else: # create object and save to disk save = True if pynebula.exists(str(new_library_path)): dlg2_result = cjr.warn_yes_no( "You are using a library with the same name."\ "\n\n Are you sure you want to delete it?" ) if dlg2_result == wx.ID_NO: save = False else: pynebula.delete(str(new_library_path)) if save: library = pynebula.new("nstringlist", new_library_path) path_string = str(dlg.GetPath()) library.saveas(path_string) foo, lib_name = os.path.split(new_library_path) self.files[lib_name] = [path_string, False] self.expand_tree(new_library_path.replace('/editor/', '')) dlg.Destroy()
def handle_lock_layer_request(self, should_lock): # do nothing if already in the required state if self.layer.is_locked() == should_lock: return True if self.layer.requires_password(): dlg = wx.PasswordEntryDialog( self, "Enter password for %s" % self.layer.get_name(), "Password required") if dlg.ShowModal() == wx.ID_OK: password = str(dlg.GetValue()) password_ok = self.layer.check_password(password) if not password_ok: cjr.show_error_message("Password incorrect.") return False else: return False self.layer.set_locked(should_lock) return True
def on_add_resource(self, event): """Ask the user for a new resource to add in the preload list""" resource_type = self.choice_type.GetSelection() resource_label = self.ResourceLabel[resource_type] dlg = wx.TextEntryDialog(self, "Enter %s to preload" % resource_label, "Add %s" % resource_label) if dlg.ShowModal() == wx.ID_OK: resource = dlg.GetValue() if resource != "": if self.resource_lists[resource_type].count(resource) == 0: self.resource_lists[resource_type].append(resource) self.listbox_resources.Append(resource) else: cjr.show_error_message( resource_label.capitalize() + \ " already exist" ) dlg.Destroy()
def save_windows(self): try: self.__open_output_file() except: cjr.show_error_message("Could not open output file '%s'" % self.file_name) return False try: try: self.__write_data_to_file() except: cjr.show_error_message("Error writing to output file '%s'" % self.file_name) return False finally: self.__close_output_file() return True
def on_edit_brush(self, event): brush_id = self.__currently_selected_brush_id() if brush_id == None: cjr.show_error_message( "No brush selected. Please choose a brush from the list." ) else: brush = self.material.getgrowthbrush( brush_id ) model = scriptingmodelsingleobject.new_scripting_model_for_object( brush ) dlg = propertyview.PropertyViewDialog( self, "Brush '%s'" % brush.getname(), model ) dlg.ShowModal() dlg.Destroy()
def on_load_temp_mesh(self, event): """Show a file browser and load the selected navigation mesh file as the temporary mesh""" dlg = wx.FileDialog( self.get_frame(), message="Choose a file", wildcard= "Navigation mesh files (*.txt,*.nav,*.rle)|*.txt;*.nav;*.rle", style=wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: navbuilder = app.get_navbuilder() if not navbuilder.loadnavmesh(str(dlg.GetPath())): msg = "Unable to load navigation mesh file '%s'" % dlg.GetPath( ) cjr.show_error_message(msg) dlg.Destroy()
def on_ok(self, event): try: wx.BeginBusyCursor() emitter_name = str(self.get_new_class_name()) if self.is_use_default_texture_selected(): emitter = particle2.add_emitter(self.particle_system, emitter_name) else: texture = format.append_to_path("wc:export/textures", self.get_custom_texture_name()) emitter = particle2.add_emitter(self.particle_system, emitter_name, str(texture)) if emitter is None: msg = "Unable to create '%s' particle emitter" % emitter_name cjr.show_error_message(msg) else: self.EndModal(wx.ID_OK) finally: wx.EndBusyCursor()
def on_delete_anim(self, event): index = self.list.GetSelection() if index != wx.NOT_FOUND: name = self.list.GetStringSelection() msg = "Deleting an animation cannot be undone.\n\n" \ "Are you sure you want to delete the animation %s'?" % name delete = cjr.confirm_yes_no(None, msg) if delete == wx.ID_YES: anim_index = self.anim_indices[index] deleted = self.character.removeanimstate( anim_index[1], anim_index[0]) if not deleted: cjr.show_error_message( "Cannot delete the '%s' animation.\n" \ "Maybe is it active on some character?" % name ) else: self.deleted_anim_index = anim_index self.EndModal(wx.ID_OK)
def on_delete_brush(self, event): index = self.list_brushes.GetSelection() if index == wx.NOT_FOUND: cjr.show_error_message( "No brush selected. Please choose a brush from the list." ) else: # Ask for confirmation name = self.list_brushes.GetString(index) msg = "Are you sure you want to delete the '%s' grass brush?" \ % name result = cjr.confirm_yes_no(self, msg) if result == wx.ID_YES: # Delete brush brush_id = self.list_brushes.GetClientData(index) self.material.deletegrowthbrush(brush_id) # We need to update the brush list # since the indexing may have changed self.__update_brushes_list()
def on_ok(self, event): outdoor = app.get_outdoor() if outdoor is None: cjr.show_error_message("The level has no terrain instance.") return if self.has_terrain_class_selected(): # Import terrain materials try: dlg = waitdlg.WaitDialog(self.GetParent(), self.importing_materials_text()) imported_ok = self.import_materials_to_outdoor(outdoor) finally: dlg.Destroy() if imported_ok: # Closes dialog reporting OK self.EndModal(wx.ID_OK) else: cjr.show_error_message( "Please select a terrain class from the list.")
def on_move_entities(self, event): if self.layer_selected is None: cjr.show_error_message("Please select a layer") else: layer_id = self.get_id_for_selected_layer() obj_state = app.get_object_state() items_were_moved = False for i in range(obj_state.getselectioncount()): entity = obj_state.getselectedentity(i) if entity.hascomponent('ncEditor'): entity.setlayerid(layer_id) e_server = servers.get_entity_object_server() e_server.setentityobjectdirty(entity, True) items_were_moved = True if not items_were_moved: cjr.show_error_message( "There are no entities currently selected "\ "that can be moved to this layer" )
def on_select_lightmap_light(self, event): # get light num_entities = app.get_object_state().getselectioncount() lightid = -1 for i in xrange(num_entities): entity = app.get_object_state().getselectedentity(i) if entity.isa("nelight"): lightid = entity.getid() break # if light not found if lightid == -1: cjr.show_error_message( "No nelight instance found as lightmap light source") return # if found create in the level app.get_level().setentityname(lightid, "terrain_lightmap_light") cjr.show_information_message("Terrain lightmap light selected")
def on_import_sound(self, event): lib = servers.get_sound_library() groups = [] for index in range(lib.getnumberofsoundgroups()): groups.append(lib.getsoundgroupname(index)) dialog = wx.SingleChoiceDialog(self, "Select a group", "Select sound group", groups) val = dialog.ShowModal() if val == wx.ID_OK: table = self.sound.safegetsoundtable() groupname = dialog.GetStringSelection() suc = table.importsoundgroup(str(groupname)) if suc: servers.get_entity_class_server().setentityclassdirty( self.sound, True) self.refresh() else: cjr.show_error_message("%s group not found" % groupname) dialog.Destroy()
def on_open_stream(self, event): """Open geometry stream""" # Ask for the stream name if not pynebula.exists(str("/usr/streams")): app.get_state("geometrystream").loadstreamlibrary() dlg = nodelibdlg.NodeLibDialog(self.get_frame(), nodelibdlg.OPEN, 'stream', 'Stream', "/usr/streams") if dlg.ShowModal() == wx.ID_OK: # Check that's an existing stream if not dlg.node_exists(): msg = "There is no stream called '%s'" % dlg.get_guiname() cjr.show_error_message(msg) else: # open the stream for editing win = objdlg.create_window(wx.GetApp().GetTopWindow(), dlg.get_node().getfullname()) win.display() dlg.Destroy()