diff options
author | Ian Thompson <quornian@googlemail.com> | 2008-06-24 19:25:25 +0400 |
---|---|---|
committer | Ian Thompson <quornian@googlemail.com> | 2008-06-24 19:25:25 +0400 |
commit | bdc030c664640db727ea21a1e854bb62032bf705 (patch) | |
tree | 2897a9a9bea8a9e599a0dc54c1c84703ed913b4c /source/blender | |
parent | 05ce388f358b1cfa7bc7c63e29bd772efbf25d39 (diff) |
Text plugin basis with plugin for suggestions/completions. The suggest plugin works for imported global variables, methods, modules and module members. For example typing:
import Blender
from Blender import *
| <- cursor here suggests globals
Blender.Draw.gl| <- cursor here suggests all Draw members starting gl
Currently suggestions are listed in the console when the space is redrawn but will be presented as a menu-style list soon. Also to add are shortcut/activation keys to allow plugins to respond to certain key strokes.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_suggestions.h | 77 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/suggestions.c | 125 | ||||
-rw-r--r-- | source/blender/python/BPY_interface.c | 1 | ||||
-rw-r--r-- | source/blender/python/BPY_menus.c | 5 | ||||
-rw-r--r-- | source/blender/python/BPY_menus.h | 1 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Text.c | 57 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Text.py | 12 | ||||
-rw-r--r-- | source/blender/src/drawtext.c | 15 | ||||
-rw-r--r-- | source/blender/src/header_text.c | 32 | ||||
-rw-r--r-- | source/blender/src/usiblender.c | 3 |
10 files changed, 327 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h new file mode 100644 index 00000000000..bc4e18f5a67 --- /dev/null +++ b/source/blender/blenkernel/BKE_suggestions.h @@ -0,0 +1,77 @@ +/** + * $Id: $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008, Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef BKE_SUGGESTIONS_H +#define BKE_SUGGESTIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* **************************************************************************** +Suggestions must be added in sorted order (no attempt is made to sort the list) +The list is then divided up based on the prefix provided by update_suggestions: +Example: + Prefix: ab + aaa <-- first + aab + aba <-- firstmatch + abb <-- lastmatch + baa + bab <-- last +**************************************************************************** */ + +struct Text; + +typedef struct SuggItem { + struct SuggItem *prev, *next; + char *name; + char type; +} SuggItem; + +typedef struct SuggList { + SuggItem *first, *last; + SuggItem *firstmatch, *lastmatch; +} SuggList; + +void free_suggestions(); + +void add_suggestion(const char *name, char type); +void update_suggestions(const char *prefix); +SuggItem *suggest_first(); +SuggItem *suggest_last(); + +void set_suggest_text(Text *text); +void clear_suggest_text(); +short is_suggest_active(Text *text); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c new file mode 100644 index 00000000000..3842146376d --- /dev/null +++ b/source/blender/blenkernel/intern/suggestions.c @@ -0,0 +1,125 @@ +/** + * $Id: $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008, Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "DNA_text_types.h" +#include "BKE_text.h" +#include "BKE_suggestions.h" + +static SuggList suggestions= {NULL, NULL, NULL, NULL}; +static Text *suggText = NULL; + +void free_suggestions() { + SuggItem *item; + for (item = suggestions.last; item; item=item->prev) + MEM_freeN(item); + suggestions.first = suggestions.last = NULL; + suggestions.firstmatch = suggestions.lastmatch = NULL; +} + +void add_suggestion(const char *name, char type) { + SuggItem *newitem; + + newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem"); + if (!newitem) { + printf("Failed to allocate memory for suggestion.\n"); + return; + } + + newitem->name = (char *) (newitem + 1); + strcpy(newitem->name, name); + newitem->type = type; + newitem->prev = newitem->next = NULL; + + if (!suggestions.first) { + suggestions.first = suggestions.last = newitem; + } else { + newitem->prev = suggestions.last; + suggestions.last->next = newitem; + suggestions.last = newitem; + } +} + +void update_suggestions(const char *prefix) { + SuggItem *match, *first, *last; + int cmp, len = strlen(prefix); + + if (!suggestions.first) return; + if (len==0) { + suggestions.firstmatch = suggestions.first; + suggestions.lastmatch = suggestions.last; + return; + } + + first = last = NULL; + for (match=suggestions.first; match; match=match->next) { + cmp = strncmp(prefix, match->name, len); + if (cmp==0) { + if (!first) + first = match; + } else if (cmp<0) { + if (!last) { + last = match->prev; + break; + } + } + } + if (first) { + if (!last) last = suggestions.last; + suggestions.firstmatch = first; + suggestions.lastmatch = last; + } else { + suggestions.firstmatch = suggestions.lastmatch = NULL; + } +} + +SuggItem *suggest_first() { + return suggestions.firstmatch; +} + +SuggItem *suggest_last() { + return suggestions.lastmatch; +} + +void set_suggest_text(Text *text) { + suggText = text; +} + +void clear_suggest_text() { + free_suggestions(); + suggText = NULL; +} + +short is_suggest_active(Text *text) { + return suggText==text ? 1 : 0; +} diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 7c23c86d9ba..360c8fd7f04 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -1066,6 +1066,7 @@ int BPY_menu_do_python( short menutype, int event ) case PYMENU_RENDER: case PYMENU_WIZARDS: case PYMENU_SCRIPTTEMPLATE: + case PYMENU_TEXTPLUGIN: case PYMENU_MESHFACEKEY: break; diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c index 82da9edbee6..08691973a92 100644 --- a/source/blender/python/BPY_menus.c +++ b/source/blender/python/BPY_menus.c @@ -106,6 +106,8 @@ static int bpymenu_group_atoi( char *str ) return PYMENU_ARMATURE; else if( !strcmp( str, "ScriptTemplate" ) ) return PYMENU_SCRIPTTEMPLATE; + else if( !strcmp( str, "TextPlugin" ) ) + return PYMENU_TEXTPLUGIN; else if( !strcmp( str, "MeshFaceKey" ) ) return PYMENU_MESHFACEKEY; else if( !strcmp( str, "AddMesh" ) ) @@ -184,6 +186,9 @@ char *BPyMenu_group_itoa( short menugroup ) case PYMENU_SCRIPTTEMPLATE: return "ScriptTemplate"; break; + case PYMENU_TEXTPLUGIN: + return "TextPlugin"; + break; case PYMENU_MESHFACEKEY: return "MeshFaceKey"; break; diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h index 1b557f79286..e8bca09d50e 100644 --- a/source/blender/python/BPY_menus.h +++ b/source/blender/python/BPY_menus.h @@ -99,6 +99,7 @@ typedef enum { PYMENU_UVCALCULATION, PYMENU_ARMATURE, PYMENU_SCRIPTTEMPLATE, + PYMENU_TEXTPLUGIN, PYMENU_HELP,/*Main Help menu items - prob best to leave for 'official' ones*/ PYMENU_HELPSYSTEM,/* Resources, troubleshooting, system tools */ PYMENU_HELPWEBSITES,/* Help -> Websites submenu */ diff --git a/source/blender/python/api2_2x/Text.c b/source/blender/python/api2_2x/Text.c index 603deb768ad..63c77c0bb3e 100644 --- a/source/blender/python/api2_2x/Text.c +++ b/source/blender/python/api2_2x/Text.c @@ -34,8 +34,11 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BIF_drawtext.h" +#include "BIF_screen.h" #include "BKE_text.h" +#include "BKE_suggestions.h" #include "BLI_blenlib.h" +#include "DNA_screen_types.h" #include "DNA_space_types.h" #include "gen_utils.h" #include "gen_library.h" @@ -96,6 +99,7 @@ static PyObject *Text_set( BPy_Text * self, PyObject * args ); static PyObject *Text_asLines( BPy_Text * self ); static PyObject *Text_getCursorPos( BPy_Text * self ); static PyObject *Text_setCursorPos( BPy_Text * self, PyObject * args ); +static PyObject *Text_suggest( BPy_Text * self, PyObject * args ); /*****************************************************************************/ /* Python BPy_Text methods table: */ @@ -124,6 +128,8 @@ static PyMethodDef BPy_Text_methods[] = { "() - Return cursor position as (row, col) tuple"}, {"setCursorPos", ( PyCFunction ) Text_setCursorPos, METH_VARARGS, "(row, col) - Set the cursor position to (row, col)"}, + {"suggest", ( PyCFunction ) Text_suggest, METH_VARARGS, + "(list) - List of tuples of the form (name, type) where type is one of 'm', 'v', 'f' for module, variable and function respectively"}, {NULL, NULL, 0, NULL} }; @@ -511,6 +517,57 @@ static PyObject *Text_setCursorPos( BPy_Text * self, PyObject * args ) Py_RETURN_NONE; } +static PyObject *Text_suggest( BPy_Text * self, PyObject * args ) +{ + PyObject *item = NULL; + PyObject *list = NULL, *resl = NULL; + int list_len, i; + char *prefix, *name, type; + SpaceText *st; + + if(!self->text) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "This object isn't linked to a Blender Text Object"); + + /* Parse args for a list of tuples */ + if(!PyArg_ParseTuple(args, "O!s", &PyList_Type, &list, &prefix)) + return EXPP_ReturnPyObjError(PyExc_TypeError, + "expected list of tuples followed by a string"); + + if (curarea->spacetype != SPACE_TEXT) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "Active space type is not text"); + + st = curarea->spacedata.first; + if (!st || !st->text) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "Active text area has no Text object"); + + list_len = PyList_Size(list); + clear_suggest_text(); + + for (i = 0; i < list_len; i++) { + item = PyList_GetItem(list, i); + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) + return EXPP_ReturnPyObjError(PyExc_AttributeError, + "list must contain only tuples of size 2" ); + + name = PyString_AsString(PyTuple_GetItem(item, 0)); + type = PyString_AsString(PyTuple_GetItem(item, 1))[0]; + + if (!strlen(name) || (type!='m' && type!='v' && type!='f')) + return EXPP_ReturnPyObjError(PyExc_AttributeError, + "layer values must be in the range [1, 20]" ); + + add_suggestion(name, type); + } + update_suggestions(prefix); + set_suggest_text(st->text); + scrarea_queue_redraw(curarea); + + Py_RETURN_NONE; +} + /*****************************************************************************/ /* Function: Text_compare */ /* Description: This is a callback function for the BPy_Text type. It */ diff --git a/source/blender/python/api2_2x/doc/Text.py b/source/blender/python/api2_2x/doc/Text.py index 4099b13828d..920908eef81 100644 --- a/source/blender/python/api2_2x/doc/Text.py +++ b/source/blender/python/api2_2x/doc/Text.py @@ -150,5 +150,15 @@ class Text: cursor. """ + def suggest(list): + """ + Set the suggestion list to the given list of tuples. This list *must* be + sorted by its first element, name. + @type list: list of tuples + @param list: List of pair-tuples of the form (name, type) where name is + the suggested name and type is one of 'm' (module or class), 'f' + (function or method), 'v' (variable). + """ + import id_generics -Text.__doc__ += id_generics.attributes
\ No newline at end of file +Text.__doc__ += id_generics.attributes diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c index 882baa90c65..227d1f08c20 100644 --- a/source/blender/src/drawtext.c +++ b/source/blender/src/drawtext.c @@ -60,6 +60,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_suggestions.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -999,6 +1000,19 @@ static void do_selection(SpaceText *st, int selecting) txt_undo_add_toop(st->text, UNDO_STO, sell, selc, linep2, charp2); } +void draw_suggestion_list(SpaceText *st) { + SuggItem *item, *last; + + if (!is_suggest_active(st->text)) return; + + for (item=suggest_first(), last=suggest_last(); item; item=item->next) { + /* Useful for testing but soon to be replaced by UI list */ + printf("Suggest: %c %s\n", item->type, item->name); + if (item == last) + break; + } +} + void drawtextspace(ScrArea *sa, void *spacedata) { SpaceText *st= curarea->spacedata.first; @@ -1072,6 +1086,7 @@ void drawtextspace(ScrArea *sa, void *spacedata) } draw_textscroll(st); + draw_suggestion_list(st); curarea->win_swap= WIN_BACK_OK; } diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c index 7f281096479..e371bd56160 100644 --- a/source/blender/src/header_text.c +++ b/source/blender/src/header_text.c @@ -240,6 +240,37 @@ static uiBlock *text_template_scriptsmenu (void *args_unused) return block; } +static void do_text_plugin_scriptsmenu(void *arg, int event) +{ + BPY_menu_do_python(PYMENU_TEXTPLUGIN, event); + + allqueue(REDRAWIMAGE, 0); +} + +static uiBlock *text_plugin_scriptsmenu (void *args_unused) +{ + uiBlock *block; + BPyMenu *pym; + int i= 0; + short yco = 20, menuwidth = 120; + + block= uiNewBlock(&curarea->uiblocks, "text_plugin_scriptsmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_text_plugin_scriptsmenu, NULL); + + /* note that we acount for the N previous entries with i+20: */ + for (pym = BPyMenuTable[PYMENU_TEXTPLUGIN]; pym; pym = pym->next, i++) { + + uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, + NULL, 0.0, 0.0, 1, i, + pym->tooltip?pym->tooltip:pym->filename); + } + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 60); + + return block; +} + /* action executed after clicking in File menu */ static void do_text_filemenu(void *arg, int event) { @@ -726,6 +757,7 @@ static uiBlock *text_filemenu(void *arg_unused) } uiDefIconTextBlockBut(block, text_template_scriptsmenu, NULL, ICON_RIGHTARROW_THIN, "Script Templates", 0, yco-=20, 120, 19, ""); + uiDefIconTextBlockBut(block, text_plugin_scriptsmenu, NULL, ICON_RIGHTARROW_THIN, "Text Plugins", 0, yco-=20, 120, 19, ""); if(curarea->headertype==HEADERTOP) { uiBlockSetDirection(block, UI_DOWN); diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 6c0838288b8..2e55f8cdbc2 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -67,6 +67,7 @@ #include "DNA_sound_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_text_types.h" #include "BKE_blender.h" #include "BKE_curve.h" @@ -79,6 +80,7 @@ #include "BKE_mball.h" #include "BKE_node.h" #include "BKE_packedFile.h" +#include "BKE_suggestions.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_pointcache.h" @@ -1091,6 +1093,7 @@ void exit_usiblender(void) free_actcopybuf(); free_vertexpaint(); free_imagepaint(); + free_suggestions(); /* editnurb can remain to exist outside editmode */ freeNurblist(&editNurb); |