SF.net SVN: geany:[3581] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Sat Feb 14 17:37:29 UTC 2009
Revision: 3581
http://geany.svn.sourceforge.net/geany/?rev=3581&view=rev
Author: eht16
Date: 2009-02-14 17:37:28 +0000 (Sat, 14 Feb 2009)
Log Message:
-----------
Add a plugin howto to the plugin API docs, written by Frank.
Modified Paths:
--------------
trunk/ChangeLog
trunk/doc/plugins.dox
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-02-14 11:53:42 UTC (rev 3580)
+++ trunk/ChangeLog 2009-02-14 17:37:28 UTC (rev 3581)
@@ -1,3 +1,9 @@
+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:
Modified: trunk/doc/plugins.dox
===================================================================
--- trunk/doc/plugins.dox 2009-02-14 11:53:42 UTC (rev 3580)
+++ trunk/doc/plugins.dox 2009-02-14 17:37:28 UTC (rev 3581)
@@ -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 @@
* plugins by writing a simple "Hello World" plugin in C.
*
*
- * @section start Getting started
+ * @section buildenv Build environment
*
- * @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
- *
* 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"
*
- * @section helloworld "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.
*
- * We want to write a really simple "Hello World" plugin which opens a message dialog
- * and just prints "Hello World".
+ * 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
*
- * ... to be continued ...
+ * @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.
+ *
+ * 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 at 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 at 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 at 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
+ *
**/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list