/* text widget for Pd Copyright 2003 Guenter Geiger Copyright 2004 Ben Bogart Copyright 2007 Hans-Christoph Steiner 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "shared/tkwidgets.h" /* TODO: get Ctrl-A working to select all */ /* TODO: set message doesnt work with a loadbang */ #define DEFAULT_COLOR "grey70" #define TEXT_DEFAULT_WIDTH 130 #define TEXT_DEFAULT_HEIGHT 60 #define TEXT_MIN_WIDTH 40 #define TEXT_MIN_HEIGHT 20 #define TOTAL_INLETS 1 #define TOTAL_OUTLETS 2 #define DEBUG(x) x typedef struct _textwidget { t_object x_obj; t_canvas* x_canvas; t_glist* x_glist; t_symbol* x_receive_name; int x_height; int x_width; int x_resizing; t_symbol* x_font_face; t_int x_font_size; t_symbol* x_font_weight; t_float x_border; t_symbol* x_relief; t_int x_have_scrollbar; t_int x_selected; /* IDs for Tk widgets */ char* tcl_namespace; char* canvas_id; char* frame_id; char* text_id; char* scrollbar_id; char* handle_id; char* window_tag; char* all_tag; t_outlet* x_data_outlet; t_outlet* x_status_outlet; } t_textwidget; static t_class *textwidget_class; static char *tk_options[] = { "autoseparators", "background", "borderwidth", "cursor", "exportselection", "font", "foreground", "height", "highlightbackground", "highlightcolor", "highlightthickness", "insertbackground", "insertborderwidth", "insertofftime", "insertontime", "insertwidth", "maxundo", "padx", "pady", "relief", "selectbackground", "selectborderwidth", "selectforeground", "setgrid", "spacing1", "spacing2", "spacing3", "state", "tabs", "takefocus", "undo", "width", "wrap", "xscrollcommand", "yscrollcommand" }; /* move these to tkwidgets.c */ static t_symbol *backspace_symbol; static t_symbol *return_symbol; static t_symbol *space_symbol; static t_symbol *tab_symbol; static t_symbol *escape_symbol; static t_symbol *left_symbol; static t_symbol *right_symbol; static t_symbol *up_symbol; static t_symbol *down_symbol; /* function prototypes */ static void textwidget_getrect(t_gobj *z, t_glist *owner, int *xp1, int *yp1, int *xp2, int *yp2); static void textwidget_displace(t_gobj *z, t_glist *glist, int dx, int dy); static void textwidget_select(t_gobj *z, t_glist *glist, int state); static void textwidget_activate(t_gobj *z, t_glist *glist, int state); static void textwidget_delete(t_gobj *z, t_glist *glist); static void textwidget_vis(t_gobj *z, t_glist *glist, int vis); //static int textwidget_click(t_gobj *z, t_glist *glist, int xpix, int ypix, int shift, int alt, int dbl, int doit); static void textwidget_save(t_gobj *z, t_binbuf *b); static t_widgetbehavior textwidget_widgetbehavior = { w_getrectfn: textwidget_getrect, w_displacefn: textwidget_displace, w_selectfn: textwidget_select, w_activatefn: textwidget_activate, w_deletefn: textwidget_delete, w_visfn: textwidget_vis, w_clickfn: NULL, }; /* widget helper functions */ static void set_tk_widget_ids(t_textwidget *x, t_canvas *canvas) { char buf[MAXPDSTRING]; x->x_canvas = canvas; /* Tk ID for the current canvas that this object is drawn in */ sprintf(buf,".x%lx.c", (long unsigned int) canvas); x->canvas_id = getbytes(strlen(buf)); strcpy(x->canvas_id, buf); /* Tk ID for the "frame" the other things are drawn in */ sprintf(buf,"%s.frame%lx", x->canvas_id, (long unsigned int)x); x->frame_id = getbytes(strlen(buf)); strcpy(x->frame_id, buf); sprintf(buf,"%s.text%lx", x->frame_id, (long unsigned int)x); x->text_id = getbytes(strlen(buf)); strcpy(x->text_id, buf); /* Tk ID for the "text", the meat! */ sprintf(buf,"%s.window%lx", x->canvas_id, (long unsigned int)x); x->window_tag = getbytes(strlen(buf)); strcpy(x->window_tag, buf); /* Tk ID for the resizing "window" */ post(""); sprintf(buf,"%s.handle%lx", x->canvas_id, (long unsigned int)x); x->handle_id = getbytes(strlen(buf)); strcpy(x->handle_id, buf); /* Tk ID for the resizing "handle" */ sprintf(buf,"%s.scrollbar%lx", x->frame_id, (long unsigned int)x); x->scrollbar_id = getbytes(strlen(buf)); strcpy(x->scrollbar_id, buf); /* Tk ID for the optional "scrollbar" */ sprintf(buf,"all%lx", (long unsigned int)x); x->all_tag = getbytes(strlen(buf)); strcpy(x->all_tag, buf); /* Tk ID for the optional "scrollbar" */ } static int calculate_onset(t_textwidget *x, t_glist *glist, int current_iolet, int total_iolets) { post("calculate_onset"); return(text_xpix(&x->x_obj, glist) + (x->x_width - IOWIDTH) \ * current_iolet / (total_iolets == 1 ? 1 : total_iolets - 1)); } static void textwidget_draw_inlets(t_textwidget *x, t_glist *glist, int firsttime, int total_inlets, int total_outlets) { DEBUG(post("textwidget_draw_inlets in: %d out: %d", total_inlets, total_outlets);); int i, onset; for (i = 0; i < total_inlets; i++) /* inlets */ { onset = calculate_onset(x, glist, i, total_inlets); sys_vgui("%s create rectangle %d %d %d %d -tags {%xi%d %xi %s}\n", x->canvas_id, onset, text_ypix(&x->x_obj, glist) - 2, onset + IOWIDTH, text_ypix(&x->x_obj, glist), x, i, x, x->all_tag); } for (i = 0; i < total_outlets; i++) /* outlets */ { onset = calculate_onset(x, glist, i, total_outlets); sys_vgui("%s create rectangle %d %d %d %d -tags {%xo%d %xo %s}\n", x->canvas_id, onset, text_ypix(&x->x_obj, glist) + x->x_height, onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_height + 2, x, i, x, x->all_tag); } } static void erase_inlets(t_textwidget *x) { DEBUG(post("erase_inlets");); /* Added tag for all inlets/outlets of one instance */ sys_vgui("%s delete %xi\n", x->canvas_id, x); sys_vgui("%s delete %xo\n", x->canvas_id, x); } static void draw_scrollbar(t_textwidget *x) { sys_vgui("pack %s -side right -fill y -before %s \n", x->scrollbar_id, x->text_id); x->x_have_scrollbar = 1; } static void erase_scrollbar(t_textwidget *x) { sys_vgui("pack forget %s \n", x->scrollbar_id); x->x_have_scrollbar = 0; } static void bind_standard_keys(t_textwidget *x) { #ifdef __APPLE__ sys_vgui("bind %s {pdtk_canvas_ctrlkey %s %%K 0}\n", x->text_id, x->canvas_id); sys_vgui("bind %s {pdtk_canvas_ctrlkey %s %%K 1}\n", x->text_id, x->canvas_id); #else sys_vgui("bind %s {pdtk_canvas_ctrlkey %s %%K 0}\n", x->text_id, x->canvas_id); sys_vgui("bind %s {pdtk_canvas_ctrlkey %s %%K 1}\n", x->text_id, x->canvas_id); #endif } static void bind_button_events(t_textwidget *x) { /* mouse buttons */ sys_vgui("bind %s