You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1042 lines
34 KiB

Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
11 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
11 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
11 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
  5. * Copyright (C) 2013-2015 CERN
  6. * Copyright (C) 2012-2022 KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  9. * @author Maciej Suminski <maciej.suminski@cern.ch>
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * as published by the Free Software Foundation; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, you may find one here:
  23. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  24. * or you may search the http://www.gnu.org website for the version 2 license,
  25. * or you may write to the Free Software Foundation, Inc.,
  26. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  27. */
  28. #include <pgm_base.h>
  29. #include <profile.h>
  30. #include <view/view.h>
  31. #include <view/wx_view_controls.h>
  32. #include <view/zoom_controller.h>
  33. #include <gal/graphics_abstraction_layer.h>
  34. #include <tool/tool_dispatcher.h>
  35. #include <trace_helpers.h>
  36. #include <settings/common_settings.h>
  37. #include <math/util.h> // for KiROUND
  38. #include <geometry/geometry_utils.h>
  39. #include <widgets/ui_common.h>
  40. #include <class_draw_panel_gal.h>
  41. #include <eda_draw_frame.h>
  42. #include <kiway.h>
  43. #include <kiplatform/ui.h>
  44. #include <wx/log.h>
  45. #ifdef __WXMSW__
  46. #define USE_MOUSE_CAPTURE
  47. #endif
  48. using namespace KIGFX;
  49. const wxEventType WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE = wxNewEventType();
  50. static std::unique_ptr<ZOOM_CONTROLLER> GetZoomControllerForPlatform( bool aAcceleration )
  51. {
  52. #ifdef __WXMAC__
  53. // On Apple pointer devices, wheel events occur frequently and with
  54. // smaller rotation values. For those devices, let's handle zoom
  55. // based on the rotation amount rather than the time difference.
  56. return std::make_unique<CONSTANT_ZOOM_CONTROLLER>( CONSTANT_ZOOM_CONTROLLER::MAC_SCALE );
  57. #elif __WXGTK3__
  58. // GTK3 is similar, but the scale constant is smaller
  59. return std::make_unique<CONSTANT_ZOOM_CONTROLLER>( CONSTANT_ZOOM_CONTROLLER::GTK3_SCALE );
  60. #else
  61. if( aAcceleration )
  62. return std::make_unique<ACCELERATING_ZOOM_CONTROLLER>();
  63. else
  64. return std::make_unique<CONSTANT_ZOOM_CONTROLLER>( CONSTANT_ZOOM_CONTROLLER::MSW_SCALE );
  65. #endif
  66. }
  67. WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, EDA_DRAW_PANEL_GAL* aParentPanel ) :
  68. VIEW_CONTROLS( aView ),
  69. m_state( IDLE ),
  70. m_parentPanel( aParentPanel ),
  71. m_scrollScale( 1.0, 1.0 ),
  72. #ifdef __WXGTK3__
  73. m_lastTimestamp( 0 ),
  74. #endif
  75. m_cursorPos( 0, 0 ),
  76. m_updateCursor( true )
  77. {
  78. LoadSettings();
  79. m_MotionEventCounter = std::make_unique<PROF_COUNTER>( "Mouse motion events" );
  80. m_parentPanel->Connect( wxEVT_MOTION,
  81. wxMouseEventHandler( WX_VIEW_CONTROLS::onMotion ), nullptr, this );
  82. #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
  83. m_parentPanel->Connect( wxEVT_MAGNIFY,
  84. wxMouseEventHandler( WX_VIEW_CONTROLS::onMagnify ), nullptr, this );
  85. #endif
  86. m_parentPanel->Connect( wxEVT_MOUSEWHEEL,
  87. wxMouseEventHandler( WX_VIEW_CONTROLS::onWheel ), nullptr, this );
  88. m_parentPanel->Connect( wxEVT_MIDDLE_UP,
  89. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  90. m_parentPanel->Connect( wxEVT_MIDDLE_DOWN,
  91. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  92. m_parentPanel->Connect( wxEVT_LEFT_UP,
  93. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  94. m_parentPanel->Connect( wxEVT_LEFT_DOWN,
  95. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  96. m_parentPanel->Connect( wxEVT_RIGHT_UP,
  97. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  98. m_parentPanel->Connect( wxEVT_RIGHT_DOWN,
  99. wxMouseEventHandler( WX_VIEW_CONTROLS::onButton ), nullptr, this );
  100. #if defined __WXMSW__
  101. m_parentPanel->Connect( wxEVT_ENTER_WINDOW,
  102. wxMouseEventHandler( WX_VIEW_CONTROLS::onEnter ), nullptr, this );
  103. #endif
  104. m_parentPanel->Connect( wxEVT_LEAVE_WINDOW,
  105. wxMouseEventHandler( WX_VIEW_CONTROLS::onLeave ), nullptr, this );
  106. m_parentPanel->Connect( wxEVT_SCROLLWIN_THUMBTRACK,
  107. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  108. m_parentPanel->Connect( wxEVT_SCROLLWIN_PAGEUP,
  109. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  110. m_parentPanel->Connect( wxEVT_SCROLLWIN_PAGEDOWN,
  111. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  112. m_parentPanel->Connect( wxEVT_SCROLLWIN_BOTTOM,
  113. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  114. m_parentPanel->Connect( wxEVT_SCROLLWIN_TOP,
  115. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  116. m_parentPanel->Connect( wxEVT_SCROLLWIN_LINEUP,
  117. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  118. m_parentPanel->Connect( wxEVT_SCROLLWIN_LINEDOWN,
  119. wxScrollWinEventHandler( WX_VIEW_CONTROLS::onScroll ), nullptr, this );
  120. #if defined USE_MOUSE_CAPTURE
  121. m_parentPanel->Connect( wxEVT_MOUSE_CAPTURE_LOST,
  122. wxMouseEventHandler( WX_VIEW_CONTROLS::onCaptureLost ), nullptr, this );
  123. #endif
  124. m_cursorWarped = false;
  125. m_panTimer.SetOwner( this );
  126. this->Connect( wxEVT_TIMER, wxTimerEventHandler( WX_VIEW_CONTROLS::onTimer ), nullptr, this );
  127. m_settings.m_lastKeyboardCursorPositionValid = false;
  128. m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
  129. m_settings.m_lastKeyboardCursorCommand = 0;
  130. }
  131. WX_VIEW_CONTROLS::~WX_VIEW_CONTROLS()
  132. {
  133. #if defined USE_MOUSE_CAPTURE
  134. if( m_parentPanel->HasCapture() )
  135. m_parentPanel->ReleaseMouse();
  136. #endif
  137. }
  138. void WX_VIEW_CONTROLS::LoadSettings()
  139. {
  140. COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
  141. m_settings.m_warpCursor = cfg->m_Input.center_on_zoom;
  142. m_settings.m_focusFollowSchPcb = cfg->m_Input.focus_follow_sch_pcb;
  143. m_settings.m_autoPanSettingEnabled = cfg->m_Input.auto_pan;
  144. m_settings.m_autoPanAcceleration = cfg->m_Input.auto_pan_acceleration;
  145. m_settings.m_horizontalPan = cfg->m_Input.horizontal_pan;
  146. m_settings.m_zoomAcceleration = cfg->m_Input.zoom_acceleration;
  147. m_settings.m_zoomSpeed = cfg->m_Input.zoom_speed;
  148. m_settings.m_zoomSpeedAuto = cfg->m_Input.zoom_speed_auto;
  149. m_settings.m_scrollModifierZoom = cfg->m_Input.scroll_modifier_zoom;
  150. m_settings.m_scrollModifierPanH = cfg->m_Input.scroll_modifier_pan_h;
  151. m_settings.m_scrollModifierPanV = cfg->m_Input.scroll_modifier_pan_v;
  152. m_settings.m_dragLeft = cfg->m_Input.drag_left;
  153. m_settings.m_dragMiddle = cfg->m_Input.drag_middle;
  154. m_settings.m_dragRight = cfg->m_Input.drag_right;
  155. m_zoomController.reset();
  156. if( cfg->m_Input.zoom_speed_auto )
  157. {
  158. m_zoomController = GetZoomControllerForPlatform( cfg->m_Input.zoom_acceleration );
  159. }
  160. else
  161. {
  162. if( cfg->m_Input.zoom_acceleration )
  163. {
  164. m_zoomController =
  165. std::make_unique<ACCELERATING_ZOOM_CONTROLLER>( cfg->m_Input.zoom_speed );
  166. }
  167. else
  168. {
  169. double scale = CONSTANT_ZOOM_CONTROLLER::MANUAL_SCALE_FACTOR * cfg->m_Input.zoom_speed;
  170. m_zoomController = std::make_unique<CONSTANT_ZOOM_CONTROLLER>( scale );
  171. }
  172. }
  173. }
  174. void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
  175. {
  176. ( *m_MotionEventCounter )++;
  177. bool isAutoPanning = false;
  178. int x = aEvent.GetX();
  179. int y = aEvent.GetY();
  180. VECTOR2D mousePos( x, y );
  181. // Automatic focus switching between SCH and PCB windows on canvas mouse motion
  182. if( m_settings.m_focusFollowSchPcb )
  183. {
  184. if( EDA_DRAW_FRAME* frame = m_parentPanel->GetParentEDAFrame() )
  185. {
  186. KIWAY_PLAYER* otherFrame = nullptr;
  187. if( frame->IsType( FRAME_PCB_EDITOR ) )
  188. {
  189. otherFrame = frame->Kiway().Player( FRAME_SCH, false );
  190. }
  191. else if( frame->IsType( FRAME_SCH ) )
  192. {
  193. otherFrame = frame->Kiway().Player( FRAME_PCB_EDITOR, false );
  194. }
  195. if( otherFrame && KIPLATFORM::UI::IsWindowActive( otherFrame )
  196. && !KIPLATFORM::UI::IsWindowActive( frame ) )
  197. {
  198. frame->Raise();
  199. }
  200. }
  201. }
  202. if( m_state != DRAG_PANNING && m_state != DRAG_ZOOMING )
  203. handleCursorCapture( x, y );
  204. if( m_settings.m_autoPanEnabled && m_settings.m_autoPanSettingEnabled )
  205. isAutoPanning = handleAutoPanning( aEvent );
  206. if( !isAutoPanning && aEvent.Dragging() )
  207. {
  208. if( m_state == DRAG_PANNING )
  209. {
  210. static bool justWarped = false;
  211. int warpX = 0;
  212. int warpY = 0;
  213. wxSize parentSize = m_parentPanel->GetClientSize();
  214. if( x < 0 )
  215. {
  216. warpX = parentSize.x;
  217. }
  218. else if(x >= parentSize.x )
  219. {
  220. warpX = -parentSize.x;
  221. }
  222. if( y < 0 )
  223. {
  224. warpY = parentSize.y;
  225. }
  226. else if( y >= parentSize.y )
  227. {
  228. warpY = -parentSize.y;
  229. }
  230. if( !justWarped )
  231. {
  232. VECTOR2D d = m_dragStartPoint - mousePos;
  233. m_dragStartPoint = mousePos;
  234. VECTOR2D delta = m_view->ToWorld( d, false );
  235. m_view->SetCenter( m_view->GetCenter() + delta );
  236. aEvent.StopPropagation();
  237. }
  238. if( warpX || warpY )
  239. {
  240. if( !justWarped )
  241. {
  242. KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY );
  243. m_dragStartPoint += VECTOR2D( warpX, warpY );
  244. justWarped = true;
  245. }
  246. else
  247. justWarped = false;
  248. }
  249. else
  250. justWarped = false;
  251. }
  252. else if( m_state == DRAG_ZOOMING )
  253. {
  254. static bool justWarped = false;
  255. int warpY = 0;
  256. wxSize parentSize = m_parentPanel->GetClientSize();
  257. if( y < 0 )
  258. {
  259. warpY = parentSize.y;
  260. }
  261. else if( y >= parentSize.y )
  262. {
  263. warpY = -parentSize.y;
  264. }
  265. if( !justWarped )
  266. {
  267. VECTOR2D d = m_dragStartPoint - mousePos;
  268. m_dragStartPoint = mousePos;
  269. double scale = exp( d.y * m_settings.m_zoomSpeed * 0.001 );
  270. wxLogTrace( traceZoomScroll, wxString::Format( "dy: %f scale: %f", d.y, scale ) );
  271. m_view->SetScale( m_view->GetScale() * scale, m_view->ToWorld( m_zoomStartPoint ) );
  272. aEvent.StopPropagation();
  273. }
  274. if( warpY )
  275. {
  276. if( !justWarped )
  277. {
  278. KIPLATFORM::UI::WarpPointer( m_parentPanel, x, y + warpY );
  279. m_dragStartPoint += VECTOR2D( 0, warpY );
  280. justWarped = true;
  281. }
  282. else
  283. justWarped = false;
  284. }
  285. else
  286. justWarped = false;
  287. }
  288. }
  289. if( m_updateCursor ) // do not update the cursor position if it was explicitly set
  290. m_cursorPos = GetClampedCoords( m_view->ToWorld( mousePos ) );
  291. else
  292. m_updateCursor = true;
  293. aEvent.Skip();
  294. }
  295. void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
  296. {
  297. #ifdef __WXGTK3__
  298. if( aEvent.GetTimestamp() == m_lastTimestamp )
  299. {
  300. aEvent.Skip( false );
  301. return;
  302. }
  303. m_lastTimestamp = aEvent.GetTimestamp();
  304. #endif
  305. const double wheelPanSpeed = 0.001;
  306. const int axis = aEvent.GetWheelAxis();
  307. if( axis == wxMOUSE_WHEEL_HORIZONTAL && !m_settings.m_horizontalPan )
  308. return;
  309. // Pick the modifier, if any. Shift beats control beats alt, we don't support more than one.
  310. int modifiers =
  311. aEvent.ShiftDown() ? WXK_SHIFT :
  312. ( aEvent.ControlDown() ? WXK_CONTROL : ( aEvent.AltDown() ? WXK_ALT : 0 ) );
  313. // Restrict zoom handling to the vertical axis, otherwise horizontal
  314. // scrolling events (e.g. touchpads and some mice) end up interpreted
  315. // as vertical scroll events and confuse the user.
  316. if( axis == wxMOUSE_WHEEL_VERTICAL && modifiers == m_settings.m_scrollModifierZoom )
  317. {
  318. const int rotation = aEvent.GetWheelRotation();
  319. const double zoomScale = m_zoomController->GetScaleForRotation( rotation );
  320. if( IsCursorWarpingEnabled() )
  321. {
  322. CenterOnCursor();
  323. m_view->SetScale( m_view->GetScale() * zoomScale );
  324. }
  325. else
  326. {
  327. const VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) );
  328. m_view->SetScale( m_view->GetScale() * zoomScale, anchor );
  329. }
  330. // Refresh the zoom level and mouse position on message panel
  331. // (mouse position has not changed, only the zoom level has changed):
  332. refreshMouse( true );
  333. }
  334. else
  335. {
  336. // Scrolling
  337. VECTOR2D scrollVec = m_view->ToWorld( m_view->GetScreenPixelSize(), false ) *
  338. ( (double) aEvent.GetWheelRotation() * wheelPanSpeed );
  339. double scrollX = 0.0;
  340. double scrollY = 0.0;
  341. if( axis == wxMOUSE_WHEEL_HORIZONTAL || modifiers == m_settings.m_scrollModifierPanH )
  342. scrollX = scrollVec.x;
  343. else
  344. scrollY = -scrollVec.y;
  345. VECTOR2D delta( scrollX, scrollY );
  346. m_view->SetCenter( m_view->GetCenter() + delta );
  347. refreshMouse( true );
  348. }
  349. // Do not skip this event, otherwise wxWidgets will fire
  350. // 3 wxEVT_SCROLLWIN_LINEUP or wxEVT_SCROLLWIN_LINEDOWN (normal wxWidgets behavior)
  351. // and we do not want that.
  352. m_parentPanel->Refresh();
  353. }
  354. #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
  355. void WX_VIEW_CONTROLS::onMagnify( wxMouseEvent& aEvent )
  356. {
  357. // Scale based on the magnification from our underlying magnification event.
  358. VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) );
  359. m_view->SetScale( m_view->GetScale() * ( aEvent.GetMagnification() + 1.0f ), anchor );
  360. aEvent.Skip();
  361. }
  362. #endif
  363. void WX_VIEW_CONTROLS::setState( STATE aNewState )
  364. {
  365. m_state = aNewState;
  366. }
  367. void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
  368. {
  369. switch( m_state )
  370. {
  371. case IDLE:
  372. case AUTO_PANNING:
  373. if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::PAN ) ||
  374. ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::PAN ) )
  375. {
  376. m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
  377. setState( DRAG_PANNING );
  378. #if defined USE_MOUSE_CAPTURE
  379. if( !m_parentPanel->HasCapture() )
  380. m_parentPanel->CaptureMouse();
  381. #endif
  382. }
  383. else if( ( aEvent.MiddleDown() && m_settings.m_dragMiddle == MOUSE_DRAG_ACTION::ZOOM ) ||
  384. ( aEvent.RightDown() && m_settings.m_dragRight == MOUSE_DRAG_ACTION::ZOOM ) )
  385. {
  386. m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
  387. m_zoomStartPoint = m_dragStartPoint;
  388. setState( DRAG_ZOOMING );
  389. #if defined USE_MOUSE_CAPTURE
  390. if( !m_parentPanel->HasCapture() )
  391. m_parentPanel->CaptureMouse();
  392. #endif
  393. }
  394. if( aEvent.LeftUp() )
  395. setState( IDLE ); // Stop autopanning when user release left mouse button
  396. break;
  397. case DRAG_ZOOMING:
  398. case DRAG_PANNING:
  399. if( aEvent.MiddleUp() || aEvent.LeftUp() || aEvent.RightUp() )
  400. {
  401. setState( IDLE );
  402. #if defined USE_MOUSE_CAPTURE
  403. if( !m_settings.m_cursorCaptured && m_parentPanel->HasCapture() )
  404. m_parentPanel->ReleaseMouse();
  405. #endif
  406. }
  407. break;
  408. }
  409. aEvent.Skip();
  410. }
  411. void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent )
  412. {
  413. // Avoid stealing focus from text controls
  414. // This is particularly important for users using On-Screen-Keyboards
  415. // They may move the mouse over the canvas to reach the keyboard
  416. if( KIUI::IsInputControlFocused() )
  417. {
  418. return;
  419. }
  420. #if defined( _WIN32 ) || defined( __WXGTK__ )
  421. // Win32 and some *nix WMs transmit mouse move and wheel events to all controls below the mouse regardless
  422. // of focus. Forcing the focus here will cause the EDA FRAMES to immediately become the
  423. // top level active window.
  424. if( m_parentPanel->GetParent() != nullptr )
  425. {
  426. // this assumes the parent panel's parent is the eda window
  427. if( KIPLATFORM::UI::IsWindowActive( m_parentPanel->GetParent() ) )
  428. {
  429. m_parentPanel->SetFocus();
  430. }
  431. }
  432. #else
  433. m_parentPanel->SetFocus();
  434. #endif
  435. }
  436. void WX_VIEW_CONTROLS::onLeave( wxMouseEvent& aEvent )
  437. {
  438. #if !defined USE_MOUSE_CAPTURE
  439. onMotion( aEvent );
  440. #endif
  441. }
  442. void WX_VIEW_CONTROLS::onCaptureLost( wxMouseEvent& aEvent )
  443. {
  444. // This method must be present to suppress the capture-lost assertion
  445. // Set the flag to allow calling m_parentPanel->CaptureMouse()
  446. // Note: One cannot call m_parentPanel->CaptureMouse() twice, this is not accepted
  447. // by wxWidgets (MSW specific) so we need this guard
  448. m_parentPanel->m_MouseCapturedLost = true;
  449. }
  450. void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
  451. {
  452. switch( m_state )
  453. {
  454. case AUTO_PANNING:
  455. {
  456. if( !m_settings.m_autoPanEnabled )
  457. {
  458. setState( IDLE );
  459. return;
  460. }
  461. #ifdef __WXMSW__
  462. // Hackfix: It's possible for the mouse to leave the canvas
  463. // without triggering any leave events on windows
  464. // Use a MSW only wx function
  465. if( !m_parentPanel->IsMouseInWindow() )
  466. {
  467. m_panTimer.Stop();
  468. setState( IDLE );
  469. return;
  470. }
  471. #endif
  472. if( !m_parentPanel->HasFocus() && !m_parentPanel->StatusPopupHasFocus() )
  473. {
  474. setState( IDLE );
  475. return;
  476. }
  477. double borderSize = std::min( m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().x,
  478. m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().y );
  479. // When the mouse cursor is outside the area with no pan,
  480. // m_panDirection is the dist to this area limit ( in pixels )
  481. // It will be used also as pan value (the pan speed depends on this dist).
  482. VECTOR2D dir( m_panDirection );
  483. // When the mouse cursor is outside the area with no pan, the pan value
  484. // is accelerated depending on the dist between the area and the cursor
  485. float accel = 0.5f + ( m_settings.m_autoPanAcceleration / 5.0f );
  486. // For a small mouse cursor dist to area, just use the distance.
  487. // But for a dist > borderSize / 2, use an accelerated pan value
  488. if( dir.EuclideanNorm() >= borderSize ) // far from area limits
  489. dir = dir.Resize( borderSize * accel );
  490. else if( dir.EuclideanNorm() > borderSize / 2 ) // Near from area limits
  491. dir = dir.Resize( borderSize );
  492. dir = m_view->ToWorld( dir, false );
  493. m_view->SetCenter( m_view->GetCenter() + dir );
  494. refreshMouse( true );
  495. m_panTimer.Start();
  496. }
  497. break;
  498. case IDLE: // Just remove unnecessary warnings
  499. case DRAG_PANNING:
  500. case DRAG_ZOOMING:
  501. break;
  502. }
  503. }
  504. void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent )
  505. {
  506. const double linePanDelta = 0.05;
  507. const double pagePanDelta = 0.5;
  508. int type = aEvent.GetEventType();
  509. int dir = aEvent.GetOrientation();
  510. if( type == wxEVT_SCROLLWIN_THUMBTRACK )
  511. {
  512. auto center = m_view->GetCenter();
  513. const auto& boundary = m_view->GetBoundary();
  514. // Flip scroll direction in flipped view
  515. const double xstart = ( m_view->IsMirroredX() ?
  516. boundary.GetRight() : boundary.GetLeft() );
  517. const double xdelta = ( m_view->IsMirroredX() ? -1 : 1 );
  518. if( dir == wxHORIZONTAL )
  519. center.x = xstart + xdelta * ( aEvent.GetPosition() / m_scrollScale.x );
  520. else
  521. center.y = boundary.GetTop() + aEvent.GetPosition() / m_scrollScale.y;
  522. m_view->SetCenter( center );
  523. }
  524. else
  525. {
  526. double dist = 0;
  527. if( type == wxEVT_SCROLLWIN_PAGEUP )
  528. dist = pagePanDelta;
  529. else if( type == wxEVT_SCROLLWIN_PAGEDOWN )
  530. dist = -pagePanDelta;
  531. else if( type == wxEVT_SCROLLWIN_LINEUP )
  532. dist = linePanDelta;
  533. else if( type == wxEVT_SCROLLWIN_LINEDOWN )
  534. dist = -linePanDelta;
  535. else
  536. wxCHECK_MSG( false, /* void */, wxT( "Unhandled event type" ) );
  537. VECTOR2D scroll = m_view->ToWorld( m_view->GetScreenPixelSize(), false ) * dist;
  538. double scrollX = 0.0;
  539. double scrollY = 0.0;
  540. if ( dir == wxHORIZONTAL )
  541. scrollX = -scroll.x;
  542. else
  543. scrollY = -scroll.y;
  544. VECTOR2D delta( scrollX, scrollY );
  545. m_view->SetCenter( m_view->GetCenter() + delta );
  546. }
  547. m_parentPanel->Refresh();
  548. }
  549. void WX_VIEW_CONTROLS::CaptureCursor( bool aEnabled )
  550. {
  551. #if defined USE_MOUSE_CAPTURE
  552. // Note: for some reason, m_parentPanel->HasCapture() can be false even if CaptureMouse()
  553. // was called (i.e. mouse was captured, so when need to test m_MouseCapturedLost to be
  554. // sure a wxEVT_MOUSE_CAPTURE_LOST event was fired before. Otherwise wxMSW complains
  555. if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost )
  556. {
  557. m_parentPanel->CaptureMouse();
  558. // Clear the flag to allow calling m_parentPanel->CaptureMouse()
  559. // Calling it without calling ReleaseMouse() is not accepted by wxWidgets (MSW specific)
  560. m_parentPanel->m_MouseCapturedLost = false;
  561. }
  562. else if( !aEnabled && m_parentPanel->HasCapture()
  563. && m_state != DRAG_PANNING && m_state != DRAG_ZOOMING )
  564. {
  565. m_parentPanel->ReleaseMouse();
  566. // Mouse is released, calling CaptureMouse() is allowed now:
  567. m_parentPanel->m_MouseCapturedLost = true;
  568. }
  569. #endif
  570. VIEW_CONTROLS::CaptureCursor( aEnabled );
  571. }
  572. void WX_VIEW_CONTROLS::CancelDrag()
  573. {
  574. if( m_state == DRAG_PANNING || m_state == DRAG_ZOOMING )
  575. {
  576. setState( IDLE );
  577. #if defined USE_MOUSE_CAPTURE
  578. if( !m_settings.m_cursorCaptured && m_parentPanel->HasCapture() )
  579. m_parentPanel->ReleaseMouse();
  580. #endif
  581. }
  582. }
  583. VECTOR2D WX_VIEW_CONTROLS::GetMousePosition( bool aWorldCoordinates ) const
  584. {
  585. wxPoint msp = getMouseScreenPosition();
  586. VECTOR2D screenPos( msp.x, msp.y );
  587. return aWorldCoordinates ? GetClampedCoords( m_view->ToWorld( screenPos ) ) : screenPos;
  588. }
  589. VECTOR2D WX_VIEW_CONTROLS::GetRawCursorPosition( bool aEnableSnapping ) const
  590. {
  591. GAL* gal = m_view->GetGAL();
  592. if( aEnableSnapping && gal->GetGridSnapping() )
  593. {
  594. return gal->GetGridPoint( m_cursorPos );
  595. }
  596. else
  597. {
  598. return m_cursorPos;
  599. }
  600. }
  601. VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition( bool aEnableSnapping ) const
  602. {
  603. if( m_settings.m_forceCursorPosition )
  604. {
  605. return m_settings.m_forcedPosition;
  606. }
  607. else
  608. {
  609. return GetClampedCoords( GetRawCursorPosition( aEnableSnapping ) );
  610. }
  611. }
  612. void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpView,
  613. bool aTriggeredByArrows, long aArrowCommand )
  614. {
  615. m_updateCursor = false;
  616. VECTOR2D clampedPosition = GetClampedCoords( aPosition );
  617. if( aTriggeredByArrows )
  618. {
  619. m_settings.m_lastKeyboardCursorPositionValid = true;
  620. m_settings.m_lastKeyboardCursorPosition = clampedPosition;
  621. m_settings.m_lastKeyboardCursorCommand = aArrowCommand;
  622. m_cursorWarped = false;
  623. }
  624. else
  625. {
  626. m_settings.m_lastKeyboardCursorPositionValid = false;
  627. m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
  628. m_settings.m_lastKeyboardCursorCommand = 0;
  629. m_cursorWarped = true;
  630. }
  631. WarpMouseCursor( clampedPosition, true, aWarpView );
  632. m_cursorPos = clampedPosition;
  633. }
  634. void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition,
  635. bool aWarpView = true )
  636. {
  637. m_updateCursor = false;
  638. VECTOR2D clampedPosition = GetClampedCoords( aPosition );
  639. const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
  640. BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
  641. VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
  642. if( aWarpView && !screen.Contains( screenPos ) )
  643. m_view->SetCenter( clampedPosition );
  644. m_cursorPos = clampedPosition;
  645. }
  646. void WX_VIEW_CONTROLS::WarpMouseCursor( const VECTOR2D& aPosition, bool aWorldCoordinates,
  647. bool aWarpView )
  648. {
  649. if( aWorldCoordinates )
  650. {
  651. const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
  652. BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
  653. VECTOR2D clampedPosition = GetClampedCoords( aPosition );
  654. VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
  655. if( !screen.Contains( screenPos ) )
  656. {
  657. if( aWarpView )
  658. {
  659. m_view->SetCenter( clampedPosition );
  660. KIPLATFORM::UI::WarpPointer( m_parentPanel, screenSize.x / 2, screenSize.y / 2 );
  661. }
  662. }
  663. else
  664. {
  665. KIPLATFORM::UI::WarpPointer( m_parentPanel, screenPos.x, screenPos.y );
  666. }
  667. }
  668. else
  669. {
  670. KIPLATFORM::UI::WarpPointer( m_parentPanel, aPosition.x, aPosition.y );
  671. }
  672. // If we are not refreshing because of mouse movement, don't set the modifiers
  673. // because we are refreshing for keyboard movement, which uses the same modifiers for other actions
  674. refreshMouse( m_updateCursor );
  675. }
  676. void WX_VIEW_CONTROLS::CenterOnCursor()
  677. {
  678. const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
  679. VECTOR2I screenCenter( screenSize / 2 );
  680. if( GetMousePosition( false ) != screenCenter )
  681. {
  682. m_view->SetCenter( GetCursorPosition() );
  683. m_dragStartPoint = screenCenter;
  684. KIPLATFORM::UI::WarpPointer( m_parentPanel, screenCenter.x, screenCenter.y );
  685. }
  686. }
  687. void WX_VIEW_CONTROLS::PinCursorInsideNonAutoscrollArea( bool aWarpMouseCursor )
  688. {
  689. int border = std::min( m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().x,
  690. m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().y );
  691. border += 2;
  692. VECTOR2D topLeft( border, border );
  693. VECTOR2D botRight( m_view->GetScreenPixelSize().x - border,
  694. m_view->GetScreenPixelSize().y - border );
  695. topLeft = m_view->ToWorld( topLeft );
  696. botRight = m_view->ToWorld( botRight );
  697. VECTOR2D pos = GetMousePosition( true );
  698. if( pos.x < topLeft.x )
  699. pos.x = topLeft.x;
  700. else if( pos.x > botRight.x )
  701. pos.x = botRight.x;
  702. if( pos.y < topLeft.y )
  703. pos.y = topLeft.y;
  704. else if( pos.y > botRight.y )
  705. pos.y = botRight.y;
  706. SetCursorPosition( pos, false, false, 0 );
  707. if( aWarpMouseCursor )
  708. WarpMouseCursor( pos, true );
  709. }
  710. bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
  711. {
  712. VECTOR2I p( aEvent.GetX(), aEvent.GetY() );
  713. VECTOR2I pKey( m_view->ToScreen(m_settings.m_lastKeyboardCursorPosition ) );
  714. if( m_cursorWarped || ( m_settings.m_lastKeyboardCursorPositionValid && p == pKey ) )
  715. {
  716. // last cursor move event came from keyboard cursor control. If auto-panning is enabled
  717. // and the next position is inside the autopan zone, check if it really came from a mouse
  718. // event, otherwise disable autopan temporarily. Also temporarily disable autopan if the
  719. // cursor is in the autopan zone because the application warped the cursor.
  720. m_cursorWarped = false;
  721. return true;
  722. }
  723. m_cursorWarped = false;
  724. // Compute areas where autopanning is active
  725. int borderStart = std::min( m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().x,
  726. m_settings.m_autoPanMargin * m_view->GetScreenPixelSize().y );
  727. borderStart = std::max( borderStart, 2 );
  728. int borderEndX = m_view->GetScreenPixelSize().x - borderStart;
  729. int borderEndY = m_view->GetScreenPixelSize().y - borderStart;
  730. if( p.x < borderStart )
  731. m_panDirection.x = -( borderStart - p.x );
  732. else if( p.x > borderEndX )
  733. m_panDirection.x = ( p.x - borderEndX );
  734. else
  735. m_panDirection.x = 0;
  736. if( p.y < borderStart )
  737. m_panDirection.y = -( borderStart - p.y );
  738. else if( p.y > borderEndY )
  739. m_panDirection.y = ( p.y - borderEndY );
  740. else
  741. m_panDirection.y = 0;
  742. bool borderHit = ( m_panDirection.x != 0 || m_panDirection.y != 0 );
  743. switch( m_state )
  744. {
  745. case AUTO_PANNING:
  746. if( !borderHit )
  747. {
  748. m_panTimer.Stop();
  749. setState( IDLE );
  750. return false;
  751. }
  752. return true;
  753. case IDLE:
  754. if( borderHit )
  755. {
  756. setState( AUTO_PANNING );
  757. m_panTimer.Start( (int) ( 250.0 / 60.0 ), true );
  758. return true;
  759. }
  760. return false;
  761. case DRAG_PANNING:
  762. case DRAG_ZOOMING:
  763. return false;
  764. }
  765. wxCHECK_MSG( false, false, wxT( "This line should never be reached" ) );
  766. return false;
  767. }
  768. void WX_VIEW_CONTROLS::handleCursorCapture( int x, int y )
  769. {
  770. if( m_settings.m_cursorCaptured )
  771. {
  772. bool warp = false;
  773. wxSize parentSize = m_parentPanel->GetClientSize();
  774. if( x < 0 )
  775. {
  776. x = 0;
  777. warp = true;
  778. }
  779. else if( x >= parentSize.x )
  780. {
  781. x = parentSize.x - 1;
  782. warp = true;
  783. }
  784. if( y < 0 )
  785. {
  786. y = 0;
  787. warp = true;
  788. }
  789. else if( y >= parentSize.y )
  790. {
  791. y = parentSize.y - 1;
  792. warp = true;
  793. }
  794. if( warp )
  795. KIPLATFORM::UI::WarpPointer( m_parentPanel, x, y );
  796. }
  797. }
  798. void WX_VIEW_CONTROLS::refreshMouse( bool aSetModifiers )
  799. {
  800. // Notify tools that the cursor position has changed in the world coordinates
  801. wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
  802. wxPoint msp = getMouseScreenPosition();
  803. moveEvent.SetX( msp.x );
  804. moveEvent.SetY( msp.y );
  805. if( aSetModifiers )
  806. {
  807. // Set the modifiers state
  808. moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
  809. moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
  810. moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
  811. }
  812. m_cursorPos = GetClampedCoords( m_view->ToWorld( VECTOR2D( msp.x, msp.y ) ) );
  813. wxPostEvent( m_parentPanel, moveEvent );
  814. }
  815. wxPoint WX_VIEW_CONTROLS::getMouseScreenPosition() const
  816. {
  817. wxPoint msp = wxGetMousePosition();
  818. m_parentPanel->ScreenToClient( &msp.x, &msp.y );
  819. return msp;
  820. }
  821. void WX_VIEW_CONTROLS::UpdateScrollbars()
  822. {
  823. const BOX2D viewport = m_view->GetViewport();
  824. const BOX2D& boundary = m_view->GetBoundary();
  825. m_scrollScale.x = 2e3 / viewport.GetWidth(); // TODO it does not have to be updated so often
  826. m_scrollScale.y = 2e3 / viewport.GetHeight();
  827. VECTOR2I newScroll( ( viewport.Centre().x - boundary.GetLeft() ) * m_scrollScale.x,
  828. ( viewport.Centre().y - boundary.GetTop() ) * m_scrollScale.y );
  829. // We add the width of the scroll bar thumb to the range because the scroll range is given by
  830. // the full bar while the position is given by the left/top position of the thumb
  831. VECTOR2I newRange( m_scrollScale.x * boundary.GetWidth() +
  832. m_parentPanel->GetScrollThumb( wxSB_HORIZONTAL ),
  833. m_scrollScale.y * boundary.GetHeight() +
  834. m_parentPanel->GetScrollThumb( wxSB_VERTICAL ) );
  835. // Flip scroll direction in flipped view
  836. if( m_view->IsMirroredX() )
  837. newScroll.x = ( boundary.GetRight() - viewport.Centre().x ) * m_scrollScale.x;
  838. // Adjust scrollbars only if it is needed. Otherwise there are cases when canvas is continuously
  839. // refreshed (Windows)
  840. if( m_scrollPos != newScroll || newRange.x != m_parentPanel->GetScrollRange( wxSB_HORIZONTAL )
  841. || newRange.y != m_parentPanel->GetScrollRange( wxSB_VERTICAL ) )
  842. {
  843. m_parentPanel->SetScrollbars( 1, 1, newRange.x, newRange.y, newScroll.x, newScroll.y,
  844. true );
  845. m_scrollPos = newScroll;
  846. #if !defined( __APPLE__ ) && !defined( WIN32 )
  847. // Trigger a mouse refresh to get the canvas update in GTK (re-draws the scrollbars).
  848. // Note that this causes an infinite loop on OSX and Windows (in certain cases) as it
  849. // generates a paint event.
  850. refreshMouse( false );
  851. #endif
  852. }
  853. }
  854. void WX_VIEW_CONTROLS::ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition )
  855. {
  856. VECTOR2D clampedPosition = GetClampedCoords( aPosition );
  857. m_settings.m_forceCursorPosition = aEnabled;
  858. m_settings.m_forcedPosition = clampedPosition;
  859. }