123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- /* Widgets for the Midnight Commander, Tk interface code
- Copyright (C) 1994, 1995, 1996 Miguel de Icaza
- Copyright (C) 1995 Jakub Jelinek
- Copyright (C) 1994 Radek Doulik
- 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.
- TODO: Destroy all the command names that are created for each
- widget during runtime.
- */
- #include <config.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "tkmain.h"
- #include "tkwidget.h"
- #include "dlg.h"
- static char
- widget_number (Widget *w)
- {
- Dlg_head *h = w->parent;
- const int count = h->count;
- Widget_Item *item;
- int i;
- item = h->first;
- for (i = 0; i < count; i++){
- if (item->widget == w)
- return i;
- item = item->next;
- }
- /* Actually, if we get this far, this message should not appear */
- fprintf (stderr, "Inconsistent widget\n");
- exit (1);
- }
- /* Returns a new command prefixed with an x:
- x.query.$the_frame.b0
- for the command of the query dialog box button 0
- This allow us to control the widget with the command:
- .query.$the_frame.b0
-
- and to access the C code callback with the:
- x.query.$the_frame.b0
- command.
- */
- char *
- tk_new_command (widget_data parent, void *widget,
- tcl_callback callback, char id)
- {
- char buffer [60];
- Widget *w = (Widget *) widget;
- Dlg_head *h = w->parent;
- char *cmd;
- /* wdata holds the frame information, it will be replaced with the
- * the widget command name
- */
- if (h->grided && w->tkname)
- sprintf (buffer, ".widgets.%s", w->tkname);
- else {
- char *format;
-
- if (((char *) parent) [1] == 0)
- format = "%s%c%d";
- else
- format = ".%s%c%d";
-
- sprintf (buffer, format, w->frame, id, widget_number (w));
- }
- cmd = copy_strings ("x", (char *)parent, buffer, 0);
- w->wdata = (widget_data) cmd;
- if (callback)
- Tcl_CreateCommand (interp, cmd, callback, w, NULL);
- return cmd;
- }
- /* Button routines */
- static int
- is_default_button (WButton *b)
- {
- return b->action == B_ENTER;
- }
- /* Called from the Tcl/Tk program when a button has been pressed */
- static int
- tk_button_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WButton *b = (WButton *) cd;
- Dlg_head *h = (Dlg_head *) b->widget.parent;
- int stop = 0;
- char *cmd = wtcl_cmd (b->widget);
-
- if (b->callback)
- stop = (*b->callback)(b->action, b->callback_data);
- if (!b->callback || stop){
- h->running = 0;
- h->ret_value = b->action;
- }
- return TCL_OK;
- }
- void
- x_button_set (WButton *b, char *text)
- {
- char *cmd = wtcl_cmd (b->widget);
- char *postfix = is_default_button (b) ? ".button" : "";
-
- tk_evalf ("%s%s configure -text {%s}", cmd+1, postfix, text);
- }
- /* Creates the button $parent.$newname and executes $newname command */
- int
- x_create_button (Dlg_head *h, widget_data parent, WButton *b)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, b, tk_button_callback, 'b');
- tk_evalf ("newbutton %s %s {%s} %d", cmd+1, cmd, b->text, is_default_button (b));
- return 1;
- }
- /* Radio button routines */
- static int
- tk_radio_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WRadio *r = (WRadio *) cd;
- if (STREQ (argv [1], "select")){
- r->pos = r->sel = atoi (argv [2]);
- }
- (r->widget.callback)(r->widget.parent, r, WIDGET_KEY, ' ');
- return TCL_OK;
- }
- void
- x_radio_focus_item (WRadio *r)
- {
- tk_evalf ("focus %s.%d", (char *)(r->widget.wdata)+1, r->pos);
- }
- int
- x_create_radio (Dlg_head *h, widget_data parent, WRadio *r)
- {
- int i;
- char *cmd;
- cmd = tk_new_command (parent, r, tk_radio_callback, 'r');
- tk_evalf ("newradio %s", cmd+1);
-
- for (i = 0; i < r->count; i++){
- tk_evalf ("radio_item %d {%s} %s %d", i, r->texts [i], cmd,
- r->sel == i);
- }
- return 1;
- }
- /* Checkbuttons routines */
- static int
- tk_check_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WCheck *c = (WCheck *) cd;
- Dlg_head *h = c->widget.parent;
- (*c->widget.callback)(h, c, WIDGET_KEY, ' ');
- return TCL_OK;
- }
- int
- x_create_check (Dlg_head *h, widget_data parent, WCheck *c)
- {
- char *cmd;
- cmd = tk_new_command (parent, c, tk_check_callback, 'c');
- tk_evalf ("newcheck %s %s {%s} %d", cmd+1, cmd, c->text, c->state);
- return 1;
- }
- /* Input line */
- int input_event (Gpm_Event *event, WInput *b);
- /* This callback command accepts the following commands:
- **
- ** $win mouse x-position
- ** $win setmark x-position
- */
- static int
- tk_input_callback (ClientData cd, Tcl_Interp *interp, int argc, char *av [])
- {
- Gpm_Event e;
- WInput *in = (WInput *) cd;
-
- if (strcmp (av [1], "mouse") == 0){
- e.x = atoi (av [2]) + 1;
- e.y = 0;
- e.type = GPM_DOWN;
- input_event (&e, (WInput *) cd);
- return TCL_OK;
- } else if (strcmp (av [1], "setmark") == 0){
- in->mark = in->point;
- return TCL_OK;
- }
-
- return TCL_OK;
- }
- void
- x_update_input (WInput *in)
- {
- char *name = wtcl_cmd (in->widget);
- int p;
-
- if (!name)
- return;
- name++;
- if (in->is_password){
- tk_evalf ("%s delete 0 end", name);
- tk_evalf ("%s insert end {*secret*}", name);
- p = 9;
- } else {
- tk_evalf ("entry_save_sel %s", name);
- if (in->inserted_one && isascii (in->inserted_one) && in->inserted_one > ' '){
- tk_evalf ("%s insert insert {%c}", name, in->inserted_one);
- in->inserted_one = 0;
- } else {
- tk_evalf ("%s delete 0 end", name);
- tk_evalf ("%s insert end {%s}", name, in->buffer);
- }
- p = in->point;
- }
- tk_evalf ("%s icursor %d; entry_restore_sel %s", name, p, name);
- }
- int
- x_create_input (Dlg_head *h, widget_data parent, WInput *in)
- {
- char *cmd;
- cmd = tk_new_command (parent, in, tk_input_callback, 'i');
- tk_evalf ("newinput %s {%s}", cmd+1, in->buffer ? in->buffer: "");
- return 1;
- }
- void
- x_listbox_select_nth (WListbox *l, int nth)
- {
- if (!wtcl_cmd (l->widget))
- return;
-
- tk_evalf ("listbox_sel %s %d", wtk_win (l->widget), nth);
- }
- void
- x_listbox_delete_nth (WListbox *l, int nth)
- {
- tk_evalf ("%s delete %d", wtk_win (l->widget), nth);
- }
- int
- x_create_listbox (Dlg_head *h, widget_data parent, WListbox *l)
- {
- char *cmd;
- int i;
- WLEntry *e;
-
- cmd = tk_new_command (parent, l, 0, 'x');
- tk_evalf ("listbox %s -width %d -selectmode single", cmd+1, l->widget.cols);
- /* As Jakub said on his very fine xvwidget.c: the user could add some
- * entries to the listbox before the tk-listbox was created, so we have
- * to add it manually :-)
- */
- i = 0;
- if ((e = l->list) == NULL)
- return 1;
- do {
- tk_evalf ("%s insert %d {%s}", cmd+1, i, e->text);
- if (e == l->current)
- x_listbox_select_nth (l, i);
- e = e->next;
- i++;
- } while (e != l->list);
- return 1;
- }
- /*
- * 30.10.96 bor: x_list_insert added in reverse order as x_create_listbox
- */
- void
- x_list_insert (WListbox *l, WLEntry *p, WLEntry *e)
- {
- int i;
- char *t = e->text;
- if (wtcl_cmd (l->widget) == NULL)
- return;
- for (i = 0; p != NULL && p != e; p = p->next, i++)
- ;
- tk_evalf ("%s insert %d {%s}", wtk_win (l->widget), i, t);
- }
- int
- x_create_label (Dlg_head *g, widget_data parent, WLabel *l)
- {
- char *cmd;
- cmd = tk_new_command (parent, l, 0, 'l');
- tk_evalf ("label %s -text {%s}", cmd+1, l->text);
- return 1;
- }
- void
- x_label_set_text (WLabel *label, char *text)
- {
- char *lname;
- if (!wtcl_cmd (label->widget))
- return;
-
- tk_evalf ("%s configure -text {%s}", wtk_win (label->widget),
- text ? text : "");
- }
- static int
- tk_buttonbar_callback (ClientData cd, Tcl_Interp *in, int ac, char *av [])
- {
- WButtonBar *bb = (WButtonBar *) cd;
- Dlg_head *h = (Dlg_head *) bb->widget.parent;
- int which = atoi (av [1]);
- (*bb->labels [which].function)(bb->labels [which].data);
- return TCL_OK;
- }
- int
- x_create_buttonbar (Dlg_head *h, widget_data parent, WButtonBar *bb)
- {
- char *cmd;
- int i;
-
- cmd = tk_new_command (parent, bb, tk_buttonbar_callback, 'n');
- tk_evalf ("frame %s", cmd+1);
- for (i = 0; i < 10; i++){
- tk_evalf ("newbutton %s.%d {%s %d} {%d %s} 0", cmd+1, i, cmd, i, i+1,
- bb->labels [i].text ? bb->labels [i].text : "");
- tk_evalf ("%s.%d configure -padx 1", cmd+1, i);
- tk_evalf ("pack %s.%d -side left -fill x -expand 1 -ipady 0",
- cmd+1, i);
- }
- return 1;
- }
- void
- x_redefine_label (WButtonBar *bb, int idx)
- {
- if (!bb->widget.wdata)
- return;
- if (!*(char *) bb->widget.wdata)
- return;
-
- if (!bb->labels [idx-1].text)
- return;
- tk_evalf ("%s.%d configure -text {%d %s}",
- wtk_win (bb->widget), idx-1, idx, bb->labels [idx-1].text);
- }
- /* destructor for the Tk widgets */
- void
- x_destroy_cmd (void *w)
- {
- Widget *widget = (Widget *)w;
-
- if (widget->wdata){
- Tcl_DeleteCommand (interp, wtcl_cmd (*widget));
- tk_evalf ("destroy %s", wtk_win (*widget));
- free (wtcl_cmd (*widget));
- }
- }
- int
- x_find_buttonbar_check (WButtonBar *bb, Widget *paneletc)
- {
- return (strcmp ((char *) bb->widget.wcontainer,
- (char *)paneletc->wcontainer));
- }
- /* The only parameter accepted is the size of the widget width */
- static int
- tk_gauge_callback (ClientData cd, Tcl_Interp *in, int ac, char *av [])
- {
- WGauge *g = (WGauge *) cd;
- g->pixels = atoi (av [1]);
- return TCL_OK;
- }
- int
- x_create_gauge (Dlg_head *h, widget_data parent, WGauge *g)
- {
- char *cmd;
- cmd = tk_new_command (parent, g, tk_gauge_callback, 'g');
- tk_evalf ("newgauge %s", cmd+1);
- return 1;
- }
- static void
- x_gauge_display (WGauge *g)
- {
- tk_evalf ("%s coords gauge 0 0 %d 90", wtk_win (g->widget),
- (int) (g->current*g->pixels)/g->max);
- }
- void
- x_gauge_show (WGauge *g)
- {
- tk_evalf ("gauge_%s %s", g->shown ? "shown":"hidden", wtk_win (g->widget));
- if (g->shown)
- x_gauge_display (g);
- }
- void
- x_gauge_set_value (WGauge *g, int max, int current)
- {
- if (g->shown)
- x_gauge_display (g);
- }
|