Kaydet (Commit) b4223479 authored tarafından Enrico Tröger's avatar Enrico Tröger

Add a plugin howto to the plugin API docs, written by Frank.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3581 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 08fd390c
2009-02-14 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* doc/plugins.dox:
Add a plugin howto to the plugin API docs, written by Frank.
2009-02-13 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/msgwindow.c:
......
......@@ -3,6 +3,7 @@
*
* Copyright 2008-2009 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* Copyright 2008-2009 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* Copyright 2009 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
*
* 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
......@@ -30,7 +31,7 @@
*
* @mainpage Geany Plugin API Documentation
*
* @author Enrico Tröger, Nick Treleaven
* @author Enrico Tröger, Nick Treleaven, Frank Lanitz
* @date $Date$
*
* @section Intro
......@@ -331,70 +332,229 @@ PluginCallback plugin_callbacks[] =
* plugins by writing a simple "Hello World" plugin in C.
*
*
* @section start Getting started
*
* @subsection structure Plugin structure
*
* Every plugin must contain some essential symbols unless it won't work. A complete
* list of all necessary and optional symbols can be found in
* @link pluginsymbols.c Plugin Symbols @endlink.
* Every plugin should include "geany.h" and "plugindata.h" which provide necessary
* preprocessor macros and other basic information.
* There are two important preprocessor macros which need to be used at the beginning:
* PLUGIN_SET_INFO() and PLUGIN_VERSION_CHECK().
*
* PLUGIN_SET_INFO() tells Geany about basic plugin information like name, description,
* version and author of the plugin.
*
* PLUGIN_VERSION_CHECK() checks for compatibility of the API version which
* the plugin uses with the used Geany sources. Furthermore, it also checks
* the binary compatiblity of the plugin with Geany.
*
* A few functions are necessary to let Geany work with the plugin, at least plugin_init() must
* exist in the plugin. plugin_cleanup() should also be used to free allocated memory or destroy
* created widgets.
*
* @subsection buildenv Build environment
* @section buildenv Build environment
*
* To be able to write plugins for Geany, you need the source code and some development
* packages for GTK and its dependencies. I will only describe the way to compile and
* packages for GTK and its dependencies. The following will only describe the way to compile and
* build plugins on Unix-like systems [1].
* If you already have the Geany source code and compiled it from them, you can skip the
* following.
*
* First you need to get the source code of Geany from the website at
* http://www.geany.org/Download/Releases [2]. Then install the development files for GTK
* First you need to have Geany installed. Then install the development files for GTK
* and its dependencies. The easiest way to do this is to use your distribution's package
* management system, e.g. on Debian and Ubuntu systems you can use
* @code apt-get install libgtk2.0-dev intltool @endcode
* This will install all necessary files to be able to compile Geany and plugins. On other
* This will install all necessary files to be able to compile plugins for Geany. On other
* distributions, the package names and commands to use may differ.
*
* Basically, we are done at this point and could continue with writing the plugin code.
* You don't need necessarily to configure and build the Geany sources when the sources
* have the same version as your running Geany installation. But if the version of the
* sources differ from your Geany installation or especially when you used the source code
* from the Subversion repository, we strongly recommend to configure and build these
* sources and use it. To do so, run @code
./configure && make
su -c "make install"
* @endcode
* in your Geany source directory. This will build and install Geany on your system.
* Basically, you are done at this point and could continue with writing the plugin code.
*
* [1] For Windows, it is basically the same but you might have some more work on setting up
* the general build environment(compiler, GTK development files, ...). This is described on
* Geany's website at http://www.geany.org/Support/BuildingOnWin32.
*
* [2] You can also use the bleedging edge source code from our Subversion repository.
* More information about this can be found at http://www.geany.org/Download/SVN.
*
* @section helloworld "Hello World"
*
* We want to write a really simple "Hello World" plugin which opens a message dialog
* and just prints "Hello World".
* When writing a plugin, you will find a couple of functions or macros which are mandatory
* and some which are free to use for implementing some useful feature once your plugin
* becomes more powerful like including a configuration or help dialog.
*
* You should start your plugin with including some of the needed C header files and defining
* some basic global variables which will help you to access all needed functions of the plugin
* API in a more comfortable way.
*
* Let's start with the very basic headers and add more later if necessary.
* @code
#include "geany.h"
#include "plugindata.h"
#include "geanyfunctions.h"
* @endcode
*
* @a geany.h will include the necessary GTK header files, so there is no need to include
* @a gtk/gtk.h yourself.
*
* @a plugindata.h contains the biggest part of the plugin API and provides some basic macros.
*
* @a geanyfunctions.h provide some macros for convenient access to the plugin API.
*
* Later, you will note that by adding more functionality more header file includes will be
* necessary. Best practice for including header files is to always include @a geany.h at first,
* then include other necessary header files and at last include plugindata.h and @a
* geanyfunctions.h.
*
* The you should define three basic variables which will give access to data fields and
* functions provided by the plugin API.
* @code
GeanyPlugin *geany_plugin;
GeanyData *geany_data;
GeanyFunctions *geany_functions;
* @endcode
*
* Now you can go on and write your first lines for your new plugin. As mentioned before,
* you will need to implement and fill out a couple of functions/macros to make the plugin work.
* So let's start with PLUGIN_VERSION_CHECK().
*
* PLUGIN_VERSION_CHECK() is a convenient way to tell Geany which version of Geany's plugin API
* is needed at minimum to run your plugin. The value is defined in
* @a plugindata.h by @a GEANY_API_VERSION. In most cases this should be your minimum.
* Nevertheless when setting this value, you should choose the lowest possible version here to
* make the plugin compatible with a bigger number of versions of Geany.
*
* As the next step, you will need to tell Geany a couple of basic information of your plugin,
* so it is able to show them e.g. on the plugin manager dialog.
*
* ... to be continued ...
* For doing this, you should use PLUGIN_SET_INFO() which expects 4 values:
* - Plugin name that should appear on the plugin manager dialog
* - Short plugin description
* - Plugin version
* - Author.
*
* Based on this, the line could look like:
* @code
PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
"1.0", "John Doe <john.doe@example.org>");
* @endcode
*
* Once this is done, you will need to implement the function which will be executed when the
* plugin is loaded. Part of that function could be adding and removing of an item to
* Geany's Tools menu, setting up keybindings or registering some callbacks. Also you will
* need to implement the function that is called when your plugin is unloaded.
* These functions are called plugin_init() and plugin_cleanup(). Let's see how it could look like:
* @code
PLUGIN_VERSION_CHECK(130)
PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
"1.0", "Joe Doe <joe.doe@example.org>");
void plugin_init(GeanyData *data)
{
}
void plugin_cleanup(void)
{
}
* @endcode
*
* If you think this plugin seems to doesn't implement any function right now and only waste
* some memory, you are right. At least, it should compile and load/unload on in Geany nicely.
* Now you have the very basic layout of a new plugin. Great, isn't it?
*
* Let's go on and implement some real functionality.
*
* As mentioned before, plugin_init() will be called when the plugin is loaded in Geany.
* So it should implement everything that needs to be done during startup. In this example case,
* we like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
* @code
void plugin_init(GeanyData *data)
{
GtkWidget *main_menu_item;
// Create a new menu item and show it
main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
gtk_widget_show(main_menu_item);
// Attach the new menu item to the Tools menu
gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
main_menu_item);
// Connect the menu item with a callback function
// which is called when the item is clicked
g_signal_connect(main_menu_item, "activate",
G_CALLBACK(item_activate_cb), NULL);
}
* @endcode
*
* This will add an item to the Tools menu and connect this item to a function which implements
* what should be done when the menu item is activated by the user.
* This is done by g_signal_connect(). The Tools menu can be accessed with
* geany->main_widgets->tools_menu. The structure @a main_widgets contains pointers to some
* main GUI elements in Geany. To be able to use it, you must include ui_utils.h. This can
* be done by adding the following line to the include section of your code.
* @code
#include "ui_utils.h"
* @endcode
*
* Geany is offering a simple API for showing message dialogs. So the function contains
* only a few lines like:
* @code
void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
{
dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
}
* @endcode
*
* For the moment you don't need to worry about the parameters of that function.
*
* Do you remember, you need to clean up when unloading the plugin? Because of this,
* some more action is required.
*
* To remove the menu item from the Tools menu, you can use gtk_widget_destroy().
* gtk_widget_destroy() expects a pointer to a GtkWidget object.
*
* First you should add gtk_widget_destroy() to your plugin_cleanup() function.
* The argument for gtk_widget_destroy() is the widget object you created earlier in
* plugin_init(). To be able to access this pointer in plugin_cleanup(), you need to move
* its definition from plugin_init() into the global context so its visibility will increase
* and it can be accessed in all functions.
* @code
static GtkWidget *main_menu_item = NULL;
// ...
void plugin_init(GeanyData *data)
{
main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
gtk_widget_show(main_menu_item);
// ...
}
void plugin_cleanup(void)
{
gtk_widget_destroy(main_menu_item);
}
* @endcode
*
* This will ensure, your menu item will be removed from the Tools menu as well as from
* memory once your plugin is unloaded and you don't leave any memory leaks back.
* Once this is done, your first plugin is ready. Congratulations!
*
* The complete listing (without comments):
* @code
#include "geany.h"
#include "ui_utils.h"
#include "plugindata.h"
#include "geanyfunctions.h"
GeanyPlugin *geany_plugin;
GeanyData *geany_data;
GeanyFunctions *geany_functions;
PLUGIN_VERSION_CHECK(130)
PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
"1.0", "John Doe <john.doe@example.org>");
static GtkWidget *main_menu_item = NULL;
static void item_activate_cb(GtkMenuItem *menuitem, gpointer gdata)
{
dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
}
void plugin_init(GeanyData *data)
{
main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
gtk_widget_show(main_menu_item);
gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
main_menu_item);
g_signal_connect(main_menu_item, "activate",
G_CALLBACK(item_activate_cb), NULL);
}
void plugin_cleanup(void)
{
gtk_widget_destroy(main_menu_item);
}
* @endcode
*
**/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment