/* text entry widget for PD * * Based on button from GGEE by Guenter Geiger * * Copyright Ben Bogart 2004 ben@ekran.org * * This program is distributed under the terms of the GNU General Public * * License * * entry 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. * * entry 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. */ #include #include #include #include #include /* TODO: get Ctrl-A working to select all */ /* TODO: set message doesnt work with a loadbang */ #ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif #ifndef IOWIDTH #define IOWIDTH 4 #endif #define DEFAULT_COLOR "grey70" #define TKW_HANDLE_HEIGHT 15 #define TKW_HANDLE_WIDTH 15 #define TKW_HANDLE_INSET -2 #define ENTRY_DEFAULT_WIDTH 130 #define ENTRY_DEFAULT_HEIGHT 130 #define ENTRY_MIN_WIDTH 66 #define ENTRY_MIN_HEIGHT 34 #define TOTAL_INLETS 1 #define TOTAL_OUTLETS 2 #define DEBUG(x) typedef struct _entry { 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_bgcolour; t_symbol *x_fgcolour; 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_entry; static t_class *entry_class; 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 entry_getrect(t_gobj *z, t_glist *owner, int *xp1, int *yp1, int *xp2, int *yp2); static void entry_displace(t_gobj *z, t_glist *glist, int dx, int dy); static void entry_select(t_gobj *z, t_glist *glist, int state); static void entry_activate(t_gobj *z, t_glist *glist, int state); static void entry_delete(t_gobj *z, t_glist *glist); static void entry_vis(t_gobj *z, t_glist *glist, int vis); //static int entry_click(t_gobj *z, t_glist *glist, int xpix, int ypix, int shift, int alt, int dbl, int doit); static void entry_save(t_gobj *z, t_binbuf *b); static t_widgetbehavior entry_widgetbehavior = { w_getrectfn: entry_getrect, w_displacefn: entry_displace, w_selectfn: entry_select, w_activatefn: entry_activate, w_deletefn: entry_delete, w_visfn: entry_vis, w_clickfn: NULL, }; /* widget helper functions */ static void set_tk_widget_ids(t_entry *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_entry *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 draw_inlets(t_entry *x, t_glist *glist, int firsttime, int total_inlets, int total_outlets) { DEBUG(post("draw_inlets in: %d out: %d", total_inlets, total_outlets);); int i, onset; /* inlets */ for (i = 0; i < total_inlets; i++) { onset = calculate_onset(x, glist, i, total_inlets); if (firsttime) { 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); if (firsttime) { 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); } } DEBUG(post("draw inlet end");); } static void erase_inlets(t_entry *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_entry *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_entry *x) { sys_vgui("pack forget %s \n", x->scrollbar_id); x->x_have_scrollbar = 0; } static void bind_standard_keys(t_entry *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_entry *x) { /* mouse buttons */ sys_vgui("bind %s