def check_input(self): """Checks if all input fields have valid flag, and changes program state if needed. Should be called after an input field updates. :return: None """ if self.ldraw_name_isvalid and self.stl_path_isvalid: if UIDriver.application_state != ApplicationState.WAITING_GO: UIDriver.fire_event(UserEvent( UserEventType.INPUT_VALID, LogMessage(LogType.IGNORE, ""))) else: if UIDriver.application_state != ApplicationState.WAITING_INPUT: UIDriver.fire_event(UserEvent( UserEventType.INPUT_INVALID, LogMessage(LogType.IGNORE, ""))) # Set colors if self.ldraw_name_isvalid: self.ldraw_name_input.SetBackgroundColour(UIStyle.metadata_input_valid_background) else: self.ldraw_name_input.SetBackgroundColour(UIStyle.metadata_input_invalid_background) if self.stl_path_isvalid: self.stl_path_input.SetBackgroundColour(UIStyle.metadata_input_valid_background) else: self.stl_path_input.SetBackgroundColour(wx.Colour(UIStyle.metadata_input_invalid_background))
def update(self): # Do whatever you want to have done for each iteration of the event # loop. In this example we'll just sleep a bit to simulate something # real happening. current = time.time() if current - self.last >= 0.00833333334: UIDriver.update(current - self.last) self.last = current
def convert(self, event): """Convert the selected STL file into an LDraw file. :param event: The wx event that was recorded. :return: None """ UIDriver.fire_event( UserEvent( UserEventType.CONVERSION_STARTED, LogMessage(LogType.INFORMATION, "Conversion process started..")))
def cancel(self, event): """Cancel the conversion operation. :param event: The wx event that was recorded. :return: None """ UIDriver.fire_event( UserEvent( UserEventType.CONVERSION_CANCELED, LogMessage(LogType.INFORMATION, "Conversion process canceled.")))
def on_wire_frame_pressed(self, event): """Send an event that the wire frame button was pressed. The OpenGLCanvas will detect and react accordingly. :param event: The wxpython event that occured. :return: None """ UIDriver.fire_event( UserEvent( UserEventType.RENDERING_WIRE_FRAME_PRESSED, BoolMessage(LogType.DEBUG, "Wire frame checkbox pressed.", self.cb_wire_frame.GetValue()))) event.Skip()
def on_mouse_wheel(self, event): """Called when the user scrolls with the mouse wheel. We will notify all panels of the mouse wheel instance. :param event: The wxpython Event. :return: None """ if ModelShipper.input_model is not None: self.scene.on_mouse_wheel(event) UIDriver.fire_event( UserEvent( UserEventType.RENDERING_MOUSE_WHEEL_EVENT, FloatMessage(LogType.IGNORE, "Mouse Moved", self.scene.get_camera_distance_to_origin())))
def text_ctrl_output_on_kill_focus(self, event): """Called when the output text control loses focus. :param event: The event that occurred. :return: None. """ output_text = self.ldraw_name_input.GetValue() if len(output_text) <= 0: self.ldraw_name_input.SetValue("Browse output -->") if len(self.ldraw_name_input.GetValue()) > 0: self.ldraw_name_input.SetBackgroundColour(UIStyle.metadata_input_valid_background) UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.ERROR, "Output file path cannot be blank."))) event.Skip()
def save_log(self, event): """ Save the feedback log to a file :param event: :return: """ try: UIDriver.fire_event( UserEvent(UserEventType.RENDERING_CANVAS_DISABLE, LogMessage(LogType.IGNORE, ""))) with open(SettingsManager.file_path, "r") as file: file_settings = json.load(file) part_name = file_settings["part_name"] log_dir = file_settings["log_dir"] log_name = part_name.split(".")[0] + ".txt" dialog = wx.FileDialog(self, "Choose a log save location", defaultFile=log_name, defaultDir=log_dir, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, wildcard="*.txt") if dialog.ShowModal() == wx.ID_OK: pathname = dialog.GetPath() directory = dialog.GetDirectory() # Check if the new directory is different the old one. If so update the settings file. if log_dir != directory: SettingsManager.save_settings("log_dir", directory) try: log_file = open(pathname, mode="w") log_file.write(self.log_text_ctrl.GetValue()) log_file.close() except IOError: pass finally: pass UIDriver.fire_event( UserEvent(UserEventType.RENDERING_CANVAS_ENABLE, LogMessage(LogType.IGNORE, ""))) dialog.Destroy() except IOError: pass
def text_ctrl_input_on_kill_focus(self, event): """Get the path for STL input file from user typing into TextCtrl element. :param event: :return: """ prev_text = self.stl_path_text self.stl_path_text = self.stl_path_input.GetValue() self.stl_path_input.SetValue(MetadataPanel.reduce_text_path(self.stl_path_input.GetValue())) if prev_text != self.stl_path_text: # Check file path validity if Util.is_file(self.stl_path_text): if self.stl_path_text.endswith('.stl'): # Check if this .stl is valid mesh = ModelShipper.load_stl_model(self.stl_path_text) if mesh: # Load in LDraw object to input model ModelShipper.input_model = LDrawModel(mesh) self.stl_dir = Util.get_parent(self.stl_path_text) # Only the dir SettingsManager.save_settings("stl_dir", self.stl_dir) self.stl_path_isvalid = True UIDriver.fire_event( UserEvent(UserEventType.INPUT_MODEL_READY, LogMessage(LogType.INFORMATION, "Input file loaded from: '" + self.stl_path_text + "'."))) else: self.stl_path_isvalid = False UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.ERROR, "The input file '" + self.stl_path_text + "' is not a valid STL file."))) else: self.stl_path_isvalid = False UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.ERROR, "Input file must have .stl extension."))) else: self.stl_path_isvalid = False if len(self.stl_path_text) <=0: log_msg = "Input filepath cannot be blank." else: log_msg = "The path '" + self.stl_path_text + "' could not be found." UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.ERROR, log_msg))) self.check_input() event.Skip()
def __init__(self): """Default constructor for LScan class. """ wx.App.__init__(self) self.main_loop = None root_frame = MainFrame() root_frame.Show() self.ui_driver = UIDriver(root_frame)
def text_ctrl_license_on_kill_focus(self, event): """Get the license value from the user and update the settings file as needed.""" license_input_text = self.license_input.GetValue() # Update settings file license info if license_input_text != self.license_text and license_input_text != "": self.license_text = license_input_text UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.INFORMATION, "License changed to: " + self.license_text))) SettingsManager.save_settings("license", self.license_text) elif len(license_input_text) == 0: self.reset_license() event.Skip()
def browse_input(self, event): """Browse for a valid STL input file. :param event: :return: """ UIDriver.fire_event(UserEvent( UserEventType.RENDERING_CANVAS_DISABLE, LogMessage(LogType.IGNORE, ""))) stl_wildcard = "*.stl" dialog = wx.FileDialog(self, "Choose a STL file", defaultDir=self.stl_dir, wildcard=stl_wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) if dialog.ShowModal() == wx.ID_OK: filename = dialog.GetPath() # Check for file existing # If valid, pass to worker thread who will check data if self.stl_path_text != filename: self.stl_path_input.SetValue(filename) self.stl_path_input.SetValue(MetadataPanel.reduce_text_path(self.stl_path_input.GetValue())) # Only update stuff if selection changed # Check if this .stl is valid mesh = ModelShipper.load_stl_model(filename) if mesh: # Load in LDraw object to input model ModelShipper.input_model = LDrawModel(mesh) self.stl_dir = Util.get_parent(filename) # Only the dir self.stl_path_text = filename # The whole path to file self.stl_path_isvalid = True SettingsManager.save_settings("stl_dir", self.stl_dir) UIDriver.fire_event( UserEvent(UserEventType.INPUT_MODEL_READY, LogMessage(LogType.INFORMATION, "Input file loaded from: '" + self.stl_path_text + "'."))) else: self.stl_path_isvalid = False UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.ERROR, "The input file '" + filename + "' is not a valid STL file."))) self.check_input() UIDriver.fire_event(UserEvent( UserEventType.RENDERING_CANVAS_ENABLE, LogMessage(LogType.IGNORE, ""))) dialog.Destroy()
def pause_resume(self, event): """Pause/resume the conversion process. :param event: The wx event that was recorded. :return: None """ self.is_paused = not self.is_paused if self.is_paused: self.pause_button.SetLabelText('Resume') UIDriver.fire_event( UserEvent( UserEventType.CONVERSION_PAUSED, LogMessage(LogType.INFORMATION, "Conversion process paused."))) else: self.pause_button.SetLabelText('Pause') UIDriver.fire_event( UserEvent( UserEventType.CONVERSION_RESUMED, LogMessage(LogType.INFORMATION, "Conversion process resumed.")))
def text_ctrl_author_on_kill_focus(self, event): """Get the author value from the user and update the settings file as needed. :param event: The event that occurred. :return: None """ author = self.author_input.GetValue() # Update settings file author info if author != self.author_text and author != "": self.author_text = author UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.INFORMATION, "Author changed to: " + self.author_text))) SettingsManager.save_settings("author", self.author_text) elif len(author) == 0: self.reset_author() event.Skip()
def about(self, event): """Presents program name, program version, copyright information, licensing information, and authors to user. :param event: :return: """ about_text = UIDriver.get_assets_file_text("ABOUT.txt") if about_text is not None: self.popup = Popup(self.GetTopLevelParent(), "About", about_text) else: self.popup = Popup(self.GetTopLevelParent(), "Error", "Could not read about text file, sorry.") self.help_button.Disable() self.about_button.Disable() self.popup.Show(True) self.popup.Bind(wx.EVT_CLOSE, self.popup_on_close)
def save(self, event): """Save the finalized conversion of the input file. Hide main window options and replace them with metadata options. Once the user finalizes their metadata options (back or save), they return to the original options. :param event: The wx event that was recorded. :return: None """ self.save_button.Disable() with open(SettingsManager.file_path, "r") as file: file_settings = json.load(file) part_dir = file_settings["part_dir"] part_name = file_settings["part_name"] file_path = Util.path_conversion(part_dir + "/" + part_name) with open(file_path, "w") as text_file: text_file.write(ModelShipper.get_metadata() + ModelShipper.output_data_text) self.save_button.Enable() UIDriver.fire_event( UserEvent( UserEventType.LOG_INFO, LogMessage(LogType.INFORMATION, "File was saved to '" + file_path + "'.")))
def help(self, event): """Presents program limitations, common troubleshooting steps, and steps to update LDraw parts library. :param event: :return: """ help_text = UIDriver.get_assets_file_text("HELP.txt") if help_text is not None: self.popup = Popup(self.GetTopLevelParent(), "Help", help_text) else: self.popup = Popup(self.GetTopLevelParent(), "Error", "Could not read help text file, sorry.") self.help_button.Disable() self.about_button.Disable() self.popup.Show(True) self.popup.Bind(wx.EVT_CLOSE, self.popup_on_close)
def browse_output(self, event): """Browse for a valid output file path :param event: :return: """ UIDriver.fire_event(UserEvent( UserEventType.RENDERING_CANVAS_DISABLE, LogMessage(LogType.IGNORE, ""))) dat_wildcard = "*.dat" dialog = wx.FileDialog(self, "Choose a location for the LDraw file", defaultDir=self.part_dir, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, wildcard=dat_wildcard) dialog.SetFilename(self.part_name) if dialog.ShowModal() == wx.ID_OK: pathname = dialog.GetPath() if self.out_file != pathname: # Check if part name ends with .dat, if not append that if not pathname.endswith('.dat'): pathname = pathname + '.dat' self.out_file = pathname # Full path self.part_dir = Util.get_parent(pathname) # Only the dir self.part_name = Util.get_filename(pathname) # Only filename self.ldraw_name_isvalid = True SettingsManager.save_settings("part_dir", self.part_dir) SettingsManager.save_settings("part_name", self.part_name) self.ldraw_name_input.SetValue(self.out_file) self.ldraw_name_input.SetValue(MetadataPanel.reduce_text_path(self.ldraw_name_input.GetValue())) self.check_input() UIDriver.fire_event( UserEvent(UserEventType.LOG_INFO, LogMessage(LogType.INFORMATION, "Output file will be saved as: '" + self.out_file + "'."))) UIDriver.fire_event(UserEvent( UserEventType.RENDERING_CANVAS_ENABLE, LogMessage(LogType.IGNORE, ""))) dialog.Destroy()
def testReadAssetsFileAboutText(self): about_text = UIDriver.get_assets_file_text("ABOUT.txt") self.assertIsNotNone(about_text) # The about text file should always contain the MIT License. # This way we can make sure the about text file contains the information we expect. self.assertTrue(about_text.find("MIT License") != -1)
def testReadAssetsFileNotExist(self): no_text = UIDriver.get_assets_file_text( "THIS_FILE_SERIOUSLY_SHOULD_NOT_EXISTS.txt") self.assertIsNone(no_text)
def testReadAssetsFileHelpText(self): help_text = UIDriver.get_assets_file_text("HELP.txt") self.assertIsNotNone(help_text) # The help text file probably will always contain the LDraw word. # This way we can make sure the help text contains the information we expect. self.assertTrue(help_text.find("LDraw") != -1)