2017-02-12 13:21:08 +01:00
/*
KLayout Layout Viewer
2017-02-12 15:28:14 +01:00
Copyright ( C ) 2006 - 2017 Matthias Koefferlein
2017-02-12 13:21:08 +01:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# include "gsiDecl.h"
# include "gsiDeclBasic.h"
# include "layPlugin.h"
# include "layViewObject.h"
# include "layLayoutView.h"
# include "layCursor.h"
namespace gsi
{
class PluginFactoryBase ;
class PluginBase ;
}
namespace tl
{
template < > struct type_traits < gsi : : PluginFactoryBase > : public type_traits < void > {
typedef tl : : false_tag has_copy_constructor ;
} ;
template < > struct type_traits < gsi : : PluginBase > : public type_traits < void > {
typedef tl : : false_tag has_copy_constructor ;
} ;
template < > Registrar < gsi : : PluginFactoryBase > * Registrar < gsi : : PluginFactoryBase > : : instance = 0 ;
}
namespace gsi
{
// TODO: these static variables are a bad hack!
// However it's not easy to pass parameters to a C++ classes constructor in Ruby without
// compromising the capability to derive from that class (at least I have not learned how
// to create a "new" in the super class *and* allow to "new" the derived class). Anyway,
// since PluginBase object are only allowed to be created inside the create_plugin method
// of the factory, this hack is a quick but dirty workaround.
static bool s_in_create_plugin = false ;
static lay : : LayoutView * sp_view = 0 ;
static lay : : PluginRoot * sp_root = 0 ;
class PluginBase
: public lay : : Plugin , public lay : : ViewService
{
public :
PluginBase ( )
: lay : : Plugin ( sp_root ) , lay : : ViewService ( sp_view ? sp_view - > view_object_widget ( ) : 0 )
{
if ( ! s_in_create_plugin ) {
throw tl : : Exception ( tl : : to_string ( QObject : : tr ( " A PluginBase object can only be created in the PluginFactory's create_plugin method " ) ) ) ;
}
}
void grab_mouse ( )
{
if ( widget ( ) ) {
widget ( ) - > grab_mouse ( this , false ) ;
}
}
void ungrab_mouse ( )
{
if ( widget ( ) ) {
widget ( ) - > ungrab_mouse ( this ) ;
}
}
void set_cursor ( int c )
{
if ( widget ( ) ) {
lay : : ViewService : : set_cursor ( ( enum lay : : Cursor : : cursor_shape ) c ) ;
}
}
virtual lay : : ViewService * view_service_interface ( )
{
return this ;
}
virtual void menu_activated ( const std : : string & symbol )
{
if ( f_menu_activated . can_issue ( ) ) {
f_menu_activated . issue < lay : : Plugin , const std : : string & > ( & lay : : Plugin : : menu_activated , symbol ) ;
} else {
lay : : Plugin : : menu_activated ( symbol ) ;
}
}
virtual bool configure ( const std : : string & name , const std : : string & value )
{
return f_configure . can_issue ( ) ? f_configure . issue < PluginBase , bool , const std : : string & , const std : : string & > ( & PluginBase : : configure , name , value ) : lay : : Plugin : : configure ( name , value ) ;
}
virtual void config_finalize ( )
{
f_config_finalize . can_issue ( ) ? f_config_finalize . issue < PluginBase > ( & PluginBase : : config_finalize ) : lay : : Plugin : : config_finalize ( ) ;
}
virtual bool key_event ( unsigned int key , unsigned int buttons )
{
if ( f_key_event . can_issue ( ) ) {
return f_key_event . issue < lay : : ViewService , bool , unsigned int , unsigned int > ( & lay : : ViewService : : key_event , key , buttons ) ;
} else {
return lay : : ViewService : : key_event ( key , buttons ) ;
}
}
virtual bool mouse_press_event ( const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_mouse_press_event . can_issue ( ) ) {
return f_mouse_press_event . issue < lay : : ViewService , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : mouse_press_event , p , buttons , prio ) ;
} else {
return lay : : ViewService : : mouse_press_event ( p , buttons , prio ) ;
}
}
virtual bool mouse_click_event ( const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_mouse_click_event . can_issue ( ) ) {
return f_mouse_click_event . issue < lay : : ViewService , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : mouse_click_event , p , buttons , prio ) ;
} else {
return lay : : ViewService : : mouse_click_event ( p , buttons , prio ) ;
}
}
virtual bool mouse_double_click_event ( const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_mouse_double_click_event . can_issue ( ) ) {
return f_mouse_double_click_event . issue < lay : : ViewService , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : mouse_double_click_event , p , buttons , prio ) ;
} else {
return lay : : ViewService : : mouse_double_click_event ( p , buttons , prio ) ;
}
}
virtual bool leave_event ( bool prio )
{
if ( f_leave_event . can_issue ( ) ) {
return f_leave_event . issue < lay : : ViewService , bool , bool > ( & lay : : ViewService : : leave_event , prio ) ;
} else {
return lay : : ViewService : : leave_event ( prio ) ;
}
}
virtual bool enter_event ( bool prio )
{
if ( f_enter_event . can_issue ( ) ) {
return f_enter_event . issue < lay : : ViewService , bool , bool > ( & lay : : ViewService : : enter_event , prio ) ;
} else {
return lay : : ViewService : : enter_event ( prio ) ;
}
}
virtual bool mouse_move_event ( const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_mouse_move_event . can_issue ( ) ) {
return f_mouse_move_event . issue < lay : : ViewService , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : mouse_move_event , p , buttons , prio ) ;
} else {
return lay : : ViewService : : mouse_move_event ( p , buttons , prio ) ;
}
}
virtual bool mouse_release_event ( const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_mouse_release_event . can_issue ( ) ) {
return f_mouse_release_event . issue < lay : : ViewService , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : mouse_release_event , p , buttons , prio ) ;
} else {
return lay : : ViewService : : mouse_release_event ( p , buttons , prio ) ;
}
}
virtual bool wheel_event ( int delta , bool horizontal , const db : : DPoint & p , unsigned int buttons , bool prio )
{
if ( f_wheel_event . can_issue ( ) ) {
return f_wheel_event . issue < lay : : ViewService , bool , int , bool , const db : : DPoint & , unsigned int , bool > ( & lay : : ViewService : : wheel_event , delta , horizontal , p , buttons , prio ) ;
} else {
return lay : : ViewService : : wheel_event ( delta , horizontal , p , buttons , prio ) ;
}
}
virtual void activated ( )
{
if ( f_activated . can_issue ( ) ) {
f_activated . issue < lay : : ViewService > ( & lay : : ViewService : : activated ) ;
} else {
lay : : ViewService : : activated ( ) ;
}
}
virtual void deactivated ( )
{
if ( f_deactivated . can_issue ( ) ) {
f_deactivated . issue < lay : : ViewService > ( & lay : : ViewService : : deactivated ) ;
} else {
lay : : ViewService : : deactivated ( ) ;
}
}
virtual void drag_cancel ( )
{
if ( f_drag_cancel . can_issue ( ) ) {
f_drag_cancel . issue < lay : : ViewService > ( & lay : : ViewService : : drag_cancel ) ;
} else {
lay : : ViewService : : drag_cancel ( ) ;
}
}
virtual void update ( )
{
if ( f_update . can_issue ( ) ) {
f_update . issue < lay : : ViewService > ( & lay : : ViewService : : update ) ;
} else {
lay : : ViewService : : update ( ) ;
}
}
gsi : : Callback f_menu_activated ;
gsi : : Callback f_configure ;
gsi : : Callback f_config_finalize ;
gsi : : Callback f_key_event ;
gsi : : Callback f_mouse_press_event ;
gsi : : Callback f_mouse_click_event ;
gsi : : Callback f_mouse_double_click_event ;
gsi : : Callback f_leave_event ;
gsi : : Callback f_enter_event ;
gsi : : Callback f_mouse_move_event ;
gsi : : Callback f_mouse_release_event ;
gsi : : Callback f_wheel_event ;
gsi : : Callback f_activated ;
gsi : : Callback f_deactivated ;
gsi : : Callback f_drag_cancel ;
gsi : : Callback f_update ;
} ;
class PluginFactoryBase
: public lay : : PluginDeclaration
{
public :
PluginFactoryBase ( )
: PluginDeclaration ( ) ,
m_implements_mouse_mode ( true ) , mp_registration ( 0 )
{
// .. nothing yet ..
}
~ PluginFactoryBase ( )
{
delete mp_registration ;
mp_registration = 0 ;
}
void register_gsi ( int position , const char * name , const char * title )
{
register_gsi2 ( position , name , title , 0 ) ;
}
void register_gsi2 ( int position , const char * name , const char * title , const char * icon )
{
// makes the object owned by the C++ side
keep ( ) ;
// remove an existing factory with the same name
static std : : map < std : : string , PluginFactoryBase * > s_factories ;
std : : map < std : : string , PluginFactoryBase * > : : iterator f = s_factories . find ( name ) ;
if ( f ! = s_factories . end ( ) ) {
delete f - > second ;
f - > second = this ;
} else {
s_factories . insert ( std : : make_pair ( std : : string ( name ) , this ) ) ;
}
// cancel any previous registration and register (again)
delete mp_registration ;
mp_registration = new tl : : RegisteredClass < lay : : PluginDeclaration > ( this , position , name , false /*does not own object*/ ) ;
m_mouse_mode_title = name ;
if ( title ) {
m_mouse_mode_title + = " \t " ;
m_mouse_mode_title + = title ;
}
if ( icon ) {
m_mouse_mode_title + = " \t < " ;
m_mouse_mode_title + = icon ;
m_mouse_mode_title + = " > " ;
}
// (dynamically) register the plugin class. This will also call initialize if the main window is
// present already.
register_plugin ( ) ;
}
virtual bool configure ( const std : : string & name , const std : : string & value )
{
if ( f_configure . can_issue ( ) ) {
return f_configure . issue < lay : : PluginDeclaration , bool , const std : : string & , const std : : string & > ( & lay : : PluginDeclaration : : configure , name , value ) ;
} else {
return lay : : PluginDeclaration : : configure ( name , value ) ;
}
}
virtual void config_finalize ( )
{
if ( f_config_finalize . can_issue ( ) ) {
f_config_finalize . issue < lay : : PluginDeclaration > ( & lay : : PluginDeclaration : : config_finalize ) ;
} else {
lay : : PluginDeclaration : : config_finalize ( ) ;
}
}
virtual bool menu_activated ( const std : : string & symbol ) const
{
if ( f_menu_activated . can_issue ( ) ) {
return f_menu_activated . issue < lay : : PluginDeclaration , bool , const std : : string & > ( & lay : : PluginDeclaration : : menu_activated , symbol ) ;
} else {
return lay : : PluginDeclaration : : menu_activated ( symbol ) ;
}
}
virtual void initialize ( lay : : PluginRoot * root )
{
if ( f_initialize . can_issue ( ) ) {
f_initialize . issue < lay : : PluginDeclaration > ( & lay : : PluginDeclaration : : initialize , root ) ;
} else {
lay : : PluginDeclaration : : initialize ( root ) ;
}
}
virtual void uninitialize ( lay : : PluginRoot * root )
{
if ( f_uninitialize . can_issue ( ) ) {
f_uninitialize . issue < lay : : PluginDeclaration > ( & lay : : PluginDeclaration : : uninitialize , root ) ;
} else {
lay : : PluginDeclaration : : uninitialize ( root ) ;
}
}
virtual lay : : Plugin * create_plugin ( db : : Manager * manager , lay : : PluginRoot * root , lay : : LayoutView * view ) const
{
if ( f_create_plugin . can_issue ( ) ) {
return create_plugin_gsi ( manager , root , view ) ;
} else {
return lay : : PluginDeclaration : : create_plugin ( manager , root , view ) ;
}
}
virtual gsi : : PluginBase * create_plugin_gsi ( db : : Manager * manager , lay : : PluginRoot * root , lay : : LayoutView * view ) const
{
// TODO: this is a hack. See notes above at s_in_create_plugin
s_in_create_plugin = true ;
sp_view = view ;
sp_root = root ;
gsi : : PluginBase * ret = 0 ;
try {
ret = f_create_plugin . issue < PluginFactoryBase , gsi : : PluginBase * , db : : Manager * , lay : : PluginRoot * , lay : : LayoutView * > ( & PluginFactoryBase : : create_plugin_gsi , manager , root , view ) ;
s_in_create_plugin = false ;
sp_view = 0 ;
sp_root = 0 ;
} catch ( . . . ) {
s_in_create_plugin = false ;
sp_view = 0 ;
sp_root = 0 ;
}
return ret ;
}
virtual void get_menu_entries ( std : : vector < lay : : MenuEntry > & menu_entries ) const
{
menu_entries = m_menu_entries ;
}
virtual void get_options ( std : : vector < std : : pair < std : : string , std : : string > > & options ) const
{
options = m_options ;
}
void add_menu_entry1 ( const std : : string & menu_name , const std : : string & insert_pos )
{
m_menu_entries . push_back ( lay : : MenuEntry ( menu_name , insert_pos ) ) ;
}
void add_menu_entry2 ( const std : : string & symbol , const std : : string & menu_name , const std : : string & insert_pos , const std : : string & title )
{
m_menu_entries . push_back ( lay : : MenuEntry ( symbol , menu_name , insert_pos , title ) ) ;
}
void add_menu_entry3 ( const std : : string & symbol , const std : : string & menu_name , const std : : string & insert_pos , const std : : string & title , bool sub_menu )
{
m_menu_entries . push_back ( lay : : MenuEntry ( symbol , menu_name , insert_pos , title , sub_menu ) ) ;
}
void add_option ( const std : : string & name , const std : : string & default_value )
{
m_options . push_back ( std : : make_pair ( name , default_value ) ) ;
}
void has_tool_entry ( bool f )
{
m_implements_mouse_mode = f ;
}
virtual bool implements_mouse_mode ( std : : string & title ) const
{
title = m_mouse_mode_title ;
return m_implements_mouse_mode ;
}
gsi : : Callback f_create_plugin ;
gsi : : Callback f_initialize ;
gsi : : Callback f_uninitialize ;
gsi : : Callback f_configure ;
gsi : : Callback f_config_finalize ;
gsi : : Callback f_menu_activated ;
private :
std : : vector < std : : pair < std : : string , std : : string > > m_options ;
std : : vector < lay : : MenuEntry > m_menu_entries ;
bool m_implements_mouse_mode ;
std : : string m_mouse_mode_title ;
tl : : RegisteredClass < lay : : PluginDeclaration > * mp_registration ;
} ;
Class < gsi : : PluginFactoryBase > decl_PluginFactory ( " PluginFactory " ,
method ( " register " , & PluginFactoryBase : : register_gsi ,
" @brief Registers the plugin factory \n "
" @args position, name, title \n "
" @param position An integer that determines the order in which the plugins are created. The internal plugins use the values from 1000 to 50000. \n "
" @param name The plugin name. This is an arbitrary string which should be unique. Hence it is recommended to use a unique prefix, i.e. \" myplugin::ThePluginClass \" . \n "
" @param title The title string which is supposed to appear in the tool bar and menu related to this plugin. \n "
" \n "
" Registration of the plugin factory makes the object known to the system. Registration requires that the menu items have been set "
" already. Hence it is recommended to put the registration at the end of the initialization method of the factory class. \n "
) +
method ( " register " , & PluginFactoryBase : : register_gsi2 ,
" @brief Registers the plugin factory \n "
" @args position, name, title, icon \n "
" @param position An integer that determines the order in which the plugins are created. The internal plugins use the values from 1000 to 50000. \n "
" @param name The plugin name. This is an arbitrary string which should be unique. Hence it is recommended to use a unique prefix, i.e. \" myplugin::ThePluginClass \" . \n "
" @param title The title string which is supposed to appear in the tool bar and menu related to this plugin. \n "
" @param icon The path to the icon that appears in the tool bar and menu related to this plugin. \n "
" \n "
" This version also allows to register an icon for the tool bar. \n "
" \n "
" Registration of the plugin factory makes the object known to the system. Registration requires that the menu items have been set "
" already. Hence it is recommended to put the registration at the end of the initialization method of the factory class. \n "
) +
callback ( " configure " , & gsi : : PluginFactoryBase : : configure , & gsi : : PluginFactoryBase : : f_configure ,
" @brief Gets called for configuration events for the plugin singleton \n "
" @args name, value \n "
" This method can be reimplemented to receive configuration events "
" for the plugin singleton. Before a configuration can be received it must be "
" registered by calling \\ add_option in the plugin factories' constructor. \n "
" \n "
" The implementation of this method may return true indicating that the configuration request "
" will not be handled by further modules. It's more cooperative to return false which will "
" make the system distribute the configuration request to other receivers as well. \n "
" \n "
" @param name The configuration key \n "
" @param value The value of the configuration variable \n "
" @return True to stop further processing \n "
) +
callback ( " config_finalize " , & gsi : : PluginFactoryBase : : config_finalize , & gsi : : PluginFactoryBase : : f_config_finalize ,
" @brief Gets called after a set of configuration events has been sent \n "
" @args \n "
" This method can be reimplemented and is called after a set of configuration events "
" has been sent to the plugin factory singleton with \\ configure. It can be used to "
" set up user interfaces properly for example. \n "
) +
callback ( " menu_activated " , & gsi : : PluginFactoryBase : : menu_activated , & gsi : : PluginFactoryBase : : f_menu_activated ,
" @brief Gets called when a menu item is selected \n "
" @args symbol \n "
" \n "
" Usually, menu-triggered functionality is implemented in the per-view instance of the plugin. "
" However, using this method it is possible to implement functionality globally for all plugin "
" instances. The symbol is the string registered with the specific menu item in the \\ add_menu_item "
" call. \n "
" \n "
" If this method was handling the menu event, it should return true. This indicates that the event "
" will not be propagated to other plugins hence avoiding duplicate calls. \n "
) +
callback ( " initialized " , & gsi : : PluginFactoryBase : : initialize , & gsi : : PluginFactoryBase : : f_initialize ,
" @brief Gets called when the plugin singleton is initialized, i.e. when the application has been started. \n "
" @args root \n "
" @param root The reference to the \\ MainWindow object \n "
) +
callback ( " uninitialized " , & gsi : : PluginFactoryBase : : uninitialize , & gsi : : PluginFactoryBase : : f_uninitialize ,
" @brief Gets called when the application shuts down and the plugin is unregistered \n "
" This event can be used to free resources allocated with this factory singleton. \n "
" @args root \n "
" @param root The reference to the \\ MainWindow object \n "
) +
callback ( " create_plugin " , & gsi : : PluginFactoryBase : : create_plugin_gsi , & gsi : : PluginFactoryBase : : f_create_plugin ,
" @brief Creates the plugin \n "
" This is the basic functionality that the factory must provide. This method must create a plugin of the "
" specific type. \n "
" @args manager, root, view \n "
" @param manager The database manager object responsible for handling database transactions \n "
" @param root The reference to the \\ MainWindow object \n "
" @param view The \\ LayoutView that is plugin is created for \n "
" @return The new \\ Plugin implementation object \n "
) +
method ( " add_menu_entry " , & gsi : : PluginFactoryBase : : add_menu_entry1 ,
" @brief Specifies a separator \n "
" @args menu_name, insert_pos \n "
" Call this method in the factory constructor to build the menu items that this plugin shall create. \n "
" This specific call inserts a separator at the given position (insert_pos). The position uses abstract menu item paths "
" and \" menu_name \" names the component that will be created. See \\ AbstractMenu for a description of the path. \n "
) +
method ( " add_menu_entry " , & gsi : : PluginFactoryBase : : add_menu_entry2 ,
" @brief Specifies a menu item \n "
" @args symbol, menu_name, insert_pos, title \n "
" Call this method in the factory constructor to build the menu items that this plugin shall create. \n "
" This specific call inserts a menu item at the specified position (insert_pos). The position uses abstract menu item paths "
" and \" menu_name \" names the component that will be created. See \\ AbstractMenu for a description of the path. \n "
" When the menu item is selected \" symbol \" is the string that is sent to the \\ menu_activated callback (either the global one for the factory ot the one of the per-view plugin instance). \n "
" \n "
" @param symbol The string to send to the plugin if the menu is triggered \n "
" @param menu_name The name of entry to create at the given position \n "
" @param insert_pos The position where to create the entry \n "
" @param title The title string for the item. The title can contain a keyboard shortcut in round braces after the title text, i.e. \" My Menu Item(F12) \" \n "
) +
method ( " add_menu_entry " , & gsi : : PluginFactoryBase : : add_menu_entry3 ,
" @brief Specifies a menu item or sub-menu \n "
" @args symbol, menu_name, insert_pos, title, sub_menu \n "
" Similar to the previous form of \" add_menu_entry \" , but this version allows also to create sub-menus by setting the "
" last parameter to \" true \" "
) +
method ( " add_option " , & gsi : : PluginFactoryBase : : add_option ,
" @brief Specifies configuration variables. \n "
" @args name, default_value \n "
" Call this method in the factory constructor to add configuration key/value pairs to the configuration repository. "
" Without specifying configuration variables, the status of a plugin cannot be persisted. "
" \n \n "
" Once the configuration variables are known, they can be retrieved on demand using \" get_config \" from "
" \\ MainWindow or listening to \\ configure callbacks (either in the factory or the plugin instance). Configuration variables can "
" be set using \" set_config \" from \\ MainWindow. This scheme also works without registering the configuration options, but "
" doing so has the advantage that it is guaranteed that a variable with this keys exists and has the given default value initially. "
" \n \n "
) +
method ( " has_tool_entry= " , & gsi : : PluginFactoryBase : : has_tool_entry ,
" @brief Enables or disables the tool bar entry \n "
" @args f \n "
" Initially this property is set to true. This means that the plugin will have a visible entry in the toolbar. "
" This property can be set to false to disable this feature. In that case, the title and icon given on registration will be ignored. "
) ,
" @brief The plugin framework's plugin factory object \n "
" \n "
" Plugins are components that extend KLayout's functionality in various aspects. Scripting support exists "
" currently for providing mouse mode handlers and general on-demand functionality connected with a menu "
" entry. \n "
" \n "
" Plugins are objects that implement the \\ Plugin interface. Each layout view is associated with one instance "
" of such an object. The PluginFactory is a singleton which is responsible for creating \\ Plugin objects and "
" providing certain configuration information such as where to put the menu items connected to this plugin and "
" what configuration keys are used. \n "
" \n "
" An implementation of PluginFactory must at least provide an implementation of \\ create_plugin. This method "
" must instantiate a new object of the specific plugin. \n "
" \n "
" After the factory has been created, it must be registered in the system using one of the \\ register methods. "
" It is therefore recommended to put the call to \\ register at the end of the \" initialize \" method. For the registration "
" to work properly, the menu items must be defined before \\ register is called. \n "
" \n "
" The following features can also be implemented: \n "
" \n "
" @<ul> \n "
" @<li>Reserve keys in the configuration file using \\ add_option in the constructor@</li> \n "
" @<li>Create menu items by using \\ add_menu_entry in the constructor@</li> \n "
" @<li>Set the title for the mode entry that appears in the tool bar using the \\ register argument@</li> \n "
" @<li>Provide global functionality (independent from the layout view) using \\ configure or \\ menu_activated@</li> \n "
" @</ul> \n "
" \n "
" This is a simple example for a plugin in Ruby. It switches the mouse cursor to a 'cross' cursor when it is active: \n "
" \n "
" @code \n "
" class PluginTestFactory < RBA::PluginFactory \n "
" \n "
" # Constructor \n "
" def initialize \n "
" # registers the new plugin class at position 100000 (at the end), with name \n "
" # \" my_plugin_test \" and title \" My plugin test \" \n "
" register(100000, \" my_plugin_test \" , \" My plugin test \" ) \n "
" end \n "
" \n "
" # Create a new plugin instance of the custom type \n "
" def create_plugin(manager, root, view) \n "
" return PluginTest.new \n "
" end \n "
" \n "
" end \n "
" \n "
" # The plugin class \n "
" class PluginTest < RBA::Plugin \n "
" def mouse_moved_event(p, buttons, prio) \n "
" if prio \n "
" # Set the cursor to cross if our plugin is active. \n "
" set_cursor(RBA::Cursor::Cross) \n "
" end \n "
" # Returning false indicates that we don't want to consume the event. \n "
" # This way for example the cursor position tracker still works. \n "
" false \n "
" end \n "
" def mouse_click_event(p, buttons, prio) \n "
" if prio \n "
" puts \" mouse button clicked. \" \n "
" # This indicates we want to consume the event and others don't receive the mouse click \n "
" # with prio = false. \n "
" return true \n "
" end \n "
" # don't consume the event if we are not active. \n "
" false \n "
" end \n "
" end \n "
" \n "
" # Instantiate the new plugin factory. \n "
" PluginTestFactory.new \n "
" @/code \n "
" \n "
" This class has been introduced in version 0.22. \n "
) ;
Class < gsi : : PluginBase > decl_Plugin ( " Plugin " ,
callback ( " menu_activated " , & gsi : : PluginBase : : menu_activated , & gsi : : PluginBase : : f_menu_activated ,
" @brief Gets called when a custom menu item is selected \n "
" @args symbol \n "
" When a menu item is clicked which was registered with the plugin factory, the plugin's 'menu_activated' method is "
" called for the current view. The symbol registered for the menu item is passed in the 'symbol' argument. "
) +
callback ( " configure " , & gsi : : PluginBase : : configure , & gsi : : PluginBase : : f_configure ,
" @brief Sends configuration requests to the plugin \n "
" @args name, value \n "
" @param name The name of the configuration variable as registered in the plugin factory \n "
" @param value The value of the configuration variable \n "
" When a configuration variable is changed, the new value is reported to the plugin by calling the 'configure' method. "
) +
callback ( " config_finalize " , & gsi : : PluginBase : : config_finalize , & gsi : : PluginBase : : f_config_finalize ,
" @brief Sends the post-configuration request to the plugin \n "
" @args \n "
" After all configuration parameters have been sent, 'config_finalize' is called to given the plugin a chance to "
" update it's internal state according to the new configuration. \n "
) +
callback ( " key_event " , & gsi : : PluginBase : : key_event , & gsi : : PluginBase : : f_key_event ,
" @brief Handles the key pressed event \n "
" @args key, buttons \n "
" This method will called by the view on the active plugin when a button is pressed on the mouse. \n "
" \n "
" If the plugin handles the event, it should return true to indicate that the event should not be processed further. "
" \n "
" @param key The Qt key code of the key that was pressed \n "
" @param buttons A combination of the constants in the \\ ButtonState class which codes both the mouse buttons and the key modifiers (.e. ShiftButton etc). \n "
" @return True to terminate dispatcher \n "
) +
callback ( " mouse_button_pressed_event " , & gsi : : PluginBase : : mouse_press_event , & gsi : : PluginBase : : f_mouse_press_event ,
" @brief Handles the mouse button pressed event \n "
" @args p, buttons, prio \n "
" This method will called by the view when a button is pressed on the mouse. \n "
" \n "
" First, the plugins that grabbed the mouse with \\ grab_mouse will receive this event with 'prio' set to true "
" in the reverse order the plugins grabbed the mouse. The loop will terminate if one of the mouse event handlers "
" returns true. \n "
" \n "
" If that is not the case or no plugin has grabbed the mouse, the active plugin receives the mouse event with 'prio' set to true. \n "
" \n "
" If no receiver accepted the mouse event by returning true, it is sent again to all plugins with 'prio' set to false. \n "
" Again, the loop terminates if one of the receivers returns true. The second pass gives inactive plugins a chance to monitor the mouse "
" and implement specific actions - i.e. displaying the current position. \n "
" \n "
" This event is not sent immediately when the mouse button is pressed but when a signification movement for the mouse cursor away from the "
" original position is detected. If the mouse button is released before that, a mouse_clicked_event is sent rather than a press-move-release "
" sequence. "
" \n "
" @param p The point at which the button was pressed \n "
" @param buttons A combination of the constants in the \\ ButtonState class which codes both the mouse buttons and the key modifiers (.e. LeftButton, ShiftButton etc). \n "
" @return True to terminate dispatcher \n "
) +
callback ( " mouse_click_event " , & gsi : : PluginBase : : mouse_click_event , & gsi : : PluginBase : : f_mouse_click_event ,
" @brief Handles the mouse button click event (after the button has been released) \n "
" @args p, buttons, prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse button has been released without moving it. \n "
) +
callback ( " mouse_double_click_event " , & gsi : : PluginBase : : mouse_double_click_event , & gsi : : PluginBase : : f_mouse_double_click_event ,
" @brief Handles the mouse button double-click event \n "
" @args p, buttons, prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse button has been double-clicked. \n "
) +
callback ( " leave_event " , & gsi : : PluginBase : : leave_event , & gsi : : PluginBase : : f_leave_event ,
" @brief Handles the leave event (mouse leaves canvas area of view) \n "
" @args prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse leaves the canvas area. \n "
" This method does not have a position nor button flags. \n "
) +
callback ( " enter_event " , & gsi : : PluginBase : : enter_event , & gsi : : PluginBase : : f_enter_event ,
" @brief Handles the enter event (mouse enters canvas area of view) \n "
" @args prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse enters the canvas area. \n "
" This method does not have a position nor button flags. \n "
) +
callback ( " mouse_moved_event " , & gsi : : PluginBase : : mouse_move_event , & gsi : : PluginBase : : f_mouse_move_event ,
" @brief Handles the mouse move event \n "
" @args p, buttons, prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse is moved in the canvas area. \n "
) +
callback ( " mouse_button_released_event " , & gsi : : PluginBase : : mouse_release_event , & gsi : : PluginBase : : f_mouse_release_event ,
" @brief Handles the mouse button release event \n "
" @args p, buttons, prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse button is released. \n "
) +
callback ( " wheel_event " , & gsi : : PluginBase : : wheel_event , & gsi : : PluginBase : : f_wheel_event ,
" @args delta, horizontal, p, buttons, prio \n "
" The behaviour of this callback is the same than for \\ mouse_press_event, except that it is called when the mouse wheel is rotated. \n "
" Additional parameters for this event are 'delta' (the rotation angle in units of 1/8th degree) and 'horizontal' which is true when the horizontal wheel was rotated and "
" false if the vertical wheel was rotated. \n "
) +
callback ( " activated " , & gsi : : PluginBase : : activated , & gsi : : PluginBase : : f_activated ,
" @brief Gets called when the plugin is activated (selected in the tool bar) \n "
" @args \n "
) +
callback ( " deactivated " , & gsi : : PluginBase : : deactivated , & gsi : : PluginBase : : f_deactivated ,
" @brief Gets called when the plugin is deactivated and another plugin is activated \n "
" @args \n "
) +
callback ( " drag_cancel " , & gsi : : PluginBase : : drag_cancel , & gsi : : PluginBase : : f_drag_cancel ,
" @brief Gets called on various occasions when a drag operation should be canceled \n "
" @args \n "
" If the plugin implements some press-and-drag or a click-and-drag operation, this callback should "
" cancel this operation and return in some state waiting for a new mouse event. "
) +
callback ( " update " , & gsi : : PluginBase : : update , & gsi : : PluginBase : : f_update ,
" @brief Gets called when the view has changed \n "
" @args \n "
" This method is called in particular if the view has changed the visible rectangle, i.e. after zooming in or out or panning. "
" This callback can be used to update any internal states that depend on the view's state. "
) +
method ( " grab_mouse " , & gsi : : PluginBase : : grab_mouse ,
" @brief Redirects mouse events to this plugin, even if the plugin is not active. \n "
" @args \n "
) +
method ( " ungrab_mouse " , & gsi : : PluginBase : : ungrab_mouse ,
" @brief Removes a mouse grab registered with \\ grab_mouse. \n "
" @args \n "
) +
method ( " set_cursor " , & gsi : : PluginBase : : set_cursor ,
" @brief Sets the cursor in the view area to the given type \n "
" @args cursor_type \n "
" Setting the cursor has an effect only inside event handlers, i.e. mouse_press_event. The cursor is not set permanently. Is is reset "
" in the mouse move handler unless a button is pressed or the cursor is explicitly set again in the mouse_move_event. \n "
" \n "
" The cursor type is one of the cursor constants in the \\ Cursor class, i.e. 'CursorArrow' for the normal cursor. "
) ,
" @brief The plugin object \n "
" \n "
" This class provides the actual plugin implementation. Each view gets it's own instance of the plugin class. The plugin factory \\ PluginFactory class "
" must be specialized to provide a factory for new objects of the Plugin class. See the documentation there for details about the plugin mechanism and "
" the basic concepts. \n "
" \n "
" This class has been introduced in version 0.22. \n "
) ;
class CursorNamespace { } ;
static int cursor_shape_none ( ) { return int ( lay : : Cursor : : none ) ; }
static int cursor_shape_arrow ( ) { return int ( lay : : Cursor : : arrow ) ; }
static int cursor_shape_up_arrow ( ) { return int ( lay : : Cursor : : up_arrow ) ; }
static int cursor_shape_cross ( ) { return int ( lay : : Cursor : : cross ) ; }
static int cursor_shape_wait ( ) { return int ( lay : : Cursor : : wait ) ; }
static int cursor_shape_i_beam ( ) { return int ( lay : : Cursor : : i_beam ) ; }
static int cursor_shape_size_ver ( ) { return int ( lay : : Cursor : : size_ver ) ; }
static int cursor_shape_size_hor ( ) { return int ( lay : : Cursor : : size_hor ) ; }
static int cursor_shape_size_bdiag ( ) { return int ( lay : : Cursor : : size_bdiag ) ; }
static int cursor_shape_size_fdiag ( ) { return int ( lay : : Cursor : : size_fdiag ) ; }
static int cursor_shape_size_all ( ) { return int ( lay : : Cursor : : size_all ) ; }
static int cursor_shape_blank ( ) { return int ( lay : : Cursor : : blank ) ; }
static int cursor_shape_split_v ( ) { return int ( lay : : Cursor : : split_v ) ; }
static int cursor_shape_split_h ( ) { return int ( lay : : Cursor : : split_h ) ; }
static int cursor_shape_pointing_hand ( ) { return int ( lay : : Cursor : : pointing_hand ) ; }
static int cursor_shape_forbidden ( ) { return int ( lay : : Cursor : : forbidden ) ; }
static int cursor_shape_whats_this ( ) { return int ( lay : : Cursor : : whats_this ) ; }
static int cursor_shape_busy ( ) { return int ( lay : : Cursor : : busy ) ; }
static int cursor_shape_open_hand ( ) { return int ( lay : : Cursor : : open_hand ) ; }
static int cursor_shape_closed_hand ( ) { return int ( lay : : Cursor : : closed_hand ) ; }
Class < gsi : : CursorNamespace > decl_Cursor ( " Cursor " ,
method ( " None " , & cursor_shape_none , " @brief 'No cursor (default)' constant for \\ set_cursor (resets cursor to default) " ) +
method ( " Arrow " , & cursor_shape_arrow , " @brief 'Arrow cursor' constant " ) +
method ( " UpArrow " , & cursor_shape_up_arrow , " @brief 'Upward arrow cursor' constant " ) +
method ( " Cross " , & cursor_shape_cross , " @brief 'Cross cursor' constant " ) +
method ( " Wait " , & cursor_shape_wait , " @brief 'Waiting cursor' constant " ) +
method ( " IBeam " , & cursor_shape_i_beam , " @brief 'I beam (text insert) cursor' constant " ) +
method ( " SizeVer " , & cursor_shape_size_ver , " @brief 'Vertical resize cursor' constant " ) +
method ( " SizeHor " , & cursor_shape_size_hor , " @brief 'Horizontal resize cursor' constant " ) +
method ( " SizeBDiag " , & cursor_shape_size_bdiag , " @brief 'Backward diagonal resize cursor' constant " ) +
method ( " SizeFDiag " , & cursor_shape_size_fdiag , " @brief 'Forward diagonal resize cursor' constant " ) +
method ( " SizeAll " , & cursor_shape_size_all , " @brief 'Size all directions cursor' constant " ) +
method ( " Blank " , & cursor_shape_blank , " @brief 'Blank cursor' constant " ) +
method ( " SplitV " , & cursor_shape_split_v , " @brief 'Split vertical cursor' constant " ) +
method ( " SplitH " , & cursor_shape_split_h , " @brief 'split_horizontal cursor' constant " ) +
method ( " PointingHand " , & cursor_shape_pointing_hand , " @brief 'Pointing hand cursor' constant " ) +
method ( " Forbidden " , & cursor_shape_forbidden , " @brief 'Forbidden area cursor' constant " ) +
method ( " WhatsThis " , & cursor_shape_whats_this , " @brief 'Question mark cursor' constant " ) +
method ( " Busy " , & cursor_shape_busy , " @brief 'Busy state cursor' constant " ) +
method ( " OpenHand " , & cursor_shape_open_hand , " @brief 'Open hand cursor' constant " ) +
method ( " ClosedHand " , & cursor_shape_closed_hand , " @brief 'Closed hand cursor' constant " ) ,
" @brief The namespace for the cursor constants \n "
" This class defines the constants for the cursor setting (for example for class \\ Plugin, method set_cursor). "
" \n "
" This class has been introduced in version 0.22. \n "
) ;
class ButtonStateNamespace { } ;
static int const_ShiftButton ( ) { return ( int ) lay : : ShiftButton ; }
static int const_ControlButton ( ) { return ( int ) lay : : ControlButton ; }
static int const_AltButton ( ) { return ( int ) lay : : AltButton ; }
static int const_LeftButton ( ) { return ( int ) lay : : LeftButton ; }
static int const_MidButton ( ) { return ( int ) lay : : MidButton ; }
static int const_RightButton ( ) { return ( int ) lay : : RightButton ; }
Class < gsi : : ButtonStateNamespace > decl_ButtonState ( " ButtonState " ,
method ( " ShiftKey " , & const_ShiftButton , " @brief Indicates that the Shift key is pressed \n This constant is combined with other constants within \\ ButtonState " ) +
method ( " ControlKey " , & const_ControlButton , " @brief Indicates that the Control key is pressed \n This constant is combined with other constants within \\ ButtonState " ) +
method ( " AltKey " , & const_AltButton , " @brief Indicates that the Alt key is pressed \n This constant is combined with other constants within \\ ButtonState " ) +
method ( " LeftButton " , & const_LeftButton , " @brief Indicates that the left mouse button is pressed \n This constant is combined with other constants within \\ ButtonState " ) +
method ( " MidButton " , & const_MidButton , " @brief Indicates that the middle mouse button is pressed \n This constant is combined with other constants within \\ ButtonState " ) +
method ( " RightButton " , & const_RightButton , " @brief Indicates that the right mouse button is pressed \n This constant is combined with other constants within \\ ButtonState " ) ,
" @brief The namespace for the button state flags in the mouse events of the Plugin class. \n "
" This class defines the constants for the button state. In the event handler, the button state is "
" indicated by a bitwise combination of these constants. See \\ Plugin for further details. "
" \n "
" This class has been introduced in version 0.22. \n "
) ;
static std : : vector < std : : string >
get_config_names ( lay : : PluginRoot * view )
{
std : : vector < std : : string > names ;
view - > get_config_names ( names ) ;
return names ;
}
lay : : PluginRoot * config_root_instance ( )
{
return lay : : PluginRoot : : instance ( ) ;
}
/**
* @ brief Exposes the PluginRoot interface
*
* This interface is intentionally not derived from Plugin . It is used currently to
* identify the plugin root node for configuration . The Plugin nature of this interface
* is somewhat artificial and may be removed later .
*
* TODO : this is a duplicate of the respective methods in LayoutView and MainWindow .
* This is intentional since we don ' t want to spend the only derivation path on this .
* Once there is a mixin concept , provide a path through that concept .
*/
Class < lay : : PluginRoot > decl_PluginRoot ( " PluginRoot " ,
method ( " clear_config " , & lay : : PluginRoot : : clear_config ,
" @brief Clears the configuration parameters \n "
) +
method ( " instance " , & config_root_instance ,
" @brief Gets the singleton instance of the PluginRoot object \n "
" \n "
" @return The instance \n "
) +
method ( " write_config " , & lay : : PluginRoot : : write_config ,
" @brief Writes configuration to a file \n "
" @args file_name \n "
" @return A value indicating whether the operation was successful \n "
" \n "
" If the configuration file cannot be written, false \n "
" is returned but no exception is thrown. \n "
) +
method ( " read_config " , & lay : : PluginRoot : : read_config ,
" @brief Reads the configuration from a file \n "
" @args file_name \n "
" @return A value indicating whether the operation was successful \n "
" \n "
" This method siletly does nothing, if the config file does not \n "
" exist. If it does and an error occured, the error message is printed \n "
" on stderr. In both cases, false is returned. \n "
) +
method ( " get_config " , ( bool ( lay : : PluginRoot : : * ) ( const std : : string & , std : : string & ) const ) & lay : : PluginRoot : : config_get ,
" @brief Get the value of a local configuration parameter \n "
" \n "
" @args name \n "
" @param name The name of the configuration parameter whose value shall be obtained (a string) \n "
" \n "
" @return The value of the parameter \n "
) +
method ( " set_config " , ( void ( lay : : PluginRoot : : * ) ( const std : : string & , const std : : string & ) ) & lay : : PluginRoot : : config_set ,
" @brief Set a local configuration parameter with the given name to the given value \n "
" \n "
" @args name, value \n "
" @param name The name of the configuration parameter to set \n "
" @param value The value to which to set the configuration parameter \n "
" \n "
" This method sets a configuration parameter with the given name to the given value. "
" Values can only be strings. Numerical values have to be converted into strings first. "
" Local configuration parameters override global configurations for this specific view. "
" This allows for example to override global settings of background colors. "
" Any local settings are not written to the configuration file. "
) +
method_ext ( " get_config_names " , & get_config_names ,
" @brief Gets the configuration parameter names \n "
" \n "
" @return A list of configuration parameter names \n "
" \n "
" This method returns the names of all known configuration parameters. These names can be used to "
" get and set configuration parameter values. \n "
) +
method ( " commit_config " , & lay : : PluginRoot : : config_end ,
" @brief Commits the configuration settings \n "
" \n "
" Some configuration options are queued for performance reasons and become active only after 'commit_config' has been called. "
" After a sequence of \\ set_config calls, this method should be called to activate the "
" settings made by these calls. \n "
) ,
" @brief Root of the configuration space in the plugin context \n "
" \n "
" This class provides access to the root configuration space. This object provides access to the configuration space in the context "
" of plugin programming. \n "
" Plugins are organized in a configuration tree. Configuration settings are propagated down to the individual plugins. "
" If there is a main window, the configuration root is identical with this object, so configuration settings "
" applied in the configuration root are available to all views. \n "
" \n "
" This class has been introduced in version 0.25. \n "
) ;
}