class GeometryEditMode(BaseEditMode): # states ES_Move = BaseEditMode.ES_Count + 1 ES_LineCreate = ES_Move + 1 ES_CircleCreate = ES_LineCreate + 1 ES_LengthChange = ES_CircleCreate + 1 ES_Count = ES_LengthChange + 1 def __init__(self, _logic): BaseEditMode.__init__(self, _logic, "Geometry edit") # last scroll position self.last_scroll_pos = None # grid align mode self.grid_align = True self.mouse_pos = (0, 0) # objects we works with self.highlighted_obj = None # current edit state self.state = GeometryEditMode.ES_None # current object we worked with self.active_object = None # line creation mode self.__pointSpirit = GeometryPoint() self.__pointSpirit.setState(Object.OS_Normal) self.__pointSpirit.setScale(ogre.Vector3(0.5, 0.5, 0.5)) self.__lineSpirit = GeometryLineSection() self.__lineSpirit.setState(Object.OS_Normal) self.__lineSpirit.setEnd(self.__pointSpirit) self.__lineBegin = None def __del__(self): BaseEditMode.__del__(self) def _highlight(self): """Highlighting object under mouse """ mobjects = self._logic._getSheet()._getObjectsUnderMouse(self.mouse_pos) obj = None if len(mobjects) > 0: obj = mobjects[0][1] if (obj is None) and (self.highlighted_obj is None): return if (obj is self.highlighted_obj): return # change highlight if self.highlighted_obj: self.highlighted_obj.resetState() # if self.highlighted_obj._getSelected(): # self.highlighted_obj.setState(Object.OS_Selected) # else: # self.highlighted_obj.setState(Object.OS_Normal) self.highlighted_obj = obj if self.highlighted_obj: self.highlighted_obj.setState(Object.OS_Highlighted) def _getMousePos(self, _state): """Returns mouse position based on state and align mode @return: mouse position @rtype: tuple(int, int) """ if self.grid_align: return self._logic.positionMouseToGrid((_state.X.abs, _state.Y.abs)) else: return (_state.X.abs, _state.Y.abs) def _onMouseMoved(self, _evt): """Mouse moved notification event """ if BaseEditMode._onMouseMoved(self, _evt): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) self.mouse_pos = (mstate.X.abs, mstate.Y.abs) if self.state is GeometryEditMode.ES_Move: self.active_object.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) return True elif self.state is GeometryEditMode.ES_LineCreate: self.__pointSpirit.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() self._highlight() return True elif self.state is GeometryEditMode.ES_CircleCreate: radius = self.active_object.getPosition().distance(render_engine.pos2dTo3dIsoPos(mpos)) self.active_object.setRadius(radius) self._highlight() return False def _onMousePressed(self, _evt, _id): """Event on mouse button pressed """ if BaseEditMode._onMousePressed(self, _evt, _id): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) # getting objects under mouse mobjects = self._logic._getSheet()._getObjectsUnderMouse(True, True, self.mouse_pos) if _id == ois.MB_Right: # none any mode if self.state is GeometryEditMode.ES_None: # creating point if there is no any objects under mouse if len(mobjects) is 0: obj = self._logic.createPoint(mpos) sheet = self._logic._getSheet() sheet.addChild(obj) return True else: obj = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if obj is not None: self.state = GeometryEditMode.ES_LineCreate self.__lineSpirit.setBegin(obj) sheet = self._logic._getSheet() sheet.sceneNodeChilds.addChild(self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.addChild(self.__pointSpirit.sceneNode) self.__lineBegin = obj self.__pointSpirit.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() return True # on line creation mode finishing line elif self.state is GeometryEditMode.ES_LineCreate: obj = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) sheet = self._logic._getSheet() if obj is not None: # creating line line = self._logic.createLineSection(self.__lineBegin, obj) sheet.addChild(line) # removing state self.state = GeometryEditMode.ES_None sheet.sceneNodeChilds.removeChild(self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.removeChild(self.__pointSpirit.sceneNode) self.__lineBegin = None elif _id == ois.MB_Left: # if there is an any object under mouse, then starts moving if len(mobjects) > 0 and self.state is GeometryEditMode.ES_None: self.active_object = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if self.active_object is not None: self.state = GeometryEditMode.ES_Move self._selectObject(self.active_object) else: # selecting first object under mouse self._selectObject(mobjects[0][1]) return True elif self.state is GeometryEditMode.ES_CircleCreate: self.active_object = None self.state = GeometryEditMode.ES_None return False def _onMouseReleased(self, _evt, _id): """Event on mouse button released """ if BaseEditMode._onMouseReleased(self, _evt, _id): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) if _id == ois.MB_Left: # moving state finishing if self.state is GeometryEditMode.ES_Move: self.state = GeometryEditMode.ES_None # self._selectObject(self.active_object) self.active_object = None return False def _onKeyPressed(self, _evt): """Event on key pressed """ if _evt.key == ois.KC_DELETE: return True if BaseEditMode._onKeyPressed(self, _evt): return True key = _evt.key if key == ois.KC_C and isinstance(self._logic._getSheet().getSelected()[0], GeometryPoint): self.state = GeometryEditMode.ES_CircleCreate self.active_object = self._logic.createCircle(self._logic._getSheet().getSelected()[0], 3.0) self._logic._getSheet().addChild(self.active_object) if key == ois.KC_T: selected = self._logic._getSheet().getSelected() if len(selected) == 3: # check if selected objects are lines lines = True for obj in selected: if not isinstance(obj, GeometryLineSection): lines = False if lines: triangle = self._logic.createTriangle(selected) self._logic._getSheet().addChild(triangle) if key == ois.KC_L: selected = self._logic._getSheet().getSelected() if len(selected) > 0 and isinstance(selected[0], GeometryLineSection): self.state = GeometryEditMode.ES_LengthChange self.length_changer = TextInput(selected[0], self._length_change_callback, str(selected[0].getLength())) return False def _onKeyReleased(self, _evt): """Event key released """ if BaseEditMode._onKeyReleased(self, _evt): return True return False def _length_change_callback(self, _object, _value): """Callback on line length changing """ self.state = GeometryEditMode.ES_None if _value is not None: try: v = float(str(_value)) _object.setLength(v) except ValueError: print "Non-numeric value found %s" % str(_value) del self.length_changer def _updateLineSpirits(self): """Updates spirit objects used in line creation mode """ self.__pointSpirit.needUpdate = True self.__pointSpirit._update(0) self.__lineSpirit.needUpdate = True self.__lineSpirit._update(0)
class GeometryEditMode(BaseEditMode): # states ES_Move, \ ES_LineCreate, \ ES_CircleCreate, \ ES_LengthChange, \ ES_RadiusChange, \ ES_DiameterChange, \ ES_SquareChange, \ ES_PerimeterChange, \ ES_Count = range(BaseEditMode.ES_Count + 1, BaseEditMode.ES_Count + 10) # label used for removing property if user inputs this value label_to_clear_property = "" def __init__(self, _logic): BaseEditMode.__init__(self, _logic, "Geometry edit") # last scroll position self.last_scroll_pos = None # grid align mode self.grid_align = True self.mouse_pos = (0, 0) self.objectInfoPanel = geom_controls.ObjectInfoPanel() # objects we works with self.highlighted_obj = None # current edit state self.state = GeometryEditMode.ES_None # current object we worked with self.active_object = None # candidate object to be processed with mouse self.candidate_object = None # line creation mode self.__pointSpirit = GeometryPoint() self.__pointSpirit.setState(Object.OS_Normal) self.__pointSpirit.setScale(ogre.Vector3(0.5, 0.5, 0.5)) self.__lineSpirit = GeometryLineSection() self.__lineSpirit.setState(Object.OS_Normal) self.__lineSpirit.setEnd(self.__pointSpirit) self.__lineBegin = None def __del__(self): BaseEditMode.__del__(self) def delete(self): self.objectInfoPanel.delete() BaseEditMode.delete(self) def activate(self): BaseEditMode.activate(self) def deactivate(self): BaseEditMode.deactivate(self) def _onRootChanged(self, _isRoot): BaseEditMode._onRootChanged(self, _isRoot) self.objectInfoPanel.setVisible(_isRoot) def _selectObject(self, _object): BaseEditMode._selectObject(self, _object) self.objectInfoPanel.setObject(_object) def _unselectObject(self, _object): BaseEditMode._unselectObject(self, _object) selected = self._logic._getSheet().getSelected() if len(selected) > 0: self.objectInfoPanel.setObject(selected[-1]) else: self.objectInfoPanel.setObject(None) def _highlight(self): """Highlighting object under mouse """ mobjects = self._logic._getSheet()._getObjectsUnderMouse(self.mouse_pos) obj = None if len(mobjects) > 0: obj = mobjects[0][1] if (obj is None) and (self.highlighted_obj is None): return if (obj is self.highlighted_obj): return # change highlight if self.highlighted_obj: self.highlighted_obj.resetState() # if self.highlighted_obj._getSelected(): # self.highlighted_obj.setState(Object.OS_Selected) # else: # self.highlighted_obj.setState(Object.OS_Normal) self.highlighted_obj = obj if self.highlighted_obj: self.highlighted_obj.setState(Object.OS_Highlighted) def _getMousePos(self, _state): """Returns mouse position based on state and align mode @return: mouse position @rtype: tuple(int, int) """ if self.grid_align: return self._logic.positionMouseToGrid((_state.X.abs, _state.Y.abs)) else: return (_state.X.abs, _state.Y.abs) def _onMouseMoved(self, _evt): """Mouse moved notification event """ if BaseEditMode._onMouseMoved(self, _evt): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) self.mouse_pos = (mstate.X.abs, mstate.Y.abs) if self.state is GeometryEditMode.ES_Move: self.active_object.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) return True elif self.state is GeometryEditMode.ES_LineCreate: self.__pointSpirit.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() self._highlight() return True elif self.state is GeometryEditMode.ES_CircleCreate: radius = self.active_object.getPosition().distance(render_engine.pos2dTo3dIsoPos(mpos)) self.active_object.setRadius(radius) self._highlight() return False def _onMousePressed(self, _evt, _id): """Event on mouse button pressed """ if BaseEditMode._onMousePressed(self, _evt, _id): return True mstate = _evt.get_state() original_mpos = (mstate.X.abs, mstate.Y.abs) mpos = self._getMousePos(mstate) # getting objects under mouse mobjects = self._logic._getSheet()._getObjectsUnderMouse(True, True, self.mouse_pos) if _id == ois.MB_Right: # none any mode if self.state is GeometryEditMode.ES_None: # creating point if there is no any objects under mouse if len(mobjects) is 0: obj = self._logic.createPoint(mpos) sheet = self._logic._getSheet() sheet.addChild(obj) return True else: # get line sections line = comutils._getFirstObjectTypeFromList(mobjects, [GeometryLineSection, GeometryCircle]) if line is not None: # create point point = self._logic.createPoint(original_mpos) sheet = self._logic._getSheet() sheet.addChild(point) # append it into line section line.addPoint(point, line._calculatePointRelPosition(render_engine.pos2dTo3dIsoPos(original_mpos))) self.objectInfoPanel.update() return True obj = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if obj is not None: self.state = GeometryEditMode.ES_LineCreate self.__lineSpirit.setBegin(obj) sheet = self._logic._getSheet() sheet.sceneNodeChilds.addChild(self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.addChild(self.__pointSpirit.sceneNode) self.__lineBegin = obj self.__pointSpirit.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() self.objectInfoPanel.update() return True # on line creation mode finishing line elif self.state is GeometryEditMode.ES_LineCreate: obj = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) sheet = self._logic._getSheet() if obj is not None: # creating line line = self._logic.createLineSection(self.__lineBegin, obj) sheet.addChild(line) # removing state self.state = GeometryEditMode.ES_None sheet.sceneNodeChilds.removeChild(self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.removeChild(self.__pointSpirit.sceneNode) self.__lineBegin = None elif _id == ois.MB_Left: # if there is an any object under mouse, then starts moving if len(mobjects) > 0 and self.state is GeometryEditMode.ES_None: if self.candidate_object is not None and self.candidate_object._getSelected() and not self._shift: self._unselectObject(self.candidate_object) self._next_candidate() self.active_object = self.candidate_object#comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if self.active_object is not None: self.state = GeometryEditMode.ES_Move self._selectObject(self.active_object) else: # selecting first object under mouse self._selectObject(mobjects[0][1]) return True elif self.state is GeometryEditMode.ES_CircleCreate: _point = comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if _point is not None: self.active_object.setRadiusPoint(_point) self.active_object = None self.state = GeometryEditMode.ES_None return False def _onMouseReleased(self, _evt, _id): """Event on mouse button released """ if BaseEditMode._onMouseReleased(self, _evt, _id): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) if _id == ois.MB_Left: # moving state finishing if self.state is GeometryEditMode.ES_Move: self.state = GeometryEditMode.ES_None # self._selectObject(self.active_object) self.active_object = None return False def _onKeyPressed(self, _evt): """Event on key pressed """ if BaseEditMode._onKeyPressed(self, _evt): return True key = _evt.key if key == ois.KC_C: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createCircle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_A: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createAngle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_T: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createTriangle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_Q: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createQuadrangle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_L: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(selected[0], (GeometryLineSection, GeometryCircle)): self.state = GeometryEditMode.ES_LengthChange self.length_changer = TextInput(obj, self._length_change_callback, obj.getPropertyValue(GeometryAbstractObject.PropLength)) if key == ois.KC_E: selected = self._logic._getSheet().getSelected() if len(selected) == 2: if isinstance(selected[0], selected[1].__class__): selected[0].setEqualTo(selected[1]) if self.objectInfoPanel.getObject() is selected[0] or self.objectInfoPanel.getObject() is selected[1]: self.objectInfoPanel.update() #remove figure's congruence property if key == ois.KC_W: selected = self._logic._getSheet().getSelected() if len(selected) == 2: if isinstance(selected[0], selected[1].__class__): selected[0].removeCongruency(selected[1]) if self.objectInfoPanel.getObject() is selected[0] or self.objectInfoPanel.getObject() is selected[1]: self.objectInfoPanel.update() if key == ois.KC_S: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, (GeometryCircle, GeometryTriangle, GeometryQuadrangle)): self.state = GeometryEditMode.ES_SquareChange self.square_changer = TextInput(obj, self._square_change_callback, obj.getPropertyValue(GeometryAbstractObject.PropSquare)) if key == ois.KC_P: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, (GeometryTriangle, GeometryQuadrangle)): self.state = GeometryEditMode.ES_PerimeterChange self.perimetr_changer = TextInput(obj, self._perimeter_change_callback, obj.getPropertyValue(GeometryAbstractObject.PropPerimeter)) if key == ois.KC_R: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, GeometryCircle): self.state = GeometryEditMode.ES_RadiusChange self.radius_changer = TextInput(obj, self._radius_change_callback, obj.getPropertyValue(GeometryAbstractObject.PropRadius)) if key == ois.KC_D: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, GeometryCircle): self.state = GeometryEditMode.ES_DiameterChange self.diameter_changer = TextInput(obj, self._diameter_change_callback, obj.getPropertyValue(GeometryAbstractObject.PropDiameter)) return False def _onKeyReleased(self, _evt): """Event key released """ if BaseEditMode._onKeyReleased(self, _evt): return True return False def _next_candidate(self): """Find next candidate object for mouse processing """ mobjects = self._logic._getSheet()._getObjectsUnderMouse(True, True, self.mouse_pos) self.candidate_object = self._get_next_from_mouse_object_list(self.candidate_object, mobjects) def _prev_candidate(self): """Find previous candidate object for mouse processing """ mobjects = self._logic._getSheet()._getObjectsUnderMouse(True, True, self.mouse_pos) self.candidate_object = self._get_prev_from_mouse_object_list(self.candidate_object, mobjects) def _length_change_callback(self, _object, _value): """Callback on line length changing """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropLength) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropLength, v) del self.length_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _square_change_callback(self, _object, _value): """Callback on square change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropSquare) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropSquare, v) del self.square_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _perimeter_change_callback(self, _object, _value): """Callback on perimeter change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropPerimeter) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropPerimeter, v) del self.perimetr_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _radius_change_callback(self, _object, _value): """Callback on radius change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropRadius) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropRadius, v) del self.radius_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _diameter_change_callback(self, _object, _value): """Callback on diameter change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropDiameter) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropDiameter, v) del self.diameter_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _updateLineSpirits(self): """Updates spirit objects used in line creation mode """ self.__pointSpirit.needUpdate = True self.__pointSpirit._update(0) self.__lineSpirit.needUpdate = True self.__lineSpirit._update(0) def _objectDeleted(self, obj): """Notification about object deletion """ if self.candidate_object is obj: self.candidate_object = None if self.objectInfoPanel.getObject() is obj: self.objectInfoPanel.setObject(None) def _check_in_mouse_object_list(self, _obj, _list): """Check if specified object is in mouse object list @param _obj: object for check @param _list: List of tuples for objects, that are under mouse """ for v, obj in _list: if obj is _obj: return True return False def _get_next_from_mouse_object_list(self, _obj, _list): """Return object that placed after \p _obj in mouse object list. If it's a last object, then first object will be returned @param _obj: object to get next @param _list: List of tuples for objects, that are under mouse """ ret = False for v, obj in _list: if ret is True: return obj if _obj is obj: ret = True if len(_list) == 0: return None return _list[0][1] def _get_prev_from_mouse_object_list(self, _obj, _list): """Return object that placed before \p _obj in mouse object list. If it's a first object, then last object will be returned @param _obj: object to get previous @param _list: List of tuples for objects, that are under mouse """ prev = None for v, obj in _list: if _obj is obj: return prev prev = obj if len(_list) > 0: prev = _list[len(_list) - 1][1] return prev
class GeometryEditMode(BaseEditMode): # states ES_Move, \ ES_LineCreate, \ ES_CircleCreate, \ ES_LengthChange, \ ES_RadiusChange, \ ES_DiameterChange, \ ES_SquareChange, \ ES_PerimeterChange, \ ES_Count = range(BaseEditMode.ES_Count + 1, BaseEditMode.ES_Count + 10) # label used for removing property if user inputs this value label_to_clear_property = "" def __init__(self, _logic): BaseEditMode.__init__(self, _logic, "Geometry edit") # last scroll position self.last_scroll_pos = None # grid align mode self.grid_align = True self.mouse_pos = (0, 0) self.objectInfoPanel = geom_controls.ObjectInfoPanel() # objects we works with self.highlighted_obj = None # current edit state self.state = GeometryEditMode.ES_None # current object we worked with self.active_object = None # candidate object to be processed with mouse self.candidate_object = None # line creation mode self.__pointSpirit = GeometryPoint() self.__pointSpirit.setState(Object.OS_Normal) self.__pointSpirit.setScale(ogre.Vector3(0.5, 0.5, 0.5)) self.__lineSpirit = GeometryLineSection() self.__lineSpirit.setState(Object.OS_Normal) self.__lineSpirit.setEnd(self.__pointSpirit) self.__lineBegin = None def __del__(self): BaseEditMode.__del__(self) def delete(self): self.objectInfoPanel.delete() BaseEditMode.delete(self) def activate(self): BaseEditMode.activate(self) def deactivate(self): BaseEditMode.deactivate(self) def _onRootChanged(self, _isRoot): BaseEditMode._onRootChanged(self, _isRoot) self.objectInfoPanel.setVisible(_isRoot) def _selectObject(self, _object): BaseEditMode._selectObject(self, _object) self.objectInfoPanel.setObject(_object) def _unselectObject(self, _object): BaseEditMode._unselectObject(self, _object) selected = self._logic._getSheet().getSelected() if len(selected) > 0: self.objectInfoPanel.setObject(selected[-1]) else: self.objectInfoPanel.setObject(None) def _highlight(self): """Highlighting object under mouse """ mobjects = self._logic._getSheet()._getObjectsUnderMouse( self.mouse_pos) obj = None if len(mobjects) > 0: obj = mobjects[0][1] if (obj is None) and (self.highlighted_obj is None): return if (obj is self.highlighted_obj): return # change highlight if self.highlighted_obj: self.highlighted_obj.resetState() # if self.highlighted_obj._getSelected(): # self.highlighted_obj.setState(Object.OS_Selected) # else: # self.highlighted_obj.setState(Object.OS_Normal) self.highlighted_obj = obj if self.highlighted_obj: self.highlighted_obj.setState(Object.OS_Highlighted) def _getMousePos(self, _state): """Returns mouse position based on state and align mode @return: mouse position @rtype: tuple(int, int) """ if self.grid_align: return self._logic.positionMouseToGrid( (_state.X.abs, _state.Y.abs)) else: return (_state.X.abs, _state.Y.abs) def _onMouseMoved(self, _evt): """Mouse moved notification event """ if BaseEditMode._onMouseMoved(self, _evt): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) self.mouse_pos = (mstate.X.abs, mstate.Y.abs) if self.state is GeometryEditMode.ES_Move: self.active_object.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) return True elif self.state is GeometryEditMode.ES_LineCreate: self.__pointSpirit.setPosition(render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() self._highlight() return True elif self.state is GeometryEditMode.ES_CircleCreate: radius = self.active_object.getPosition().distance( render_engine.pos2dTo3dIsoPos(mpos)) self.active_object.setRadius(radius) self._highlight() return False def _onMousePressed(self, _evt, _id): """Event on mouse button pressed """ if BaseEditMode._onMousePressed(self, _evt, _id): return True mstate = _evt.get_state() original_mpos = (mstate.X.abs, mstate.Y.abs) mpos = self._getMousePos(mstate) # getting objects under mouse mobjects = self._logic._getSheet()._getObjectsUnderMouse( True, True, self.mouse_pos) if _id == ois.MB_Right: # none any mode if self.state is GeometryEditMode.ES_None: # creating point if there is no any objects under mouse if len(mobjects) is 0: obj = self._logic.createPoint(mpos) sheet = self._logic._getSheet() sheet.addChild(obj) return True else: # get line sections line = comutils._getFirstObjectTypeFromList( mobjects, [GeometryLineSection, GeometryCircle]) if line is not None: # create point point = self._logic.createPoint(original_mpos) sheet = self._logic._getSheet() sheet.addChild(point) # append it into line section line.addPoint( point, line._calculatePointRelPosition( render_engine.pos2dTo3dIsoPos(original_mpos))) self.objectInfoPanel.update() return True obj = comutils._getFirstObjectTypeFromList( mobjects, [GeometryPoint]) if obj is not None: self.state = GeometryEditMode.ES_LineCreate self.__lineSpirit.setBegin(obj) sheet = self._logic._getSheet() sheet.sceneNodeChilds.addChild( self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.addChild( self.__pointSpirit.sceneNode) self.__lineBegin = obj self.__pointSpirit.setPosition( render_engine.pos2dTo3dIsoPos(mpos)) self._updateLineSpirits() self.objectInfoPanel.update() return True # on line creation mode finishing line elif self.state is GeometryEditMode.ES_LineCreate: obj = comutils._getFirstObjectTypeFromList( mobjects, [GeometryPoint]) sheet = self._logic._getSheet() if obj is not None: # creating line line = self._logic.createLineSection(self.__lineBegin, obj) sheet.addChild(line) # removing state self.state = GeometryEditMode.ES_None sheet.sceneNodeChilds.removeChild(self.__lineSpirit.sceneNode) sheet.sceneNodeChilds.removeChild(self.__pointSpirit.sceneNode) self.__lineBegin = None elif _id == ois.MB_Left: # if there is an any object under mouse, then starts moving if len(mobjects) > 0 and self.state is GeometryEditMode.ES_None: if self.candidate_object is not None and self.candidate_object._getSelected( ) and not self._shift: self._unselectObject(self.candidate_object) self._next_candidate() self.active_object = self.candidate_object #comutils._getFirstObjectTypeFromList(mobjects, [GeometryPoint]) if self.active_object is not None: self.state = GeometryEditMode.ES_Move self._selectObject(self.active_object) else: # selecting first object under mouse self._selectObject(mobjects[0][1]) return True elif self.state is GeometryEditMode.ES_CircleCreate: _point = comutils._getFirstObjectTypeFromList( mobjects, [GeometryPoint]) if _point is not None: self.active_object.setRadiusPoint(_point) self.active_object = None self.state = GeometryEditMode.ES_None return False def _onMouseReleased(self, _evt, _id): """Event on mouse button released """ if BaseEditMode._onMouseReleased(self, _evt, _id): return True mstate = _evt.get_state() mpos = self._getMousePos(mstate) if _id == ois.MB_Left: # moving state finishing if self.state is GeometryEditMode.ES_Move: self.state = GeometryEditMode.ES_None # self._selectObject(self.active_object) self.active_object = None return False def _onKeyPressed(self, _evt): """Event on key pressed """ if BaseEditMode._onKeyPressed(self, _evt): return True key = _evt.key if key == ois.KC_C: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createCircle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_A: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createAngle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_T: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createTriangle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_Q: _selected = self._logic._getSheet().getSelected() self.active_object = self._logic.createQuadrangle() if self.active_object.makeBasedOnObjects(_selected): self._logic._getSheet().addChild(self.active_object) else: self.active_object.delete() self.active_object = None if key == ois.KC_L: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(selected[0], (GeometryLineSection, GeometryCircle)): self.state = GeometryEditMode.ES_LengthChange self.length_changer = TextInput( obj, self._length_change_callback, obj.getPropertyValue( GeometryAbstractObject.PropLength)) if key == ois.KC_E: selected = self._logic._getSheet().getSelected() if len(selected) == 2: if isinstance(selected[0], selected[1].__class__): selected[0].setEqualTo(selected[1]) if self.objectInfoPanel.getObject( ) is selected[0] or self.objectInfoPanel.getObject( ) is selected[1]: self.objectInfoPanel.update() #remove figure's congruence property if key == ois.KC_W: selected = self._logic._getSheet().getSelected() if len(selected) == 2: if isinstance(selected[0], selected[1].__class__): selected[0].removeCongruency(selected[1]) if self.objectInfoPanel.getObject( ) is selected[0] or self.objectInfoPanel.getObject( ) is selected[1]: self.objectInfoPanel.update() if key == ois.KC_S: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance( obj, (GeometryCircle, GeometryTriangle, GeometryQuadrangle)): self.state = GeometryEditMode.ES_SquareChange self.square_changer = TextInput( obj, self._square_change_callback, obj.getPropertyValue( GeometryAbstractObject.PropSquare)) if key == ois.KC_P: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, (GeometryTriangle, GeometryQuadrangle)): self.state = GeometryEditMode.ES_PerimeterChange self.perimetr_changer = TextInput( obj, self._perimeter_change_callback, obj.getPropertyValue( GeometryAbstractObject.PropPerimeter)) if key == ois.KC_R: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, GeometryCircle): self.state = GeometryEditMode.ES_RadiusChange self.radius_changer = TextInput( obj, self._radius_change_callback, obj.getPropertyValue( GeometryAbstractObject.PropRadius)) if key == ois.KC_D: selected = self._logic._getSheet().getSelected() if len(selected) == 1: obj = selected[0] if isinstance(obj, GeometryCircle): self.state = GeometryEditMode.ES_DiameterChange self.diameter_changer = TextInput( obj, self._diameter_change_callback, obj.getPropertyValue( GeometryAbstractObject.PropDiameter)) return False def _onKeyReleased(self, _evt): """Event key released """ if BaseEditMode._onKeyReleased(self, _evt): return True return False def _next_candidate(self): """Find next candidate object for mouse processing """ mobjects = self._logic._getSheet()._getObjectsUnderMouse( True, True, self.mouse_pos) self.candidate_object = self._get_next_from_mouse_object_list( self.candidate_object, mobjects) def _prev_candidate(self): """Find previous candidate object for mouse processing """ mobjects = self._logic._getSheet()._getObjectsUnderMouse( True, True, self.mouse_pos) self.candidate_object = self._get_prev_from_mouse_object_list( self.candidate_object, mobjects) def _length_change_callback(self, _object, _value): """Callback on line length changing """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropLength) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropLength, v) del self.length_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _square_change_callback(self, _object, _value): """Callback on square change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropSquare) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropSquare, v) del self.square_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _perimeter_change_callback(self, _object, _value): """Callback on perimeter change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropPerimeter) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropPerimeter, v) del self.perimetr_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _radius_change_callback(self, _object, _value): """Callback on radius change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropRadius) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropRadius, v) del self.radius_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _diameter_change_callback(self, _object, _value): """Callback on diameter change """ self.state = GeometryEditMode.ES_None # if user inputs value equal to label, remove property if str(_value) == self.label_to_clear_property: _object.removeProperty(GeometryAbstractObject.PropDiameter) elif _value is not None: v = None try: v = float(str(_value)) except ValueError: print "Non-numeric value found %s" % str(_value) if v is not None: _object.setPropertyValue(GeometryAbstractObject.PropDiameter, v) del self.diameter_changer if self.objectInfoPanel.getObject() is _object: self.objectInfoPanel.update() def _updateLineSpirits(self): """Updates spirit objects used in line creation mode """ self.__pointSpirit.needUpdate = True self.__pointSpirit._update(0) self.__lineSpirit.needUpdate = True self.__lineSpirit._update(0) def _objectDeleted(self, obj): """Notification about object deletion """ if self.candidate_object is obj: self.candidate_object = None if self.objectInfoPanel.getObject() is obj: self.objectInfoPanel.setObject(None) def _check_in_mouse_object_list(self, _obj, _list): """Check if specified object is in mouse object list @param _obj: object for check @param _list: List of tuples for objects, that are under mouse """ for v, obj in _list: if obj is _obj: return True return False def _get_next_from_mouse_object_list(self, _obj, _list): """Return object that placed after \p _obj in mouse object list. If it's a last object, then first object will be returned @param _obj: object to get next @param _list: List of tuples for objects, that are under mouse """ ret = False for v, obj in _list: if ret is True: return obj if _obj is obj: ret = True if len(_list) == 0: return None return _list[0][1] def _get_prev_from_mouse_object_list(self, _obj, _list): """Return object that placed before \p _obj in mouse object list. If it's a first object, then last object will be returned @param _obj: object to get previous @param _list: List of tuples for objects, that are under mouse """ prev = None for v, obj in _list: if _obj is obj: return prev prev = obj if len(_list) > 0: prev = _list[len(_list) - 1][1] return prev