annotate lisp/wid-edit.el @ 2720:6fa9919a9a0b

[xemacs-hg @ 2005-04-08 23:10:01 by crestani] ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         New configure flag: `MC_ALLOC':         * configure.ac (XE_COMPLEX_ARG_ENABLE): Add `--enable-mc-alloc' as         a new configure flag.         * configure.in (AC_INIT_PARSE_ARGS): Add `--mc-alloc' as a new         configure flag.         * configure.usage: Add description for `mc-alloc'.         DUMP_IN_EXEC:         * Makefile.in.in: Condition the installation of a separate dump         file on !DUMP_ON_EXEC.         * configure.ac (XE_COMPLEX_ARG_ENABLE): Add         `--enable-dump-in-exec' as a new configure flag.         * configure.ac: DUMP_IN_EXEC is define as default for PDUMP but         not default for MC_ALLOC.         * configure.in (AC_INIT_PARSE_ARGS): Add `--dump-in-exec' as a         new configure flag.         * configure.in: DUMP_IN_EXEC is define as default for PDUMP but         not default for MC_ALLOC.         * configure.usage: Add description for `dump-in-exec'. lib-src/ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         DUMP_IN_EXEC:                  * Makefile.in.in: Only compile insert-data-in-exec if         DUMP_IN_EXEC is defined. lisp/ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         MEMORY_USAGE_STATS         * diagnose.el: Add new lisp function to pretty print statistics         about the new allocator.         * diagnose.el (show-mc-alloc-memory-usage): New. modules/ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         Remove Lcrecords:                  * postgresql/postgresql.c (allocate_pgconn): Allocate with new         allocator.         * postgresql/postgresql.c (allocate_pgresult): Allocate PGresult         with new allocator.           * postgresql/postgresql.h (struct Lisp_PGconn): Add         lrecord_header.         * postgresql/postgresql.h (struct Lisp_PGresult): Add         lrecord_header.         * ldap/eldap.c (allocate_ldap): Allocate with new allocator.         * ldap/eldap.h (struct Lisp_LDAP): Add lrecord_header. nt/ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         New configure flag: `MC_ALLOC':         * config.inc.samp: Add new flag `MC_ALLOC'.         * xemacs.mak: Add flag and configuration output for `MC_ALLOC'.         New files:         * xemacs.dsp: Add source files mc-alloc.c and mc-alloc.h.         * xemacs.mak: Add new object file mc-alloc.obj to dependencies. src/ChangeLog addition: 2005-04-01  Marcus Crestani  <crestani@xemacs.org>         The new allocator.         New configure flag: `MC_ALLOC':         * config.h.in: Add new flag `MC_ALLOC'.         New files:         * Makefile.in.in: Add new object file mc-alloc.o.         * depend: Add new files to dependencies.         * mc-alloc.c: New.         * mc-alloc.h: New.         Running the new allocator from XEmacs:         * alloc.c (deadbeef_memory): Moved to mc-alloc.c.         * emacs.c (main_1): Initialize the new allocator and add         syms_of_mc_alloc.         * symsinit.h: Add syms_of_mc_alloc.         New lrecord allocation and free functions:         * alloc.c (alloc_lrecord): New. Allocates an lrecord, includes         type checking and initializing of the lrecord_header.         * alloc.c (noseeum_alloc_lrecord): Same as above, but increments         the NOSEEUM cons counter.         * alloc.c (free_lrecord): New. Calls the finalizer and frees the         lrecord.         * lrecord.h: Add lrecord allocation prototypes and comments.         Remove old lrecord FROB block allocation:                  * alloc.c (allocate_lisp_storage): Former function to expand         heap. Not needed anymore, remove.         * alloc.c: Completely remove `Fixed-size type macros'         * alloc.c (release_breathing_space): Remove.         * alloc.c (memory_full): Remove release_breathing_space.         * alloc.c (refill_memory_reserve): Remove.         * alloc.c (TYPE_ALLOC_SIZE): Remove.         * alloc.c (DECLARE_FIXED_TYPE_ALLOC): Remove.         * alloc.c (ALLOCATE_FIXED_TYPE_FROM_BLOCK): Remove.         * alloc.c (ALLOCATE_FIXED_TYPE_1): Remove.         * alloc.c (ALLOCATE_FIXED_TYPE): Remove.         * alloc.c (NOSEEUM_ALLOCATE_FIXED_TYPE): Remove.         * alloc.c (struct Lisp_Free): Remove.         * alloc.c (LRECORD_FREE_P): Remove.         * alloc.c (MARK_LRECORD_AS_FREE): Remove.         * alloc.c (MARK_LRECORD_AS_NOT_FREE): Remove.         * alloc.c (PUT_FIXED_TYPE_ON_FREE_LIST): Remove.         * alloc.c (FREE_FIXED_TYPE): Remove.         * alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC): Remove.         Allocate old lrecords with new allocator:                  * alloc.c: DECLARE_FIXED_TYPE_ALLOC removed for all lrecords         defined in alloc.c.         * alloc.c (Fcons): Allocate with new allocator.         * alloc.c (noseeum_cons): Allocate with new allocator.         * alloc.c (make_float): Allocate with new allocator.         * alloc.c (make_bignum): Allocate with new allocator.         * alloc.c (make_bignum_bg): Allocate with new allocator.         * alloc.c (make_ratio): Allocate with new allocator.         * alloc.c (make_ratio_bg): Allocate with new allocator.         * alloc.c (make_ratio_rt): Allocate with new allocator.         * alloc.c (make_bigfloat): Allocate with new allocator.         * alloc.c (make_bigfloat_bf): Allocate with new allocator.         * alloc.c (make_compiled_function): Allocate with new allocator.         * alloc.c (Fmake_symbol): Allocate with new allocator.         * alloc.c (allocate_extent): Allocate with new allocator.         * alloc.c (allocate_event): Allocate with new allocator.         * alloc.c (make_key_data): Allocate with new allocator.         * alloc.c (make_button_data): Allocate with new allocator.         * alloc.c (make_motion_data): Allocate with new allocator.         * alloc.c (make_process_data): Allocate with new allocator.         * alloc.c (make_timeout_data): Allocate with new allocator.         * alloc.c (make_magic_data): Allocate with new allocator.         * alloc.c (make_magic_eval_data): Allocate with new allocator.         * alloc.c (make_eval_data): Allocate with new allocator.         * alloc.c (make_misc_user_data): Allocate with new allocator.         * alloc.c (Fmake_marker): Allocate with new allocator.         * alloc.c (noseeum_make_marker): Allocate with new allocator.         * alloc.c (make_uninit_string): Allocate with new allocator.         * alloc.c (resize_string): Allocate with new allocator.         * alloc.c (make_string_nocopy): Allocate with new allocator.         Garbage Collection:         * alloc.c (GC_CHECK_NOT_FREE): Remove obsolete assertions.         * alloc.c (SWEEP_FIXED_TYPE_BLOCK): Remove.         * alloc.c (SWEEP_FIXED_TYPE_BLOCK_1): Remove.         * alloc.c (sweep_conses): Remove.         * alloc.c (free_cons): Use new allocator to free.         * alloc.c (sweep_compiled_functions): Remove.         * alloc.c (sweep_floats): Remove.         * alloc.c (sweep_bignums): Remove.         * alloc.c (sweep_ratios): Remove.         * alloc.c (sweep_bigfloats): Remove.         * alloc.c (sweep_symbols): Remove.         * alloc.c (sweep_extents): Remove.         * alloc.c (sweep_events): Remove.         * alloc.c (sweep_key_data): Remove.         * alloc.c (free_key_data): Use new allocator to free.         * alloc.c (sweep_button_data): Remove.         * alloc.c (free_button_data): Use new allocator to free.         * alloc.c (sweep_motion_data): Remove.         * alloc.c (free_motion_data): Use new allocator to free.         * alloc.c (sweep_process_data): Remove.         * alloc.c (free_process_data): Use new allocator to free.         * alloc.c (sweep_timeout_data): Remove.         * alloc.c (free_timeout_data): Use new allocator to free.         * alloc.c (sweep_magic_data): Remove.         * alloc.c (free_magic_data): Use new allocator to free.         * alloc.c (sweep_magic_eval_data): Remove.         * alloc.c (free_magic_eval_data): Use new allocator to free.         * alloc.c (sweep_eval_data): Remove.         * alloc.c (free_eval_data): Use new allocator to free.         * alloc.c (sweep_misc_user_data): Remove.         * alloc.c (free_misc_user_data): Use new allocator to free.         * alloc.c (sweep_markers): Remove.         * alloc.c (free_marker): Use new allocator to free.         * alloc.c (garbage_collect_1): Remove release_breathing_space.         * alloc.c (gc_sweep): Remove all the old lcrecord and lrecord         related stuff. Sweeping now works like this: compact string         chars, finalize, sweep.         * alloc.c (common_init_alloc_early): Remove old lrecord         initializations, remove breathing_space.         * emacs.c (Fdump_emacs): Remove release_breathing_space.         * lisp.h: Remove prototype for release_breathing_space.         * lisp.h: Adjust the special cons mark makros.         Lrecord Finalizer:         * alloc.c: Add finalizer to lrecord definition.         * alloc.c (finalize_string): Add finalizer for string.         * bytecode.c: Add finalizer to lrecord definition.         * bytecode.c (finalize_compiled_function): Add finalizer for         compiled function.         * marker.c: Add finalizer to lrecord definition.         * marker.c (finalize_marker): Add finalizer for marker.         These changes build the interface to mc-alloc:         * lrecord.h (MC_ALLOC_CALL_FINALIZER): Tell mc-alloc how to         finalize lrecords.         * lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): Tell         mc-alloc how to finalize for disksave.         Unify lrecords and lcrecords:         * lisp.h (struct Lisp_String): Adjust string union hack to         new lrecord header.         * lrecord.h: Adjust comments.         * lrecord.h (struct lrecord_header): The new lrecord header         includes type, lisp-readonly, free, and uid.         * lrecord.h (set_lheader_implementation): Adjust to new         lrecord_header.         * lrecord.h (struct lrecord_implementation): The field basic_p         for indication of an old lrecord is not needed anymore, remove.         * lrecord.h (MAKE_LRECORD_IMPLEMENTATION): Remove basic_p.         * lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION): Remove         basic_p.         * lrecord.h (copy_sized_lrecord): Remove distinction between         old lrecords and lcrecords.         * lrecord.h (copy_lrecord): Remove distinction between old         lrecords and lcrecords.         * lrecord.h (zero_sized_lrecord): Remove distinction between         old lrecords and lcrecords.         * lrecord.h (zero_lrecord): Remove distinction between old         lrecords and lcrecords.         Remove lcrecords and lcrecord lists:         * alloc.c (basic_alloc_lcrecord): Not needed anymore, remove.         * alloc.c (very_old_free_lcrecord): Not needed anymore, remove.         * alloc.c (copy_lisp_object): No more distinction between         lrecords and lcrecords.         * alloc.c (all_lcrecords): Not needed anymore, remove.         * alloc.c (make_vector_internal): Allocate as lrecord.         * alloc.c (make_bit_vector_internal): Allocate as lrecord.         * alloc.c: Completely remove `lcrecord lists'.         * alloc.c (free_description): Remove.         * alloc.c (lcrecord_list_description): Remove.         * alloc.c (mark_lcrecord_list): Remove.         * alloc.c (make_lcrecord_list): Remove.         * alloc.c (alloc_managed_lcrecord): Remove.         * alloc.c (free_managed_lcrecord): Remove.         * alloc.c (alloc_automanaged_lcrecord): Remove.         * alloc.c (free_lcrecord): Remove.         * alloc.c (lcrecord_stats): Remove.         * alloc.c (tick_lcrecord_stats): Remove.         * alloc.c (disksave_object_finalization_1): Add call to         mc_finalize_for_disksave. Remove the lcrecord way to visit all         objects.         * alloc.c (kkcc_marking): Remove XD_FLAG_FREE_LISP_OBJECT         * alloc.c (sweep_lcrecords_1): Remove.         * alloc.c (common_init_alloc_early): Remove everything related         to lcrecords, remove old lrecord initializations,         * alloc.c (init_lcrecord_lists): Not needed anymore, remove.         * alloc.c (reinit_alloc_early): Remove everything related to         lcrecords.         * alloc.c (init_alloc_once_early): Remove everything related to         lcrecords.         * buffer.c (allocate_buffer): Allocate as lrecord.         * buffer.c (nuke_all_buffer_slots): Use lrecord functions.         * buffer.c (common_init_complex_vars_of_buffer): Allocate as         lrecord.         * buffer.h (struct buffer): Add lrecord_header.         * casetab.c (allocate_case_table): Allocate as lrecord.         * casetab.h (struct Lisp_Case_Table): Add lrecord_header.         * charset.h (struct Lisp_Charset): Add lrecord_header.         * chartab.c (fill_char_table): Use lrecord functions.         * chartab.c (Fmake_char_table): Allocate as lrecord.         * chartab.c (make_char_table_entry): Allocate as lrecord.         * chartab.c (copy_char_table_entry): Allocate as lrecord.         * chartab.c (Fcopy_char_table): Allocate as lrecord.         * chartab.c (put_char_table): Use lrecord functions.         * chartab.h (struct Lisp_Char_Table_Entry): Add lrecord_header.         * chartab.h (struct Lisp_Char_Table): Add lrecord_header.         * console-impl.h (struct console): Add lrecord_header.         * console-msw-impl.h (struct Lisp_Devmode): Add lrecord_header.         * console-msw-impl.h (struct mswindows_dialog_id): Add         lrecord_header.         * console.c (allocate_console): Allocate as lrecord.         * console.c (nuke_all_console_slots): Use lrecord functions.         * console.c (common_init_complex_vars_of_console): Allocate as         lrecord.         * data.c (make_weak_list): Allocate as lrecord.         * data.c (make_weak_box): Allocate as lrecord.         * data.c (make_ephemeron): Allocate as lrecord.         * database.c (struct Lisp_Database): Add lrecord_header.         * database.c (allocate_database): Allocate as lrecord.         * device-impl.h (struct device): Add lrecord_header.         * device-msw.c (allocate_devmode): Allocate as lrecord.         * device.c (nuke_all_device_slots): Use lrecord functions.         * device.c (allocate_device): Allocate as lrecord.         * dialog-msw.c (handle_question_dialog_box): Allocate as lrecord.         * elhash.c (struct Lisp_Hash_Table): Add lrecord_header.         * elhash.c (make_general_lisp_hash_table): Allocate as lrecord.         * elhash.c (Fcopy_hash_table): Allocate as lrecord.         * event-stream.c: Lcrecord lists Vcommand_builder_free_list and         Vtimeout_free_list are no longer needed. Remove.         * event-stream.c (allocate_command_builder): Allocate as lrecord.         * event-stream.c (free_command_builder): Use lrecord functions.         * event-stream.c (event_stream_generate_wakeup): Allocate as         lrecord.         * event-stream.c (event_stream_resignal_wakeup): Use lrecord         functions.         * event-stream.c (event_stream_disable_wakeup): Use lrecord         functions.         * event-stream.c (reinit_vars_of_event_stream): Lcrecord lists         remove.         * events.h (struct Lisp_Timeout): Add lrecord_header.         * events.h (struct command_builder): Add lrecord_header.         * extents-impl.h (struct extent_auxiliary): Add lrecord_header.         * extents-impl.h (struct extent_info): Add lrecord_header.         * extents.c (allocate_extent_auxiliary): Allocate as lrecord.         * extents.c (allocate_extent_info): Allocate as lrecord.         * extents.c (copy_extent): Allocate as lrecord.         * faces.c (allocate_face): Allocate as lrecord.         * faces.h (struct Lisp_Face): Add lrecord_header.         * file-coding.c (allocate_coding_system): Allocate as lrecord.         * file-coding.c (Fcopy_coding_system): Allocate as lrecord.         * file-coding.h (struct Lisp_Coding_System): Add lrecord_header.         * fns.c (Ffillarray): Allocate as lrecord.         * frame-impl.h (struct frame): Add lrecord_header.         * frame.c (nuke_all_frame_slots): Use lrecord functions.         * frame.c (allocate_frame_core): Allocate as lrecord.         * glyphs.c (allocate_image_instance): Allocate as lrecord.         * glyphs.c (Fcolorize_image_instance): Allocate as lrecord.         * glyphs.c (allocate_glyph): Allocate as lrecord.         * glyphs.h (struct Lisp_Image_Instance): Add lrecord_header.         * glyphs.h (struct Lisp_Glyph): Add lrecord_header.         * gui.c (allocate_gui_item): Allocate as lrecord.         * gui.h (struct Lisp_Gui_Item): Add lrecord_header.         * keymap.c (struct Lisp_Keymap): Add lrecord_header.         * keymap.c (make_keymap): Allocate as lrecord.         * lisp.h (struct Lisp_Vector): Add lrecord_header.         * lisp.h (struct Lisp_Bit_Vector): Add lrecord_header.         * lisp.h (struct weak_box): Add lrecord_header.         * lisp.h (struct ephemeron): Add lrecord_header.         * lisp.h (struct weak_list): Add lrecord_header.         * lrecord.h (struct lcrecord_header): Not used, remove.         * lrecord.h (struct free_lcrecord_header): Not used, remove.         * lrecord.h (struct lcrecord_list): Not needed anymore, remove.         * lrecord.h (lcrecord_list): Not needed anymore, remove.         * lrecord.h: (enum data_description_entry_flags): Remove         XD_FLAG_FREE_LISP_OBJECT.         * lstream.c: Lrecord list Vlstream_free_list remove.         * lstream.c (Lstream_new): Allocate as lrecord.         * lstream.c (Lstream_delete): Use lrecod functions.         * lstream.c (reinit_vars_of_lstream): Vlstream_free_list         initialization remove.           * lstream.h (struct lstream): Add lrecord_header.         * emacs.c (main_1): Remove lstream initialization.         * mule-charset.c (make_charset): Allocate as lrecord.         * objects-impl.h (struct Lisp_Color_Instance): Add         lrecord_header.         * objects-impl.h (struct Lisp_Font_Instance): Add lrecord_header.         * objects.c (Fmake_color_instance): Allocate as lrecord.         * objects.c (Fmake_font_instance): Allocate as lrecord.         * objects.c (reinit_vars_of_objects): Allocate as lrecord.         * opaque.c: Lcreord list Vopaque_ptr_list remove.         * opaque.c (make_opaque): Allocate as lrecord.         * opaque.c (make_opaque_ptr): Allocate as lrecord.         * opaque.c (free_opaque_ptr): Use lrecord functions.         * opaque.c (reinit_opaque_early):         * opaque.c (init_opaque_once_early): Vopaque_ptr_list         initialization remove.         * opaque.h (Lisp_Opaque): Add lrecord_header.         * opaque.h (Lisp_Opaque_Ptr): Add lrecord_header.         * emacs.c (main_1): Remove opaque variable initialization.         * print.c (default_object_printer): Use new lrecord_header.         * print.c (print_internal): Use new lrecord_header.         * print.c (debug_p4): Use new lrecord_header.         * process.c (make_process_internal): Allocate as lrecord.         * procimpl.h (struct Lisp_Process): Add lrecord_header.         * rangetab.c (Fmake_range_table): Allocate as lrecord.         * rangetab.c (Fcopy_range_table): Allocate as lrecord.         * rangetab.h (struct Lisp_Range_Table): Add lrecord_header.         * scrollbar.c (create_scrollbar_instance): Allocate as lrecord.         * scrollbar.h (struct scrollbar_instance): Add lrecord_header.         * specifier.c (make_specifier_internal): Allocate as lrecord.         * specifier.h (struct Lisp_Specifier): Add lrecord_header.         * symbols.c:         * symbols.c (Fmake_variable_buffer_local): Allocate as lrecord.         * symbols.c (Fdontusethis_set_symbol_value_handler): Allocate         as lrecord.         * symbols.c (Fdefvaralias): Allocate as lrecord.         * symeval.h (struct symbol_value_magic): Add lrecord_header.         * toolbar.c (update_toolbar_button): Allocate as lrecord.         * toolbar.h (struct toolbar_button): Add lrecord_header.         * tooltalk.c (struct Lisp_Tooltalk_Message): Add lrecord_header.         * tooltalk.c (make_tooltalk_message): Allocate as lrecord.         * tooltalk.c (struct Lisp_Tooltalk_Pattern): Add lrecord_header.         * tooltalk.c (make_tooltalk_pattern): Allocate as lrecord.         * ui-gtk.c (allocate_ffi_data): Allocate as lrecord.         * ui-gtk.c (allocate_emacs_gtk_object_data): Allocate as lrecord.         * ui-gtk.c (allocate_emacs_gtk_boxed_data): Allocate as lrecord.         * ui-gtk.h (structs): Add lrecord_header.         * window-impl.h (struct window): Add lrecord_header.         * window-impl.h (struct window_mirror): Add lrecord_header.         * window.c (allocate_window): Allocate as lrecord.         * window.c (new_window_mirror): Allocate as lrecord.         * window.c (make_dummy_parent): Allocate as lrecord.         MEMORY_USAGE_STATS         * alloc.c (fixed_type_block_overhead): Not used anymore, remove.         * buffer.c (compute_buffer_usage): Get storage size from new         allocator.         * marker.c (compute_buffer_marker_usage): Get storage size from         new allocator.         * mule-charset.c (compute_charset_usage): Get storage size from         new allocator.         * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): Get         storage size from new allocator.         * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage):         Get storage size from new allocator.         * scrollbar-x.c (x_compute_scrollbar_instance_usage): Get         storage size from new allocator.         * scrollbar.c (compute_scrollbar_instance_usage): Get storage         size from new allocator.         * unicode.c (compute_from_unicode_table_size_1): Get storage         size from new allocator.         * unicode.c (compute_to_unicode_table_size_1): Get storage size         from new allocator.         * window.c (compute_window_mirror_usage): Get storage size from         new allocator.         * window.c (compute_window_usage): Get storage size from new         allocator.         MC_ALLOC_TYPE_STATS:         * alloc.c (alloc_lrecord): Bump lrecord count.         * alloc.c (noseeum_alloc_lrecord): Bump lrecord count.         * alloc.c (struct lrecord_stats): Storage for counts.         * alloc.c (init_lrecord_stats): Zero statistics.         * alloc.c (inc_lrecord_stats): Increase the statistic.         * alloc.c (dec_lrecord_stats): Decrease the statistic.         * alloc.c (gc_plist_hack): Used to print the information.         * alloc.c (Fgarbage_collect): Return the collected information.         * mc-alloc.c (remove_cell): Decrease lrecord count.         * mc-alloc.h: Set flag MC_ALLOC_TYPE_STATS.         * emacs.c (main_1): Init lrecord statistics.         * lrecord.h: Add prototypes for *_lrecord_stats.         Strings:         * alloc.c (Fmake_string): Initialize ascii_begin to zero.         * alloc.c (gc_count_num_short_string_in_use): Remove.         * alloc.c (gc_count_string_total_size): Remove.         * alloc.c (gc_count_short_string_total_size): Remove.         * alloc.c (debug_string_purity): Remove.         * alloc.c (debug_string_purity_print): Remove.         * alloc.c (sweep_strings): Remove.                  Remove static C-readonly Lisp objects:         * alloc.c (c_readonly): Not needed anymore, remove.         * alloc.c (GC_CHECK_LHEADER_INVARIANTS): Remove some obsolete         lheader invariants assertions.         * buffer.c (DEFVAR_BUFFER_LOCAL_1): Allocate dynamically.         * console.c (DEFVAR_CONSOLE_LOCAL_1): Allocate dynamically.         * gpmevent.c: Indirection via MC_ALLOC_Freceive_gpm_event.         * gpmevent.c (Fgpm_enable): Allocate dynamically.         * gpmevent.c (syms_of_gpmevent): Allocate dynamically.         * lisp.h (C_READONLY): Not needed anymore, remove.         * lisp.h (DEFUN): Allocate dynamically.         * lrecord.h (C_READONLY_RECORD_HEADER_P): Not needed anymore,         remove.         * lrecord.h (SET_C_READONLY_RECORD_HEADER): Not needed anymore,         remove.         * symbols.c (guts_of_unbound_marker):         * symeval.h (defsubr): Allocate dynamically.         * symeval.h (DEFSUBR_MACRO): Allocate dynamically.         * symeval.h (DEFVAR_ SYMVAL_FWD): Allocate dynamically.         * tests.c (TESTS_DEFSUBR): Allocate dynamically.         Definition of mcpro:         * lisp.h: Add mcpro prototypes.         * alloc.c (common_init_alloc_early): Add initialization for         mcpros.         * alloc.c (mcpro_description_1): New.         * alloc.c (mcpro_description): New.         * alloc.c (mcpros_description_1): New.         * alloc.c (mcpros_description): New.         * alloc.c (mcpro_one_name_description_1): New.         * alloc.c (mcpro_one_name_description): New.         * alloc.c (mcpro_names_description_1): New.         * alloc.c (mcpro_names_description): New.         * alloc.c (mcpros): New.         * alloc.c (mcpro_names): New.         * alloc.c (mcpro_1): New.         * alloc.c (mc_pro): New.         * alloc.c (garbage_collect_1): Add mcpros to root set.         Usage of mcpro:         * alloc.c (make_string_nocopy): Add string to root set.         * symbols.c (init_symbols_once_early): Add Qunbound to root set.         Changes to the Portable Dumper:                  * alloc.c (FREE_OR_REALLOC_BEGIN): Since dumped objects can be         freed with the new allocator, remove assertion for !DUMPEDP.         * dumper.c: Adjust comments, increase PDUMP_HASHSIZE.         * dumper.c (pdump_make_hash): Shift address only 2 bytes, to         avoid collisions.         * dumper.c (pdump_objects_unmark): No more mark bits within         the object, remove.         * dumper.c (mc_addr_elt): New. Element data structure for mc         hash table.         * dumper.c (pdump_mc_hash): New hash table: `lookup table'.         * dumper.c (pdump_get_mc_addr): New. Lookup for hash table.         * dumper.c (pdump_get_indirect_mc_addr): New. Lookup for         convertibles.         * dumper.c (pdump_put_mc_addr): New. Putter for hash table.         * dumper.c (pdump_dump_mc_data): New. Writes the table for         relocation at load time to the dump file.         * dumper.c (pdump_scan_lisp_objects_by_alignment): New.         Visits all dumped Lisp objects.         * dumper.c (pdump_scan_non_lisp_objects_by_alignment): New.         Visits all other dumped objects.         * dumper.c (pdump_reloc_one_mc): New. Updates all pointers         of an object by using the hash table pdump_mc_hash.         * dumper.c (pdump_reloc_one): Replaced by pdump_reloc_one_mc.         * dumper.c (pdump): Change the structure of the dump file, add         the mc post dump relocation table to dump file.         * dumper.c (pdump_load_finish): Hand all dumped objects to the         new allocator and use the mc post dump relocation table for         relocating the dumped objects at dump file load time, free not         longer used data structures.         * dumper.c (pdump_load): Free the dump file.         * dumper.h: Remove pdump_objects_unmark.         * lrecord.h (DUMPEDP): Dumped objects can be freed, remove.              DUMP_IN_EXEC:         * Makefile.in.in: Linking for and with dump in executable only if         DUMP_IN_EXEC is defined.         * config.h.in: Add new flag `DUMP_IN_EXEC'         * emacs.c: Condition dump-data.h on DUMP_IN_EXEC.         * emacs.c (main_1): Flag `-si' only works if dump image is         written into executable.         Miscellanious         * lrecord.h (enum lrecord_type): Added numbers to all types,         very handy for debugging.         * xemacs.def.in.in: Add mc-alloc functions to make them visible         to the modules.
author crestani
date Fri, 08 Apr 2005 23:11:35 +0000
parents ecf1ebac70d8
children 681d0fbb904e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; wid-edit.el --- Functions for creating and using widgets.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 ;;
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3 ;; Copyright (C) 1996-1997, 1999-2002 Free Software Foundation, Inc.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Maintainer: Hrvoje Niksic <hniksic@xemacs.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Keywords: extensions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; Version: 1.9960-x
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; it under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; GNU General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 ;;
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
30 ;; See `widget.el' and the wishlist in `../man/widget.texi'.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 (require 'widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
37 ;; XEmacs: autoload of `finder-commentary' is redundant.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;;; Customization.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 (defgroup widgets nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 "Customization support for the Widget Library."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 :link '(custom-manual "(widget)Top")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 :link '(url-link :tag "Development Page"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 "http://www.dina.kvl.dk/~abraham/custom/")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 :link '(emacs-library-link :tag "Lisp File" "widget.el")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 :prefix "widget-"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 :group 'extensions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 :group 'hypermedia)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 (defgroup widget-documentation nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 "Options controlling the display of documentation strings."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 (defgroup widget-faces nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 "Faces used by the widget library."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 :group 'faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 (defvar widget-documentation-face 'widget-documentation-face
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
61 "Face used for documentation strings in widgets.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 This exists as a variable so it can be set locally in certain buffers.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 (defface widget-documentation-face '((((class color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 (background dark))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 (:foreground "lime green"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 (((class color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 (background light))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 (:foreground "dark green"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 (t nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 "Face used for documentation text."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 :group 'widget-documentation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (defvar widget-button-face 'widget-button-face
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
76 "Face used for buttons in widgets.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 This exists as a variable so it can be set locally in certain buffers.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 (defface widget-button-face '((t (:bold t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 "Face used for widget buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 (defcustom widget-mouse-face 'highlight
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 "Face used for widget buttons when the mouse is above them."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 :type 'face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
88 ;; #### comment from GNU Emacs 21.3.50, test the first spec.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
89 ;; TTY gets special definitions here and in the next defface, because
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
90 ;; the gray colors defined for other displays cause black text on a black
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
91 ;; background, at least on light-background TTYs.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
92 (defface widget-field-face '(
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
93 ;; #### sjt sez: XEmacs doesn't like this.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
94 ;; The Custom face editor widget shows a Lisp
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
95 ;; form, not a face structure. Does it produce
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
96 ;; the right face on TTYs?
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
97 ;; One hypothesis is that the editor doesn't
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
98 ;; grok non-default display types in the value.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
99 (((type tty))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
100 (:background "yellow3")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
101 (:foreground "black"))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
102 (((class grayscale color)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 (background light))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (:background "gray85"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 (((class grayscale color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (background dark))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 (:background "dim gray"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 (:italic t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 "Face used for editable fields."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ;; Currently unused
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 ;(defface widget-single-line-field-face '((((class grayscale color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ; (background light))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 ; (:background "gray85"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 ; (((class grayscale color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 ; (background dark))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 ; (:background "dim gray"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 ; (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 ; (:italic t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 ; "Face used for editable fields spanning only a single line."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 ; :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 ;(defvar widget-single-line-display-table
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 ; (let ((table (make-display-table)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 ; (aset table 9 "^I")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 ; (aset table 10 "^J")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 ; table)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 ; "Display table used for single-line editable fields.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 ;(set-face-display-table 'widget-single-line-field-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 ; widget-single-line-display-table)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 ;; Some functions from this file have been ported to C for speed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ;; Setting this to t (*before* loading wid-edit.el) will make them
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;; shadow the subrs. It should be used only for debugging purposes.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 (defvar widget-shadow-subrs nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 ;;; Utility functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 ;; These are not really widget specific.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 (when (or (not (fboundp 'widget-plist-member))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 widget-shadow-subrs)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 ;; Recoded in C, for efficiency. It used to be a defsubst, but old
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 ;; compiled code won't fail -- it will just be slower.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (defun widget-plist-member (plist prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 ;; Return non-nil if PLIST has the property PROP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; PLIST is a property list, which is a list of the form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 ;; (PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ;; Unlike `plist-get', this allows you to distinguish between a missing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; property and a property with the value nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 ;; The value is actually the tail of PLIST whose car is PROP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (while (and plist (not (eq (car plist) prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (setq plist (cddr plist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
161 (defsubst widget-princ-to-string (object)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
162 "Return string representation of OBJECT, any Lisp object.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
163
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
164 No quoting characters or string delimiters are used."
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
165 ;(with-current-buffer (get-buffer-create " *widget-tmp*")
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
166 ; (erase-buffer)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
167 ; (princ object (current-buffer))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
168 ; (buffer-string))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
169 (prin1-to-string object t)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
170 )
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 (defun widget-prettyprint-to-string (object)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
173 "Use `cl-prettyprint' to generate a string representation of OBJECT.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
174
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
175 Cleans up `cl-prettyprint''s gratuitous surrounding newlines."
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
176 (with-temp-buffer
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (cl-prettyprint object)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 ;; `cl-prettyprint' always surrounds the text with newlines.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
179 (buffer-string (if (eq (char-after (point-min)) ?\n)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
180 (1+ (point-min))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
181 (point-min))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
182 (if (eq (char-before (point-max)) ?\n)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
183 (1- (point-max))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
184 (point-max)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (defun widget-clear-undo ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 "Clear all undo information."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 (buffer-disable-undo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (buffer-enable-undo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
191 (defun widget-sublist (list start &optional end)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
192 "Return the sublist of LIST from START to END.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
193 If END is omitted, it defaults to the length of LIST."
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
194 (if (> start 0) (setq list (nthcdr start list)))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
195 (if end
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
196 (if (<= end start)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
197 nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
198 (setq list (copy-sequence list))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
199 (setcdr (nthcdr (- end start 1) list) nil)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
200 list)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
201 (copy-sequence list)))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
202
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
203 ;; Is unimplemented the right superclass?
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
204 (define-error 'missing-package "Package not installed" 'unimplemented)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
205
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (defcustom widget-menu-max-size 40
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 "Largest number of items allowed in a popup-menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 Larger menus are read through the minibuffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 :type 'integer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
212 (defcustom widget-menu-max-shortcuts 40
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
213 "Largest number of items for which it works to choose one with a character.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
214 For a larger number of items, the minibuffer is used.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
215 #### Not yet implemented in XEmacs."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
216 :group 'widgets
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
217 :type 'integer)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
218
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 (defcustom widget-menu-minibuffer-flag nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 "*Control how to ask for a choice from the keyboard.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 Non-nil means use the minibuffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 nil means read a single character."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 :type 'boolean)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 (defun widget-choose (title items &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 "Choose an item from a list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 First argument TITLE is the name of the list.
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
230 Second argument ITEMS is a list whose members are either
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 (NAME . VALUE), to indicate selectable items, or just strings to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 indicate unselectable items.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 Optional third argument EVENT is an input event.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
235 The user is asked to choose a NAME from the items alist, and the VALUE of
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
236 the chosen element will be returned. If EVENT is a mouse event, and the
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
237 number of elements in items is less than `widget-menu-max-size', a popup
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
238 menu will be used, otherwise the minibuffer is used."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (cond ((and (< (length items) widget-menu-max-size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 event
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (console-on-window-system-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 ;; Pressed by the mouse.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (let ((val (get-popup-menu-response
724
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
244 (let ((menu-thingee
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (cons title
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 (mapcar (lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (if (stringp x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 (vector x nil nil)
724
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
249 (vector (car x)
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
250 (list (car x)) ; 'eval 'quote
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
251 t)))
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
252 items))
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
253 ))
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
254 (message "%s" menu-thingee)
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
255 menu-thingee)
76d5a3dd827a [xemacs-hg @ 2002-01-05 07:33:11 by stephent]
stephent
parents: 652
diff changeset
256 )))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 (setq val (and val
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (listp (event-object val))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 (stringp (car-safe (event-object val)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 (car (event-object val))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 (cdr (assoc val items))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 ((and (not widget-menu-minibuffer-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ;; Can't handle more than 10 items (as many digits)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (<= (length items) 10))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 ;; Construct a menu of the choices
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 ;; and then use it for prompting for a single character.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 (let* ((overriding-terminal-local-map (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 (map (make-sparse-keymap title))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 (next-digit ?0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 some-choice-enabled value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 ;; Define SPC as a prefix char to get to this menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (define-key overriding-terminal-local-map " " map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 (with-current-buffer (get-buffer-create " widget-choose")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (erase-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 (insert "Available choices:\n\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (dolist (choice items)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 (when (consp choice)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (let* ((name (car choice))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 (function (cdr choice)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 (insert (format "%c = %s\n" next-digit name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 (define-key map (vector next-digit) function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 (setq some-choice-enabled t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 ;; Allocate digits to disabled alternatives
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 ;; so that the digit of a given alternative never varies.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 (incf next-digit))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (insert "\nC-g = Quit"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (or some-choice-enabled
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (error "None of the choices is currently meaningful"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (define-key map [?\C-g] 'keyboard-quit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (define-key map [t] 'keyboard-quit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 ;(setcdr map (nreverse (cdr map)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 ;; Unread a SPC to lead to our new menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 (push (character-to-event ?\ ) unread-command-events)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 ;; Read a char with the menu, and return the result
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 ;; that corresponds to it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 (save-window-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 (display-buffer (get-buffer " widget-choose"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 (let ((cursor-in-echo-area t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 (setq value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (lookup-key overriding-terminal-local-map
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (read-key-sequence (concat title ": ") t)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 (message "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (when (or (eq value 'keyboard-quit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (null value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (error "Canceled"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 ;; Read the choice of name from the minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (setq items (remove-if 'stringp items))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (let ((val (completing-read (concat title ": ") items nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (if (stringp val)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 (let ((try (try-completion val items)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 (when (stringp try)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 (setq val try))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 (cdr (assoc val items)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
318 ;; GNU Emacs 21.3.50 uses this in `widget-choose'
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
319 (defun widget-remove-if (predicate list)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
320 (let (result (tail list))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
321 (while tail
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
322 (or (funcall predicate (car tail))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
323 (setq result (cons (car tail) result)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
324 (setq tail (cdr tail)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
325 (nreverse result)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
326
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 ;;; Widget text specifications.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 ;; These functions are for specifying text properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
332 ;; XEmacs: This probably should be unnecessary with end-closed extents.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
333 ;; If it doesn't work, it should be made to work.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (defcustom widget-field-add-space t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 ;; Setting this to nil might be available, once some problems are resolved.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 "Non-nil means add extra space at the end of editable text fields.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
338 Currently should be left set to `t', because without the space it becomes
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
339 impossible to edit a zero size field."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 :type 'boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
343 ;; #### Why aren't these used in XEmacs?
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 (defcustom widget-field-use-before-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 (and (or (> emacs-minor-version 34)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 (> emacs-major-version 19))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 (not (string-match "XEmacs" emacs-version)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 "Non-nil means use `before-change-functions' to track editable fields.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 This enables the use of undo, but doesn't work on Emacs 19.34 and earlier.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 Using before hooks also means that the :notify function can't know the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 new value."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 :type 'boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (defun widget-echo-this-extent (extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (let* ((widget (or (extent-property extent 'button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 (extent-property extent 'field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (extent-property extent 'glyph-widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 (help-echo (and widget (widget-get widget :help-echo))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 (and (functionp help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 (setq help-echo (funcall help-echo widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 (when (stringp help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 (setq help-echo-owns-message t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 (display-message 'help-echo help-echo))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (defsubst widget-handle-help-echo (extent help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 (set-extent-property extent 'balloon-help help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 (set-extent-property extent 'help-echo help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 (when (functionp help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (set-extent-property extent 'balloon-help 'widget-echo-this-extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (set-extent-property extent 'help-echo 'widget-echo-this-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (defun widget-specify-field (widget from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 "Specify editable button for WIDGET between FROM and TO."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (goto-char to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (cond ((null (widget-get widget :size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 (forward-char 1))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
379 ;; XEmacs: This comment goes outside of the save-excursion in GNU.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 ;; Terminating space is not part of the field, but necessary in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 ;; order for local-map to work. Remove next sexp if local-map works
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 ;; at the end of the extent.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (widget-field-add-space
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 (insert-and-inherit " ")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (setq to (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (let ((map (widget-get widget :keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (face (or (widget-get widget :value-face) 'widget-field-face))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (help-echo (widget-get widget :help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (extent (make-extent from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (unless (or (stringp help-echo) (null help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (setq help-echo 'widget-mouse-help))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (widget-put widget :field-extent extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (and (or (not widget-field-add-space)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 (widget-get widget :size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 (set-extent-property extent 'end-closed nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 (set-extent-property extent 'detachable nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (set-extent-property extent 'field widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (set-extent-property extent 'button-or-field t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 (set-extent-property extent 'keymap map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (set-extent-property extent 'face face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 (widget-handle-help-echo extent help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 (widget-specify-secret widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 (defun widget-specify-secret (field)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
405 "Replace text in FIELD with value of the `:secret' property, if non-nil.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
406
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
407 The value of the `:secret' property, if non-nil, must be a character.
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
408 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
409 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (let ((secret (widget-get field :secret))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 (size (widget-get field :size)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 (when secret
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 (let ((begin (widget-field-start field))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 (end (widget-field-end field)))
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
415 (when size
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 (while (and (> end begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 (eq (char-after (1- end)) ?\ ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 (setq end (1- end))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 (while (< begin end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 (let ((old (char-after begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 (unless (eq old secret)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 (subst-char-in-region begin (1+ begin) old secret)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 (put-text-property begin (1+ begin) 'secret old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 (setq begin (1+ begin))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (defun widget-specify-button (widget from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 "Specify button for WIDGET between FROM and TO."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 (let ((face (widget-apply widget :button-face-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 (help-echo (widget-get widget :help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 (extent (make-extent from to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (map (widget-get widget :button-keymap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 (widget-put widget :button-extent extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 (unless (or (null help-echo) (stringp help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (setq help-echo 'widget-mouse-help))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 (set-extent-property extent 'start-open t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 (set-extent-property extent 'button widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 (set-extent-property extent 'button-or-field t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 (set-extent-property extent 'mouse-face widget-mouse-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 (widget-handle-help-echo extent help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 (set-extent-property extent 'face face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 (set-extent-property extent 'keymap map)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 (defun widget-mouse-help (extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 "Find mouse help string for button in extent."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 (let* ((widget (widget-at (extent-start-position extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 (help-echo (and widget (widget-get widget :help-echo))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 (cond ((stringp help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 ((and (functionp help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 (stringp (setq help-echo (funcall help-echo widget))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 (format "(widget %S :help-echo %S)" widget help-echo)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 (defun widget-specify-sample (widget from to)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
456 "Specify sample for WIDGET between FROM and TO."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 (let ((face (widget-apply widget :sample-face-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 (extent (make-extent from to nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 (set-extent-property extent 'start-open t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 (set-extent-property extent 'face face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 (widget-put widget :sample-extent extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 (defun widget-specify-doc (widget from to)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
464 "Specify documentation for WIDGET between FROM and TO."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 (let ((extent (make-extent from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 (set-extent-property extent 'start-open t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 (set-extent-property extent 'widget-doc widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 (set-extent-property extent 'face widget-documentation-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 (widget-put widget :doc-extent extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 (defmacro widget-specify-insert (&rest form)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
472 "Execute FORM without inheriting any text properties."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 `(save-restriction
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (let ((inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 (insert "<>")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (narrow-to-region (- (point) 2) (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 (goto-char (1+ (point-min)))
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
480 ;; XEmacs: use `prog1' instead of a `result' variable. The latter
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 ;; confuses the byte-compiler in some cases (a warning).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (prog1 (progn ,@form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 (delete-region (point-min) (1+ (point-min)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (delete-region (1- (point-max)) (point-max))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (goto-char (point-max))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 (put 'widget-specify-insert 'edebug-form-spec '(&rest form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 ;;; Inactive Widgets.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 (defface widget-inactive-face '((((class grayscale color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 (background dark))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 (:foreground "light gray"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (((class grayscale color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (background light))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (:foreground "dim gray"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (:italic t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 "Face used for inactive widgets."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 ;; For inactiveness to work on complex structures, it is not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 ;; sufficient to keep track of whether a button/field/glyph is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ;; inactive or not -- we must know how many time it was deactivated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ;; (inactiveness level). Successive deactivations of the same button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 ;; increment its inactive-count, and activations decrement it. When
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ;; inactive-count reaches 0, the button/field/glyph is reactivated.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (defun widget-activation-widget-mapper (extent action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 "Activate or deactivate EXTENT's widget (button or field).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 Suitable for use with `map-extents'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 (ecase action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 (:activate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 (decf (extent-property extent :inactive-count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 (when (zerop (extent-property extent :inactive-count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 (set-extent-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 extent (extent-property extent :inactive-plist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 (set-extent-property extent :inactive-plist nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 (:deactivate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 (incf (extent-property extent :inactive-count 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 ;; Store a plist of old properties, which will be fed to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 ;; `set-extent-properties'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 (unless (extent-property extent :inactive-plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 (set-extent-property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 extent :inactive-plist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 (list 'mouse-face (extent-property extent 'mouse-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 'help-echo (extent-property extent 'help-echo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 'keymap (extent-property extent 'keymap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 (set-extent-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 extent '(mouse-face nil help-echo nil keymap nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 (defun widget-activation-glyph-mapper (extent action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 (let ((activate-p (if (eq action :activate) t nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 (if activate-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 (decf (extent-property extent :inactive-count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 (incf (extent-property extent :inactive-count 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 (when (or (and activate-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 (zerop (extent-property extent :inactive-count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 (and (not activate-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 (not (zerop (extent-property extent :inactive-count)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 (let* ((glyph-widget (extent-property extent 'glyph-widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 (up-glyph (widget-get glyph-widget :glyph-up))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 (inactive-glyph (widget-get glyph-widget :glyph-inactive))
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
546 (instantiator (widget-get glyph-widget :glyph-instantiator))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 (new-glyph (if activate-p up-glyph inactive-glyph)))
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
548 (cond
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
549 ;; Assume that an instantiator means a native widget.
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
550 (instantiator
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
551 (setq instantiator
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
552 (set-instantiator-property instantiator :active activate-p))
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
553 (widget-put glyph-widget :glyph-instantiator instantiator)
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
554 (set-glyph-image up-glyph instantiator))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 ;; Check that the new glyph exists, and differs from the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 ;; default one.
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
557 ((and up-glyph inactive-glyph (not (eq up-glyph inactive-glyph))
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
558 ;; Check if the glyph is already installed.
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
559 (not (eq (extent-end-glyph extent) new-glyph)))
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
560 ;; Change it.
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
561 (set-extent-end-glyph extent new-glyph))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 (defun widget-specify-inactive (widget from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 "Make WIDGET inactive for user modifications."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 (unless (widget-get widget :inactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 (let ((extent (make-extent from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 ;; It is no longer necessary for the extent to be read-only, as
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 ;; the inactive editable fields now lose their keymaps.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 (set-extent-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 extent '(start-open t face widget-inactive-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 detachable t priority 2001 widget-inactive t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 (widget-put widget :inactive extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 ;; Deactivate the buttons and fields within the range. In some
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 ;; cases, the fields are not yet setup at the time this function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 ;; is called. Those fields are deactivated explicitly by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 ;; `widget-setup'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 (map-extents 'widget-activation-widget-mapper
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 nil from to :deactivate nil 'button-or-field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 ;; Deactivate glyphs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 (map-extents 'widget-activation-glyph-mapper
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 nil from to :deactivate nil 'glyph-widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 (defun widget-specify-active (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 "Make WIDGET active for user modifications."
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
586 (let ((inactive (widget-get widget :inactive))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
587 (from (widget-get widget :from))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
588 (to (widget-get widget :to)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 (when (and inactive (not (extent-detached-p inactive)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 ;; Reactivate the buttons and fields covered by the extent.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 (map-extents 'widget-activation-widget-mapper
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
592 nil from to :activate nil 'button-or-field)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 ;; Reactivate the glyphs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 (map-extents 'widget-activation-glyph-mapper
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
595 nil from to :activate nil 'end-glyph)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 (delete-extent inactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 (widget-put widget :inactive nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;;; Widget Properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 (defsubst widget-type (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 "Return the type of WIDGET, a symbol."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (car widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
606 ;;;###autoload
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
607 (defun widgetp (widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
608 "Return non-nil iff WIDGET is a widget."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
609 (if (symbolp widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
610 (get widget 'widget-type)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
611 (and (consp widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
612 (symbolp (car widget))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
613 (get (car widget) 'widget-type))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
614
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 (when (or (not (fboundp 'widget-put))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 widget-shadow-subrs)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 (defun widget-put (widget property value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 "In WIDGET set PROPERTY to VALUE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 The value can later be retrieved with `widget-get'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 (setcdr widget (plist-put (cdr widget) property value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 ;; Recoded in C, for efficiency:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 (when (or (not (fboundp 'widget-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 widget-shadow-subrs)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (defun widget-get (widget property)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 "In WIDGET, get the value of PROPERTY.
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
627 The value may have been specified when the widget was created, or
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 later with `widget-put'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 (let ((missing t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 value tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 (while missing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 (cond ((setq tmp (widget-plist-member (cdr widget) property))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 (setq value (car (cdr tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 missing nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 ((setq tmp (car widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 (setq widget (get tmp 'widget-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 (setq missing nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 (defun widget-get-indirect (widget property)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 "In WIDGET, get the value of PROPERTY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 If the value is a symbol, return its binding.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 Otherwise, just return the value."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 (let ((value (widget-get widget property)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 (if (symbolp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 (symbol-value value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 (defun widget-member (widget property)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
651 "Non-nil iff there is a definition in WIDGET for PROPERTY."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 (cond ((widget-plist-member (cdr widget) property)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 ((car widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 (widget-member (get (car widget) 'widget-type) property))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 (t nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 (when (or (not (fboundp 'widget-apply))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 widget-shadow-subrs)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 ;;This is in C, so don't ###utoload
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 (defun widget-apply (widget property &rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 "Apply the value of WIDGET's PROPERTY to the widget itself.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 ARGS are passed as extra arguments to the function."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 (apply (widget-get widget property) widget args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 (defun widget-value (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 "Extract the current value of WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 (widget-apply widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 :value-to-external (widget-apply widget :value-get)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 (defun widget-value-set (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 "Set the current value of WIDGET to VALUE."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 (widget-apply widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 :value-set (widget-apply widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 :value-to-internal value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 (defun widget-default-get (widget)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
678 "Extract the default value of WIDGET."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 (or (widget-get widget :value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 (widget-apply widget :default-get)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 (defun widget-match-inline (widget vals)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
683 "In WIDGET, match the start of VALS."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 (cond ((widget-get widget :inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 (widget-apply widget :match-inline vals))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 436
diff changeset
686 ((and (listp vals)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 (widget-apply widget :match (car vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 (cons (list (car vals)) (cdr vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 (t nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 (defun widget-apply-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 "Apply :action in WIDGET in response to EVENT."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 (if (widget-apply widget :active)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 (widget-apply widget :action event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 (error "Attempt to perform action on inactive widget")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 ;;; Helper functions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 ;; These are widget specific.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 ;;;###autoload
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 (defun widget-prompt-value (widget prompt &optional value unbound)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 "Prompt for a value matching WIDGET, using PROMPT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 The current value is assumed to be VALUE, unless UNBOUND is non-nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 (unless (listp widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 (setq widget (list widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 (setq prompt (format "[%s] %s" (widget-type widget) prompt))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 (setq widget (widget-convert widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 (let ((answer (widget-apply widget :prompt-value prompt value unbound)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 (while (not (widget-apply widget :match answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 (setq answer (signal 'error (list "Answer does not match type"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 answer (widget-type widget)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 (defun widget-get-sibling (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 "Get the item WIDGET is assumed to toggle.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 This is only meaningful for radio buttons or checkboxes in a list."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
719 (let* ((children (widget-get (widget-get widget :parent) :children))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 (catch 'child
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 (setq child (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 children (cdr children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 (when (eq (widget-get child :button) widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 (throw 'child child)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 (defun widget-map-buttons (function &optional buffer maparg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 "Map FUNCTION over the buttons in BUFFER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 FUNCTION is called with the arguments WIDGET and MAPARG.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 If FUNCTION returns non-nil, the walk is cancelled.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 The arguments MAPARG, and BUFFER default to nil and (current-buffer),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 respectively."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 (map-extents (lambda (extent ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 ;; If FUNCTION returns non-nil, we bail out
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 (funcall function (extent-property extent 'button) maparg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 nil nil nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 'button))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 ;;; Glyphs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 (defcustom widget-glyph-directory (locate-data-directory "custom")
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
747 "Where widget button glyphs are located.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 If this variable is nil, widget will try to locate the directory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 automatically."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 :type 'directory)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 (defcustom widget-glyph-enable t
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
754 "If non nil, use glyph buttons in widgets when available."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 :type 'boolean)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
758 ;; #### What happens if you try to customize this?
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
759 (define-compatible-variable-alias 'widget-image-conversion
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
760 'widget-image-file-name-suffixes)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
761
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 (defcustom widget-image-file-name-suffixes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 '((xpm ".xpm") (gif ".gif") (png ".png") (jpeg ".jpg" ".jpeg")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 (xbm ".xbm"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 "Conversion alist from image formats to file name suffixes."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 :type '(repeat (cons :format "%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 (symbol :tag "Image Format" unknown)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 (repeat :tag "Suffixes"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 (string :format "%v")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 ;; Don't use this, because we cannot yet distinguish between widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 ;; glyphs associated with user action, and actionless ones.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 ;(defvar widget-glyph-pointer-glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 ; (make-pointer-glyph [cursor-font :data "hand2"])
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 ; "Glyph to be used as the mouse pointer shape over glyphs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 ;Use `set-glyph-image' to change this.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 (defvar widget-glyph-cache nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 "Cache of glyphs associated with strings (files).")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 (defun widget-glyph-find (image tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 "Create a glyph corresponding to IMAGE with string TAG as fallback.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 IMAGE can already be a glyph, or a file name sans extension (xpm,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 xbm, gif, jpg, or png) located in `widget-glyph-directory', or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 in one of the data directories.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 It can also be a valid image instantiator, in which case it will be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 used to make the glyph, with an additional TAG string fallback."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 (cond ((not (and image widget-glyph-enable))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 ;; We don't want to use glyphs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 ((and (not (console-on-window-system-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 ;; We don't use glyphs on TTY consoles, although we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 ;; could. However, glyph faces aren't yet working
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 ;; properly, and movement through glyphs is unintuitive.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 ;; As an exception, when TAG is nil, we assume that the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 ;; caller knows what he is doing, and that the tag is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 ;; encoded within the glyph.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 (not (glyphp image)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 ((glyphp image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 ;; Already a glyph. Use it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 ((stringp image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 ;; A string. Look it up in the cache first...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 (or (lax-plist-get widget-glyph-cache image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 ;; ...and then in the relevant directories
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 (let* ((dirlist (cons (or widget-glyph-directory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 (locate-data-directory "custom"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 data-directory-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 (all-suffixes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 (apply #'append
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 (lambda (el)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 (and (valid-image-instantiator-format-p (car el))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 (cdr el)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 widget-image-file-name-suffixes)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 (file (locate-file image dirlist all-suffixes)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 (when file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 (let* ((extension (concat "." (file-name-extension file)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 (format (car (rassoc* extension
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 widget-image-file-name-suffixes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 :test #'member))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 ;; We create a glyph with the file as the default image
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 ;; instantiator, and the TAG fallback
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 (let ((glyph (make-glyph `([,format :file ,file]
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 [string :data ,tag]))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 ;; Cache the glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 (laxputf widget-glyph-cache image glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 ;; ...and return it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 glyph))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 ((valid-instantiator-p image 'image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 ;; A valid image instantiator (e.g. [gif :file "somefile"] etc.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 (make-glyph `(,image [string :data ,tag])))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 ;; Oh well.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 (defun widget-glyph-insert (widget tag image &optional down inactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 "In WIDGET, insert the text TAG or, if supported, IMAGE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 IMAGE should either be a glyph, an image instantiator, an image file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 name sans extension (xpm, xbm, gif, jpg, or png) located in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 `widget-glyph-directory', or anything else allowed by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 `widget-glyph-find'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 If IMAGE is a list, it will be taken as a list of (UP DOWN INACTIVE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 glyphs. The down and inactive glyphs are shown when glyph is pressed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 or inactive, respectively.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 The optional DOWN and INACTIVE arguments are deprecated, and exist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 only because of compatibility."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 ;; Convert between IMAGE being a list, etc. Must use `psetq',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 ;; because otherwise change to `image' screws up the rest.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 (psetq image (or (and (consp image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 (car image))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 down (or (and (consp image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 (nth 1 image))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 down)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 inactive (or (and (consp image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 (nth 2 image))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 (let ((glyph (widget-glyph-find image tag)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 (if glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 (widget-glyph-insert-glyph widget glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 (widget-glyph-find down tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 (widget-glyph-find inactive tag))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 (insert tag))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
871 (defun widget-glyph-insert-glyph (widget glyph &optional down inactive
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
872 instantiator)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 "In WIDGET, insert GLYPH.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 If optional arguments DOWN and INACTIVE are given, they should be
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
875 glyphs used when the widget is pushed and inactive, respectively.
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
876 INSTANTIATOR is the vector used to create the glyph."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 (insert "*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 (let ((extent (make-extent (point) (1- (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 (help-echo (and widget (widget-get widget :help-echo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 (map (and widget (widget-get widget :button-keymap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 (set-extent-property extent 'glyph-widget widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 ;; It would be fun if we could make this extent atomic, so it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 ;; doesn't mess with cursor motion. But atomic-extents library is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 ;; currently a mess, so I'd rather not use it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 (set-extent-property extent 'invisible t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 (set-extent-property extent 'start-open t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887 (set-extent-property extent 'end-open t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 (set-extent-property extent 'keymap map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 ;;(set-extent-property extent 'pointer widget-glyph-pointer-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 (set-extent-end-glyph extent glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 (unless (or (stringp help-echo) (null help-echo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 (setq help-echo 'widget-mouse-help))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 (when help-echo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 (widget-handle-help-echo extent help-echo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 (when widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 (widget-put widget :glyph-up glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 (when down (widget-put widget :glyph-down down))
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
898 (when instantiator (widget-put widget :glyph-instantiator instantiator))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 (when inactive (widget-put widget :glyph-inactive inactive))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 ;;; Buttons.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 (defgroup widget-button nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 "The look of various kinds of buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 (defcustom widget-button-prefix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 "String used as prefix for buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913 (defcustom widget-button-suffix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 "String used as suffix for buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 ;;; Creating Widgets.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 ;;;###autoload
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 (defun widget-create (type &rest args)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
923 "Create a widget of type TYPE.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
924
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
925 TYPE is copied, then converted to a widget using the keyword arguments ARGS."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 (let ((widget (apply 'widget-convert type args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 (widget-apply widget :create)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 (defun widget-create-child-and-convert (parent type &rest args)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
931 "As a child of widget PARENT, create a widget of type TYPE.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
932
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
933 TYPE is copied, then converted to a widget using the keyword arguments ARGS."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 (let ((widget (apply 'widget-convert type args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 (widget-put widget :parent parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
936 (unless (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 (widget-put widget :indent (+ (or (widget-get parent :indent) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 (or (widget-get widget :extra-offset) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939 (widget-get parent :offset))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 (widget-apply widget :create)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943 (defun widget-create-child (parent type)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
944 "As a child of widget PARENT, create a widget of type TYPE.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
945
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
946 TYPE is copied, then used as a widget as-is."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
947 (let ((widget (copy-sequence type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
948 (widget-put widget :parent parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
949 (unless (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
950 (widget-put widget :indent (+ (or (widget-get parent :indent) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 (or (widget-get widget :extra-offset) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952 (widget-get parent :offset))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 (widget-apply widget :create)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 (defun widget-create-child-value (parent type value)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
957 "As a child of widget PARENT, create a widget with type TYPE and value VALUE.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
958
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
959 TYPE is copied, then used as a widget as-is."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960 (let ((widget (copy-sequence type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
961 (widget-put widget :value (widget-apply widget :value-to-internal value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
962 (widget-put widget :parent parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
963 (unless (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 (widget-put widget :indent (+ (or (widget-get parent :indent) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 (or (widget-get widget :extra-offset) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966 (widget-get parent :offset))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 (widget-apply widget :create)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
969
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 ;;;###autoload
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971 (defun widget-delete (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 "Delete WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973 (widget-apply widget :delete))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
975 (defun widget-copy (widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
976 "Make a deep copy of WIDGET."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
977 (widget-apply (copy-sequence widget) :copy))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
978
1333
1b0339b048ce [xemacs-hg @ 2003-03-02 09:38:37 by ben]
ben
parents: 1309
diff changeset
979 ;;;###autoload
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 (defun widget-convert (type &rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 "Convert TYPE to a widget without inserting it in the buffer.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
982 The optional ARGS are additional keyword arguments.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
983
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
984 The widget's :args property is set from the longest tail of ARGS whose cdr
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
985 is not a keyword, or from the longest tail of TYPE's :args property whose
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
986 cdr is not a keyword. Keyword arguments from ARGS are set, and the :value
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
987 property (if any) is converted from external to internal format."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
988 ;; Don't touch the type.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 (let* ((widget (if (symbolp type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990 (list type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 (copy-sequence type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
992 (current widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
993 (keys args))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
994 ;; First set the :args.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
995 (while (cdr current) ; Use first non-keyword element of type.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
996 (let ((next (car (cdr current))))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
997 (if (keywordp next)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
998 (setq current (cdr (cdr current)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999 (setcdr current (list :args (cdr current)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000 (setq current nil))))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1001 (while args ; Use first non-keyword element in ARGS.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1002 (let ((next (nth 0 args)))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1003 (if (keywordp next)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1004 (setq args (nthcdr 2 args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1005 (widget-put widget :args args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1006 (setq args nil))))
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1007 ;; Then convert the widget.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1008 (setq type widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1009 (while type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1010 (let ((convert-widget (plist-get (cdr type) :convert-widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1011 (if convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1012 (setq widget (funcall convert-widget widget))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1013 (setq type (get (car type) 'widget-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1014 ;; Finally set the keyword args.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1015 (while keys
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1016 (let ((next (nth 0 keys)))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1017 (if (keywordp next)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1018 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1019 (widget-put widget next (nth 1 keys))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1020 (setq keys (nthcdr 2 keys)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1021 (setq keys nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1022 ;; Convert the :value to internal format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1023 (if (widget-member widget :value)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1024 (widget-put widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1025 :value (widget-apply widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1026 :value-to-internal
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1027 (widget-get widget :value))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1028 ;; Return the newly created widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1029 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1030
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1031 ;;;###autoload
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1032 (defun widget-insert (&rest args)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1033 "Call `insert' with ARGS even if surrounding text is read only."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1034 (let ((inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1035 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1036 after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1037 (apply 'insert args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1038
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1039 (defun widget-convert-text (type from to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1040 &optional button-from button-to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1041 &rest args)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1042 "Return a widget of type TYPE with endpoints FROM and TO.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1043 No text will be inserted in the buffer. Instead the positions FROM and TO
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1044 will be used as the widget's end points. The widget is ``wrapped around''
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1045 the text between them.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1046 If optional arguments BUTTON-FROM and BUTTON-TO are given, these will be
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1047 used as the widget's button end points.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1048 Optional ARGS are extra keyword arguments for TYPE."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1049 (let ((widget (apply 'widget-convert type :delete 'widget-leave-text args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1050 (from (copy-marker from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1051 (to (copy-marker to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1052 (set-marker-insertion-type from t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1053 (set-marker-insertion-type to nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1054 (widget-put widget :from from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1055 (widget-put widget :to to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1056 (when button-from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1057 (widget-specify-button widget button-from button-to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1058 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1059
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1060 (defun widget-convert-button (type from to &rest args)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1061 "Return a widget of type TYPE with endpoints FROM and TO.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1062 Optional ARGS are extra keyword arguments for TYPE.
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1063 No text will be inserted in the buffer. Instead the positions FROM and TO
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1064 will be used as the widget's end points, as well as the widget's button's
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1065 end points. The widget is ``wrapped around'' the text between them."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1066 (apply 'widget-convert-text type from to from to args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1067
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1068 (defun widget-leave-text (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1069 "Remove markers and extents from WIDGET and its children."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1070 (let ((from (widget-get widget :from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071 (to (widget-get widget :to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 (button (widget-get widget :button-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1073 (sample (widget-get widget :sample-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1074 (doc (widget-get widget :doc-extent))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1075 (field (widget-get widget :field-extent)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1076 (set-marker from nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1077 (set-marker to nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1078 ;; Maybe we should delete the extents here? As this code doesn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079 ;; remove them from widget structures, maybe it's safer to just
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1080 ;; detach them. That's what GNU-compatible `delete-overlay' does.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 (when button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1082 (detach-extent button))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 (when sample
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 (detach-extent sample))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 (when doc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 (detach-extent doc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 (when field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1088 (detach-extent field))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1089 (mapc 'widget-leave-text (widget-get widget :children))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092 ;;; Keymap and Commands.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1093
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1094 (defvar widget-keymap nil
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1095 "Keymap containing useful bindings for buffers containing widgets.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096 Recommended as a parent keymap for modes using widgets.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 (unless widget-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1099 (setq widget-keymap (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100 (define-key widget-keymap [tab] 'widget-forward)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101 (define-key widget-keymap [(shift tab)] 'widget-backward)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 (define-key widget-keymap [(meta tab)] 'widget-backward)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 (define-key widget-keymap [backtab] 'widget-backward))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 (defvar widget-global-map global-map
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1106 "Keymap used for events a widget does not handle itself.")
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107 (make-variable-buffer-local 'widget-global-map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 (defvar widget-field-keymap nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110 "Keymap used inside an editable field.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1111
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112 (unless widget-field-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 (setq widget-field-keymap (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114 (set-keymap-parents widget-field-keymap global-map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 (define-key widget-field-keymap "\C-k" 'widget-kill-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 (define-key widget-field-keymap [(meta tab)] 'widget-complete)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117 (define-key widget-field-keymap [tab] 'widget-forward)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 (define-key widget-field-keymap [(shift tab)] 'widget-backward)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119 (define-key widget-field-keymap "\C-m" 'widget-field-activate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 (define-key widget-field-keymap "\C-a" 'widget-beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 (define-key widget-field-keymap "\C-e" 'widget-end-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122 (define-key widget-field-keymap "\C-t" 'widget-transpose-chars))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 (defvar widget-text-keymap nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125 "Keymap used inside a text field.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 (unless widget-text-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1128 (setq widget-text-keymap (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1129 (set-keymap-parents widget-field-keymap global-map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1130 (define-key widget-text-keymap "\C-a" 'widget-beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1131 (define-key widget-text-keymap "\C-e" 'widget-end-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 (define-key widget-text-keymap "\C-t" 'widget-transpose-chars))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1134 (defvar widget-button-keymap nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1135 "Keymap used inside a button.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1137 (unless widget-button-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1138 (setq widget-button-keymap (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1139 (set-keymap-parents widget-button-keymap widget-keymap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1140 (define-key widget-button-keymap "\C-m" 'widget-button-press)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1141 (define-key widget-button-keymap [button2] 'widget-button-click)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1142 ;; Ideally, button3 within a button should invoke a button-specific
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1143 ;; menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1144 (define-key widget-button-keymap [button3] 'widget-button-click)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1145 ;;Glyph support.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1146 (define-key widget-button-keymap [button1] 'widget-button1-click))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1148
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 (defun widget-field-activate (pos &optional event)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1150 "Invoke the editable field at point."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 (interactive "@d")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 (let ((field (widget-field-find pos)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 (if field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1154 (widget-apply-action field event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1155 (call-interactively
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156 (lookup-key widget-global-map (this-command-keys))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 (defface widget-button-pressed-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1159 '((((class color))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 (:foreground "red"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1162 (:bold t :underline t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 "Face used for pressed buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1164 :group 'widget-faces)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 (defun widget-event-point (event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167 "Character position of the mouse event, or nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 (and (mouse-event-p event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 (event-point event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171 (defun widget-button-click (event)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1172 "Invoke button under mouse pointer."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1173 (interactive "e")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174 (with-current-buffer (event-buffer event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175 (cond ((event-glyph event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 (widget-glyph-click event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 ((widget-event-point event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 (let* ((pos (widget-event-point event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1179 (button (get-char-property pos 'button)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180 (if button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 (let* ((extent (widget-get button :button-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 (face (extent-property extent 'face))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 (mouse-face (extent-property extent 'mouse-face))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 (help-echo (extent-property extent 'help-echo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1185 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1186 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1187 ;; Merge relevant faces, and make the result mouse-face.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1188 (let ((merge `(widget-button-pressed-face ,mouse-face)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 (nconc merge (if (listp face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 face (list face)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191 (setq merge (delete-if-not 'find-face merge))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 (set-extent-property extent 'mouse-face merge))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 (unless (widget-apply button :mouse-down-action event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194 ;; Wait for button release.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 (while (not (button-release-event-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1196 (setq event (next-event))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1197 (dispatch-event event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1198 ;; Disallow mouse-face and help-echo.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1199 (set-extent-property extent 'mouse-face nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1200 (set-extent-property extent 'help-echo nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1201 (setq pos (widget-event-point event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1202 (unless (eq (current-buffer) (extent-object extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1203 ;; Barf if dispatch-event tripped us by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1204 ;; changing buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1205 (error "Buffer changed during mouse motion"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206 ;; Do the associated action.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 (when (and pos (extent-in-region-p extent pos pos))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1208 (widget-apply-action button event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209 ;; Unwinding: fully release the button.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 (set-extent-property extent 'mouse-face mouse-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211 (set-extent-property extent 'help-echo help-echo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1212 ;; This should not happen!
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1213 (error "`widget-button-click' called outside button"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1214 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1215 (message "You clicked somewhere weird")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1216
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1217 (defun widget-button1-click (event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1218 "Invoke glyph below mouse pointer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1219 (interactive "@e")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1220 (if (event-glyph event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1221 (widget-glyph-click event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1222 ;; Should somehow avoid this.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1223 (let ((command (lookup-key widget-global-map (this-command-keys))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1224 (and (commandp command)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1225 (call-interactively command)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1226
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1227 (defun widget-glyph-click (event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1228 "Handle click on a glyph."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1229 (let* ((glyph (event-glyph event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1230 (extent (event-glyph-extent event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1231 (widget (extent-property extent 'glyph-widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1232 (down-glyph (or (and widget (widget-get widget :glyph-down)) glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1233 (up-glyph (or (and widget (widget-get widget :glyph-up)) glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1234 (last event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1235 (unless (widget-apply widget :active)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1236 (error "This widget is inactive"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1237 (let ((current-glyph 'down))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1238 ;; We always know what glyph is drawn currently, to avoid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1239 ;; unnecessary extent changes. Is this any noticeable gain?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1240 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1241 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1242 ;; Press the glyph.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1243 (set-extent-end-glyph extent down-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1244 ;; Redisplay (shouldn't be needed, but...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1245 (sit-for 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1246 (unless (widget-apply widget :mouse-down-action event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1247 ;; Wait for the release.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1248 (while (not (button-release-event-p last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1249 (unless (button-press-event-p last)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1250 (dispatch-event last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1251 (when (motion-event-p last)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1252 ;; Update glyphs on mouse motion.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1253 (if (eq extent (event-glyph-extent last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1254 (unless (eq current-glyph 'down)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1255 (set-extent-end-glyph extent down-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1256 (setq current-glyph 'down))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1257 (unless (eq current-glyph 'up)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1258 (set-extent-end-glyph extent up-glyph)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1259 (setq current-glyph 'up))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1260 (setq last (next-event event))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1261 (unless (eq (current-buffer) (extent-object extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1262 ;; Barf if dispatch-event tripped us by changing buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1263 (error "Buffer changed during mouse motion"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1264 ;; Apply widget action.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1265 (when (eq extent (event-glyph-extent last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1266 (let ((widget (extent-property (event-glyph-extent event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1267 'glyph-widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1268 (cond ((null widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1269 (message "You clicked on a glyph"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1270 ((not (widget-apply widget :active))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1271 (error "This glyph is inactive"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1272 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1273 (widget-apply-action widget event))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1274 ;; Release the glyph.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1275 (and (eq current-glyph 'down)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1276 ;; The extent might have been detached or deleted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1277 (extent-live-p extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1278 (not (extent-detached-p extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1279 (set-extent-end-glyph extent up-glyph))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1280
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1281 (defun widget-button-press (pos &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1282 "Invoke button at POS."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1283 (interactive "@d")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1284 (let ((button (get-char-property pos 'button)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1285 (if button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1286 (widget-apply-action button event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1287 (let ((command (lookup-key widget-global-map (this-command-keys))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1288 (when (commandp command)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1289 (call-interactively command))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1290
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1291 (defun widget-tabable-at (&optional pos last-tab backwardp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1292 "Return the tabable widget at POS, or nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1293 POS defaults to the value of (point)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1294 (unless pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1295 (setq pos (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1296 (let ((widget (widget-at pos)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1297 (if widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1298 (let ((order (widget-get widget :tab-order)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1299 (if order
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1300 (if last-tab (and (= order (if backwardp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1301 (1- last-tab)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1302 (1+ last-tab)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1303 widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1304 (and (> order 0) widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1305 widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1306 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1307
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1308 ;; Return the button or field extent at point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1309 (defun widget-button-or-field-extent (pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1310 (or (and (get-char-property pos 'button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1311 (widget-get (get-char-property pos 'button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1312 :button-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1313 (and (get-char-property pos 'field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1314 (widget-get (get-char-property pos 'field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1315 :field-extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1316
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1317 (defun widget-next-button-or-field (pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1318 "Find the next button, or field, and return its start position, or nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1319 Internal function, don't use it outside `wid-edit'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1320 (let* ((at-point (widget-button-or-field-extent pos))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1321 (extent (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1322 (lambda (ext ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1323 ext)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1324 nil (if at-point (extent-end-position at-point) pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1325 nil nil 'start-open 'button-or-field)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1326 (and extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1327 (extent-start-position extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1328
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329 ;; This is too slow in buffers with many buttons (W3).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1330 (defun widget-previous-button-or-field (pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1331 "Find the previous button, or field, and return its start position, or nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332 Internal function, don't use it outside `wid-edit'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1333 (let* ((at-point (widget-button-or-field-extent pos))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1334 previous-extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1335 (map-extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1336 (lambda (ext ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337 (if (eq ext at-point)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1338 ;; We reached the extent we were on originally
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1339 (if (= pos (extent-start-position at-point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1340 previous-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1341 (setq previous-extent at-point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1342 (setq previous-extent ext)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1343 nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1344 nil nil pos nil 'start-open 'button-or-field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1345 (and previous-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1346 (extent-start-position previous-extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1347
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1348 (defun widget-move (arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1349 "Move point to the ARG next field or button.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1350 ARG may be negative to move backward."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1351 (let ((opoint (point)) (wrapped 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1352 (last-tab (widget-get (widget-at (point)) :tab-order))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1353 nextpos found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1354 ;; Movement backward
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1355 (while (< arg 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1356 (setq nextpos (widget-previous-button-or-field (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1357 (if nextpos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1358 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1359 (goto-char nextpos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1360 (when (and (not (get-char-property nextpos 'widget-inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1361 (widget-tabable-at nil last-tab t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1362 (incf arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1363 (setq found t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1364 last-tab (widget-get (widget-at (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1365 :tab-order))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1366 (if (and (not found) (> wrapped 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1367 (setq arg 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1368 found nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1369 (goto-char (point-max))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1370 (incf wrapped))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1371 ;; Movement forward
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1372 (while (> arg 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1373 (setq nextpos (widget-next-button-or-field (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1374 (if nextpos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1375 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1376 (goto-char nextpos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1377 (when (and (not (get-char-property nextpos 'widget-inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1378 (widget-tabable-at nil last-tab))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1379 (decf arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1380 (setq found t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1381 last-tab (widget-get (widget-at (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1382 :tab-order))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1383 (if (and (not found) (> wrapped 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1384 (setq arg 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1385 found nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1386 (goto-char (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1387 (incf wrapped))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1388 (if (not found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1389 (goto-char opoint)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1390 (widget-echo-help (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1391 (run-hooks 'widget-move-hook))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1392
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1393 (defun widget-forward (arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1394 "Move point to the next field or button.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1395 With optional ARG, move across that many fields."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1396 (interactive "p")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1397 (run-hooks 'widget-forward-hook)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1398 (widget-move arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1400 (defun widget-backward (arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401 "Move point to the previous field or button.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1402 With optional ARG, move across that many fields."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1403 (interactive "p")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1404 (run-hooks 'widget-backward-hook)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1405 (widget-move (- arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1406
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1407 (defun widget-beginning-of-line ()
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1408 "Go to beginning of field or beginning of line, whichever is first.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1409
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1410 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1411 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1412 (interactive "_")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1413 (let* ((field (widget-field-find (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1414 (start (and field (widget-field-start field))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1415 (if (and start (not (eq start (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1416 (goto-char start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1417 (call-interactively 'beginning-of-line))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1418
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419 (defun widget-end-of-line ()
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1420 "Go to end of field or end of line, whichever is first.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1421
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1422 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1423 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1424 (interactive "_")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1425 (let* ((field (widget-field-find (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1426 (end (and field (widget-field-end field))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1427 (if (and end (not (eq end (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 (call-interactively 'end-of-line))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431 (defun widget-kill-line ()
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1432 "Kill to end of field or end of line, whichever is first.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1433
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1434 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1435 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 (interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 (let* ((field (widget-field-find (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 (newline (save-excursion (forward-line 1) (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439 (end (and field (widget-field-end field))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1440 (if (and field (> newline end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1441 (kill-region (point) end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1442 (call-interactively 'kill-line))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1443
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1444 (defun widget-transpose-chars (arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1445 "Like `transpose-chars', but works correctly at end of widget."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1446 (interactive "*P")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1447 (let* ((field (widget-field-find (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1448 (start (and field (widget-field-start field)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1449 (end (and field (widget-field-end field)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1450 (last-non-space (and start end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1451 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1452 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1453 (skip-chars-backward " \t\n" start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1454 (point)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1455 (cond ((and last-non-space
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1456 (or (= last-non-space start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1457 (= last-non-space (1+ start))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1458 ;; empty or one-character field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1459 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1460 ((= (point) start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1461 ;; at the beginning of the field -- we would get an error here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1462 (error "Cannot transpose at beginning of field"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1463 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1464 (when (and (null arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1465 (= last-non-space (point)))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1466 (backward-char 1))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1467 (transpose-chars arg)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1468
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1469 (defcustom widget-complete-field (lookup-key global-map "\M-\t")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1470 "Default function to call for completion inside fields."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1471 :options '(ispell-complete-word complete-tag lisp-complete-symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1472 :type 'function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1473 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1474
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1475 (defun widget-complete ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1476 "Complete content of editable field from point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1477 When not inside a field, move to the previous button or field."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1478 (interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1479 ;; Somehow, this should make pressing M-TAB twice scroll the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1480 ;; completions window.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1481 (let ((field (widget-field-find (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1482 (if field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1483 (widget-apply field :complete)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1484 (error "Not in an editable field"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1485
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1486
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1487 ;;; Setting up the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1488
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1489 (defvar widget-field-new nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1490 "List of all newly created editable fields in the buffer.")
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 (make-variable-buffer-local 'widget-field-new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1493 (defvar widget-field-list nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1494 "List of all editable fields in the buffer.")
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 (make-variable-buffer-local 'widget-field-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1497 ;; Is this a misnomer?
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1498 (defun widget-at (pos)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1499 "The button or field at POS."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1500 (or (get-char-property pos 'button)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1501 (get-char-property pos 'field)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1502
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1503 ;;;###autoload
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1504 (defun widget-setup ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1505 "Setup current buffer so editing string widgets works."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1506 (let ((inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1507 (after-change-functions nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 (while widget-field-new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1511 (setq field (car widget-field-new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1512 widget-field-new (cdr widget-field-new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1513 widget-field-list (cons field widget-field-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1514 (let ((from (car (widget-get field :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1515 (to (cdr (widget-get field :field-extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1516 (widget-specify-field field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1517 (marker-position from) (marker-position to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1518 (set-marker from nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1519 (set-marker to nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 ;; If the field is placed within the inactive zone, deactivate it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1521 (let ((extent (widget-get field :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1522 (when (get-char-property (extent-start-position extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1523 'widget-inactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1524 (widget-activation-widget-mapper extent :deactivate)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1525 (widget-clear-undo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1526 (widget-add-change))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1528 (defvar widget-field-last nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1529 ;; Last field containing point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 (make-variable-buffer-local 'widget-field-last)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1532 (defvar widget-field-was nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1533 ;; The widget data before the change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1534 (make-variable-buffer-local 'widget-field-was)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1535
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1536 (defun widget-field-at (pos)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1537 "Return the widget field at POS, or nil if none."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1538 (let ((field (get-char-property (or pos (point)) 'field)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1539 (if (eq field 'boundary)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1540 nil
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1541 field)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1542
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 (defun widget-field-buffer (widget)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1544 "Return the buffer containing WIDGET.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1545
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1546 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1547 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1548 (let ((extent (widget-get widget :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1549 (and extent (extent-object extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1550
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1551 (defun widget-field-start (widget)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1552 "Return the start of WIDGET's editing field.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1553
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1554 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1555 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1556 (let ((extent (widget-get widget :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1557 (and extent (extent-start-position extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1558
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559 (defun widget-field-end (widget)
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1560 "Return the end of WIDGET's editing field.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1561
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1562 It is an error to use this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1563 invoking `widget-setup'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1564 (let ((extent (widget-get widget :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565 ;; Don't subtract one if local-map works at the end of the extent.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566 (and extent (if (or widget-field-add-space
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 (null (widget-get widget :size)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568 (1- (extent-end-position extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 (extent-end-position extent)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1570
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1571 (defun widget-field-find (pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1572 "Return the field at POS.
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1573 Unlike (get-char-property POS 'field) this, works with empty fields too.
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1574
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1575 Warning: using this function after creating the widget but before invoking
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1576 `widget-setup' will always fail."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1577 ;; XEmacs: use `map-extents' instead of a while loop
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1578 (let ((field-extent (map-extents (lambda (extent ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1579 extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580 nil pos pos nil nil 'field)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 (and field-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 (extent-property field-extent 'field))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1583
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1584 ;; Warning: using this function after creating the widget but before
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
1585 ;; invoking `widget-setup' will always fail.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1586 (defun widget-before-change (from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587 ;; Barf if the text changed is outside the editable fields.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1588 (unless inhibit-read-only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1589 (let ((from-field (widget-field-find from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1590 (to-field (widget-field-find to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1591 (cond ((or (null from-field)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 (null to-field))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1593 ;; Either end of change is not within a field.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 (add-hook 'post-command-hook 'widget-add-change nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1595 (error "Attempt to change text outside editable field"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1596 ((not (eq from-field to-field))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 ;; The change begins in one fields, and ends in another one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 (add-hook 'post-command-hook 'widget-add-change nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1599 (error "Change should be restricted to a single field"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1600 ((or (and from-field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1601 (get-char-property from 'widget-inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1602 (and to-field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1603 (get-char-property to 'widget-inactive)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1604 ;; Trying to change an inactive editable field.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 (add-hook 'post-command-hook 'widget-add-change nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1606 (error "Attempt to change an inactive field"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 (widget-field-use-before-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608 ;; #### Bletch! This loses because XEmacs get confused
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1609 ;; if before-change-functions change the contents of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1610 ;; buffer before from/to.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1611 (condition-case nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1612 (widget-apply from-field :notify from-field)
776
79940b592197 [xemacs-hg @ 2002-03-15 07:43:14 by ben]
ben
parents: 724
diff changeset
1613 (error (declare-fboundp (debug "Before Change")))))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1614
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 (defun widget-add-change ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616 (make-local-hook 'post-command-hook)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1617 (remove-hook 'post-command-hook 'widget-add-change t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 (make-local-hook 'before-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619 (add-hook 'before-change-functions 'widget-before-change nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 (make-local-hook 'after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1621 (add-hook 'after-change-functions 'widget-after-change nil t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1623 (defun widget-after-change (from to old)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1624 "Adjust field size and text properties.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1625
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1626 Also, notify the widgets (so, for example, a variable changes its
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1627 state to `modified'. when it is being edited)."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1628 (condition-case nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629 (let ((field (widget-field-find from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1630 (other (widget-field-find to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1631 (when field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1632 (unless (eq field other)
776
79940b592197 [xemacs-hg @ 2002-03-15 07:43:14 by ben]
ben
parents: 724
diff changeset
1633 (declare-fboundp (debug "Change in different fields")))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 (let ((size (widget-get field :size)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 (when size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636 (let ((begin (widget-field-start field))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637 (end (widget-field-end field)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 (cond ((< (- end begin) size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1639 ;; Field too small.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 (insert-char ?\ (- (+ begin size) end))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 ((> (- end begin) size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644 ;; Field too large and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1645 (if (or (< (point) (+ begin size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1646 (> (point) end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1647 ;; Point is outside extra space.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 (setq begin (+ begin size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1649 ;; Point is within the extra space.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1650 (setq begin (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1651 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1652 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653 (while (and (eq (preceding-char) ?\ )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1654 (> (point) begin))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1655 (delete-backward-char 1)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1656 (widget-specify-secret field))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1657 (widget-apply field :notify field)))
776
79940b592197 [xemacs-hg @ 2002-03-15 07:43:14 by ben]
ben
parents: 724
diff changeset
1658 (error (declare-fboundp (debug "After Change")))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1659
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1660
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1661 ;;; Widget Functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1662 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663 ;; These functions are used in the definition of multiple widgets.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1664
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1665 (defun widget-parent-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1666 "Tell :parent of WIDGET to handle the :action.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1667 Optional EVENT is the event that triggered the action."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1668 (widget-apply (widget-get widget :parent) :action event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1669
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1670 (defun widget-children-value-delete (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1671 "Delete all :children and :buttons in WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1672 (mapc 'widget-delete (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1673 (widget-put widget :children nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1674 (mapc 'widget-delete (widget-get widget :buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1675 (widget-put widget :buttons nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1676
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1677 (defun widget-children-validate (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1678 "All the :children must be valid."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1679 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680 child found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1681 (while (and children (not found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1682 (setq child (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1683 children (cdr children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1684 found (widget-apply child :validate)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1685 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1686
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1687 (defun widget-types-copy (widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1688 "Copy :args as widget types in WIDGET."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1689 (widget-put widget :args (mapcar 'widget-copy (widget-get widget :args)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1690 widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1691
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1692 ;; Made defsubst to speed up face editor creation.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1693 (defsubst widget-types-convert-widget (widget)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1694 "Convert each member of :args in WIDGET from a widget type to a widget."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1695 (widget-put widget :args (mapcar 'widget-convert (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1696 widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1697
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1698 (defun widget-value-convert-widget (widget)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1699 "Initialize :value from `(car :args)' in WIDGET, and reset :args."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1700 (let ((args (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1701 (when args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1702 (widget-put widget :value (car args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1703 ;; Don't convert :value here, as this is done in `widget-convert'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1704 ;; (widget-put widget :value (widget-apply widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1705 ;; :value-to-internal (car args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1706 (widget-put widget :args nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1707 widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1708
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1709 (defun widget-value-value-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1710 "Return the :value property of WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1711 (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1712
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1713 ;;; The `default' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1714
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1715 (define-widget 'default nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1716 "Basic widget other widgets are derived from."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1717 :value-to-internal (lambda (widget value) value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1718 :value-to-external (lambda (widget value) value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1719 :button-prefix 'widget-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1720 :button-suffix 'widget-button-suffix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1721 :complete 'widget-default-complete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1722 :create 'widget-default-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1723 :indent nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1724 :offset 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1725 :format-handler 'widget-default-format-handler
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1726 :button-face-get 'widget-default-button-face-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1727 :sample-face-get 'widget-default-sample-face-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1728 :button-keymap widget-button-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1729 :delete 'widget-default-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1730 :value-set 'widget-default-value-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1731 :value-inline 'widget-default-value-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1732 :default-get 'widget-default-default-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1733 :menu-tag-get 'widget-default-menu-tag-get
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1734 :validate #'ignore
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1735 :active 'widget-default-active
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1736 :activate 'widget-specify-active
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1737 :deactivate 'widget-default-deactivate
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1738 :mouse-down-action #'ignore
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1739 :action 'widget-default-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1740 :notify 'widget-default-notify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1741 :prompt-value 'widget-default-prompt-value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1742
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1743 (defun widget-default-complete (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1744 "Call the value of the :complete-function property of WIDGET.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1745 If that does not exists, call the value of `widget-complete-field'."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1746 (call-interactively (or (widget-get widget :complete-function)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1747 widget-complete-field)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1748
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1749 (defun widget-default-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1750 "Create WIDGET at point in the current buffer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1751 (widget-specify-insert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1752 (let ((from (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1753 button-begin button-end button-glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1754 sample-begin sample-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1755 doc-begin doc-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1756 value-pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1757 (insert (widget-get widget :format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1758 (goto-char from)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1759 ;; Parse escapes in format.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1760 ;; Coding this in C would speed up things *a lot*.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1761 ;; sjt sez:
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1762 ;; There are other things to try:
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1763 ;; 1. Use skip-chars-forward.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1764 ;; 2. Use a LIMIT (or narrow buffer?) in the search/skip expression.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1765 ;; 3. Search/skip backward to allow LIMIT to be constant.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1766 (while (re-search-forward "%\\(.\\)" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1767 (let ((escape (aref (match-string 1) 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1768 (replace-match "" t t)
1735
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1769 (funcall
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1770 (aref
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1771 [(lambda () ;?%
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1772 (insert ?%))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1773 (lambda () ;?\[
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1774 (setq button-begin (point-marker))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1775 (set-marker-insertion-type button-begin nil))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1776 (lambda () ;?\]
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1777 (setq button-end (point-marker))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1778 (set-marker-insertion-type button-end nil))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1779 (lambda () ;?\{
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1780 (setq sample-begin (point)))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1781 (lambda () ;?\}
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1782 (setq sample-end (point)))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1783 (lambda () ;?n
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1784 (when (widget-get widget :indent)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1785 (insert ?\n)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1786 (insert-char ?\ (widget-get widget :indent))))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1787 (lambda () ;?t
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1788 (let* ((tag (widget-get widget :tag))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1789 (glyph (widget-get widget :tag-glyph)))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1790 (cond (glyph
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1791 (setq button-glyph
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1792 (widget-glyph-insert
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1793 widget (or tag "Image") glyph)))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1794 (tag
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1795 (insert tag))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1796 (t
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1797 (princ (widget-get widget :value)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1798 (current-buffer))))))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1799 (lambda () ;?d
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1800 (let ((doc (widget-get widget :doc)))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1801 (when doc
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1802 (setq doc-begin (point))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1803 (insert doc)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1804 (while (eq (preceding-char) ?\n)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1805 (delete-backward-char 1))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1806 (insert ?\n)
1735
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1807 (setq doc-end (point)))))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1808 (lambda () ;?v
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1809 (if (and button-begin (not button-end))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1810 (widget-apply widget :value-create)
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1811 (setq value-pos (point-marker))))
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1812 (lambda () ;otherwise
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1813 (widget-apply widget :format-handler escape))]
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1814 (string-match (format "[%c\010]" escape) ;^H can't be found in buff
c521eeaafa0d [xemacs-hg @ 2003-10-10 10:44:55 by stephent]
stephent
parents: 1376
diff changeset
1815 "%[]{}ntdv\010"))))) ;so it can be 'otherwise' cond
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1816 ;; Specify button, sample, and doc, and insert value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1817 (when (and button-begin button-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1818 (unless button-glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1819 (goto-char button-begin)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1820 (insert (widget-get-indirect widget :button-prefix))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1821 (goto-char button-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1822 (set-marker-insertion-type button-end t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1823 (insert (widget-get-indirect widget :button-suffix)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1824 (widget-specify-button widget button-begin button-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1825 ;; Is this necessary?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1826 (set-marker button-begin nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1827 (set-marker button-end nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1828 (and sample-begin sample-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1829 (widget-specify-sample widget sample-begin sample-end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1830 (and doc-begin doc-end
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1831 (widget-specify-doc widget doc-begin doc-end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1832 (when value-pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1833 (goto-char value-pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1834 (widget-apply widget :value-create)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1835 (let ((from (point-min-marker))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1836 (to (point-max-marker)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1837 (set-marker-insertion-type from t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1838 (set-marker-insertion-type to nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1839 (widget-put widget :from from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1840 (widget-put widget :to to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1841 (widget-clear-undo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1842
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1843 (defun widget-default-format-handler (widget escape)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1844 ;; We recognize the %h escape by default.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1845 (let* ((buttons (widget-get widget :buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1846 (cond ((eq escape ?h)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1847 (let* ((doc-property (widget-get widget :documentation-property))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1848 (doc-try (cond ((widget-get widget :doc))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1849 ((functionp doc-property)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1850 (funcall doc-property
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1851 (widget-get widget :value)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1852 ((symbolp doc-property)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1853 (documentation-property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1854 (widget-get widget :value)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1855 doc-property))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1856 (doc-text (and (stringp doc-try)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1857 (> (length doc-try) 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1858 doc-try))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1859 (doc-indent (widget-get widget :documentation-indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1860 (when doc-text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1861 (and (eq (preceding-char) ?\n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1862 (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1863 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1864 ;; The `*' in the beginning is redundant.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1865 (when (eq (aref doc-text 0) ?*)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1866 (setq doc-text (substring doc-text 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1867 ;; Get rid of trailing newlines.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1868 (when (string-match "\n+\\'" doc-text)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1869 (setq doc-text (substring doc-text 0 (match-beginning 0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1870 (push (widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1871 widget 'documentation-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1872 :indent (cond ((numberp doc-indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1873 doc-indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1874 ((null doc-indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1875 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1876 (t 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1877 doc-text)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1878 buttons))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1879 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1880 (signal 'error (list "Unknown escape" escape))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1881 (widget-put widget :buttons buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1882
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1883 (defun widget-default-button-face-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1884 ;; Use :button-face or widget-button-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1885 (or (widget-get widget :button-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1886 (let ((parent (widget-get widget :parent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1887 (if parent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1888 (widget-apply parent :button-face-get)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1889 widget-button-face))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1890
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1891 ;; Shouldn't this be like `widget-default-button-face-get', and recurse, and
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1892 ;; have a fallback?
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1893 (defun widget-default-sample-face-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1894 ;; Use :sample-face.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1895 (widget-get widget :sample-face))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1896
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1897 (defun widget-default-delete (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1898 "Remove widget from the buffer."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1899 (let ((from (widget-get widget :from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1900 (to (widget-get widget :to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1901 (inactive-extent (widget-get widget :inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1902 (button-extent (widget-get widget :button-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1903 (sample-extent (widget-get widget :sample-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1904 (doc-extent (widget-get widget :doc-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1905 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1906 after-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1907 (inhibit-read-only t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1908 (widget-apply widget :value-delete)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1909 ;; #### In current code, these are never reinserted, but recreated.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1910 ;; So they should either be destroyed, or we should think about how to
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1911 ;; reuse them.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1912 (when inactive-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1913 (detach-extent inactive-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1914 (when button-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1915 (detach-extent button-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1916 (when sample-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1917 (detach-extent sample-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1918 (when doc-extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1919 (detach-extent doc-extent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1920 (when (< from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1921 ;; Kludge: this doesn't need to be true for empty formats.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1922 (delete-region from to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1923 (set-marker from nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1924 (set-marker to nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1925 (widget-clear-undo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1926
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1927 (defun widget-default-value-set (widget value)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1928 "Recreate widget with new value."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1929 (let* ((old-pos (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1930 (from (copy-marker (widget-get widget :from)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1931 (to (copy-marker (widget-get widget :to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1932 (offset (if (and (<= from old-pos) (<= old-pos to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1933 (if (>= old-pos (1- to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1934 (- old-pos to 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1935 (- old-pos from)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1936 ;;??? Bug: this ought to insert the new value before deleting the old one,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1937 ;; so that markers on either side of the value automatically
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1938 ;; stay on the same side. -- rms.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1939 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1940 (goto-char (widget-get widget :from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1941 (widget-apply widget :delete)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1942 (widget-put widget :value value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1943 (widget-apply widget :create))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1944 (if offset
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1945 (if (< offset 0)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1946 (goto-char (+ (widget-get widget :to) offset 1))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
1947 (goto-char (min (+ from offset) (1- (widget-get widget :to))))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1948
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1949 (defun widget-default-value-inline (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1950 "Wrap value in a list unless it is inline."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1951 (if (widget-get widget :inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1952 (widget-value widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1953 (list (widget-value widget))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1954
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1955 (defun widget-default-default-get (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1956 "Get `:value'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1957 (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1958
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1959 (defun widget-default-menu-tag-get (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1960 "Use tag or value for menus."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1961 (or (widget-get widget :menu-tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1962 (widget-get widget :tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1963 (widget-princ-to-string (widget-get widget :value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1964
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1965 (defun widget-default-active (widget)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1966 "Return non-nil iff WIDGET is user-modifiable."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1967 (and (not (widget-get widget :inactive))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1968 (let ((parent (widget-get widget :parent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1969 (or (null parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1970 (widget-apply parent :active)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1971
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1972 (defun widget-default-deactivate (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1973 "Make WIDGET inactive for user modifications."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1974 (widget-specify-inactive widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1975 (widget-get widget :from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1976 (widget-get widget :to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1977
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1978 (defun widget-default-action (widget &optional event)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1979 "Notify the parent when a widget changes."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1980 (let ((parent (widget-get widget :parent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1981 (when parent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1982 (widget-apply parent :notify widget event))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1983
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1984 (defun widget-default-notify (widget child &optional event)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1985 "Pass notification to parent."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1986 (widget-default-action widget event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1987
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1988 (defun widget-default-prompt-value (widget prompt value unbound)
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1989 "Read an arbitrary value."
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1990 ;; #### XEmacs: What does this mean?
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1991 ;; Stolen from `set-variable'.
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1992 ;; (let ((initial (if unbound
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1993 ;; nil
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1994 ;; It would be nice if we could do a `(cons val 1)' here.
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1995 ;; (prin1-to-string (custom-quote value))))))
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
1996 ;; XEmacs: make this use default VALUE. Need to check callers.
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
1997 (eval-minibuffer prompt))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1998
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1999 ;;; The `item' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2000
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2001 (define-widget 'item 'default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2002 "Constant items for inclusion in other widgets."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2003 :convert-widget 'widget-value-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2004 :value-create 'widget-item-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2005 :value-delete 'ignore
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2006 :value-get 'widget-value-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2007 :match 'widget-item-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2008 :match-inline 'widget-item-match-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2009 :action 'widget-item-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2010 :format "%t\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2011
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2012 (defun widget-item-value-create (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2013 "Insert the printed representation of the value."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2014 (princ (widget-get widget :value) (current-buffer)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2015
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2016 (defun widget-item-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2017 ;; Match if the value is the same.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2018 (equal (widget-get widget :value) value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2019
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2020 (defun widget-item-match-inline (widget values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2021 ;; Match if the value is the same.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2022 (let ((value (widget-get widget :value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2023 (and (listp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2024 (<= (length value) (length values))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2025 (let ((head (widget-sublist values 0 (length value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2026 (and (equal head value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2027 (cons head (widget-sublist values (length value))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2028
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2029 (defun widget-item-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2030 ;; Just notify itself.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2031 (widget-apply widget :notify widget event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2032
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2033 ;;; The `push-button' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2034
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2035 ;; XEmacs: this seems to refer to button images. How about native widgets?
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2036 (defcustom widget-push-button-gui widget-glyph-enable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2037 "If non nil, use GUI push buttons when available."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2038 :group 'widgets
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2039 :type 'boolean)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2040
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2041 (defcustom widget-push-button-prefix "["
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2042 "String used as prefix for buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2043 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2044 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2045
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2046 (defcustom widget-push-button-suffix "]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2047 "String used as suffix for buttons."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2048 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2049 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2050
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2051 (define-widget 'push-button 'item
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2052 "A button which invokes an action.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2053
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2054 Creators should usually specify `:action' and `:help-echo' members."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2055 :button-prefix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2056 :button-suffix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2057 :value-create 'widget-push-button-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2058 :format "%[%v%]")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2059
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2060 (defun widget-push-button-value-create (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2061 "Insert text representing the `on' and `off' states."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2062 (let* ((tag (or (widget-get widget :tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2063 (widget-get widget :value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2064 (tag-glyph (widget-get widget :tag-glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2065 (text (concat widget-push-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2066 tag widget-push-button-suffix))
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
2067 gui inst)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2068 (cond (tag-glyph
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2069 (widget-glyph-insert widget text tag-glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2070 ;; We must check for console-on-window-system-p here,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2071 ;; because GUI will not work otherwise (it needs RGB
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2072 ;; components for colors, and they are not known on TTYs).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2073 ((and widget-push-button-gui
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2074 (console-on-window-system-p))
436
080151679be2 Import from CVS: tag r21-2-26
cvs
parents: 428
diff changeset
2075 (let* ((gui-button-shadow-thickness 1))
454
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
2076 (setq inst (make-gui-button tag 'widget-gui-action widget))
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
2077 (setq gui (make-glyph inst)))
d7a9135ec789 Import from CVS: tag r21-2-42
cvs
parents: 446
diff changeset
2078 (widget-glyph-insert-glyph widget gui nil nil inst))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2079 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2080 (insert text)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2081
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2082 (defun widget-gui-action (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2083 "Apply :action for WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2084 (widget-apply-action widget (this-command-keys)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2085
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2086 ;;; The `link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2087
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2088 (defcustom widget-link-prefix "["
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2089 "String used as prefix for links."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2090 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2091 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2092
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2093 (defcustom widget-link-suffix "]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2094 "String used as suffix for links."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2095 :type 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2096 :group 'widget-button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2097
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2098 (define-widget 'link 'item
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2099 "An embedded link.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2100
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2101 This is an abstract widget. Subclasses should usually specify `:action'
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2102 and `:help-echo' members."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2103 :button-prefix 'widget-link-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2104 :button-suffix 'widget-link-suffix
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2105 :help-echo "Follow the link."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2106 :format "%[%t%]")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2108 ;;; The `info-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2109
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2110 (define-widget 'info-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2111 "A link to an info file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2112 :help-echo 'widget-info-link-help-echo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2113 :action 'widget-info-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2115 (defun widget-info-link-help-echo (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2116 (concat "Read the manual entry `" (widget-value widget) "'"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2118 (defun widget-info-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2119 "Open the info node specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2120 (Info-goto-node (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2121
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2122 ;;; The `url-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2124 (define-widget 'url-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2125 "A link to an www page."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2126 :help-echo 'widget-url-link-help-echo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2127 :action 'widget-url-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2129 (defun widget-url-link-help-echo (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2130 (concat "Visit <URL:" (widget-value widget) ">"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2131
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2132 (defun widget-url-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2133 "Open the url specified by WIDGET."
2367
ecf1ebac70d8 [xemacs-hg @ 2004-11-04 23:05:23 by ben]
ben
parents: 1873
diff changeset
2134 (if-fboundp 'browse-url
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2135 (browse-url (widget-value widget))
1376
2e0147538471 [xemacs-hg @ 2003-03-24 14:51:45 by stephent]
stephent
parents: 1362
diff changeset
2136 (error 'missing-package "Cannot browse URLs in this XEmacs" 'browse-url)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2137
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2138 ;;; The `function-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2139
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2140 (define-widget 'function-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2141 "A link to an Emacs function."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2142 :action 'widget-function-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2143
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2144 (defun widget-function-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2145 "Show the function specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2146 (describe-function (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2147
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2148 ;;; The `variable-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2149
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2150 (define-widget 'variable-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2151 "A link to an Emacs variable."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2152 :action 'widget-variable-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2153
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2154 (defun widget-variable-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2155 "Show the variable specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2156 (describe-variable (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2157
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2158 ;;; The `file-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2159
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2160 (define-widget 'file-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2161 "A link to a file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2162 :action 'widget-file-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2164 (defun widget-file-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2165 "Find the file specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2166 (find-file (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2167
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2168 ;;; The `emacs-library-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2169
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2170 (define-widget 'emacs-library-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2171 "A link to an Emacs Lisp library file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2172 :help-echo 'widget-emacs-library-link-help-echo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2173 :action 'widget-emacs-library-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2174
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2175 (defun widget-emacs-library-link-help-echo (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2176 (concat "Visit " (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2178 (defun widget-emacs-library-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2179 "Find the Emacs Library file specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2180 (find-file (locate-library (widget-value widget))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2181
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2182 ;;; The `emacs-commentary-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2183
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2184 (define-widget 'emacs-commentary-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2185 "A link to Commentary in an Emacs Lisp library file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2186 :action 'widget-emacs-commentary-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2187
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2188 (defun widget-emacs-commentary-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2189 "Find the Commentary section of the Emacs file specified by WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2190 (finder-commentary (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2191
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2192 ;;; The `editable-field' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2194 (define-widget 'editable-field 'default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2195 "An editable text field."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2196 :convert-widget 'widget-value-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2197 :keymap widget-field-keymap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2198 :format "%v"
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2199 :help-echo "M-TAB: complete field; RET: enter value"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2200 :value ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2201 :prompt-internal 'widget-field-prompt-internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2202 :prompt-history 'widget-field-history
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2203 :prompt-value 'widget-field-prompt-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2204 :action 'widget-field-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2205 :validate 'widget-field-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2206 :valid-regexp ""
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2207 :error "Field's value doesn't match allowed forms"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2208 :value-create 'widget-field-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2209 :value-delete 'widget-field-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2210 :value-get 'widget-field-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2211 :match 'widget-field-match)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2212
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2213 (defvar widget-field-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2214 "History of field minibuffer edits.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2215
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2216 (defun widget-field-prompt-internal (widget prompt initial history)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2217 "Read string for WIDGET prompting with PROMPT.
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2218 INITIAL is the initial input and HISTORY is a symbol containing
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2219 the earlier input."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2220 (read-string prompt initial history))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2221
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2222 (defun widget-field-prompt-value (widget prompt value unbound)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2223 "Prompt for a string."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2224 (widget-apply widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2225 :value-to-external
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2226 (widget-apply widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2227 :prompt-internal prompt
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2228 (unless unbound
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2229 (cons (widget-apply widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2230 :value-to-internal value)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2231 0))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2232 (widget-get widget :prompt-history))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2233
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2234 ;; #### Should be named `widget-action-hooks'.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2235 (defvar widget-edit-functions nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2236 "Functions run on certain actions.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2237
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2238 Not a regular hook; each function should take a widget as an argument.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2239 The standard widget functions `widget-field-action', `widget-choice-action',
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2240 and `widget-toggle-action' use `run-hook-with-args' to run these functions.")
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2241
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2242 (defun widget-field-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2243 ;; Edit the value in the minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2244 (let* ((invalid (widget-apply widget :validate))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2245 (prompt (concat (widget-apply widget :menu-tag-get) ": "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2246 (value (unless invalid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2247 (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2248 (answer (widget-apply widget :prompt-value prompt value invalid)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2249 (unless (equal value answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2250 ;; This is a hack. We can't properly validate the widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2251 ;; because validation requires the new value to be in the field.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2252 ;; However, widget-field-value-create will not function unless
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2253 ;; the new value matches. So, we check whether the thing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2254 ;; matches, and if it does, use either the real or a dummy error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2255 ;; message.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2256 (unless (widget-apply widget :match answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2257 (let ((error-message (or (widget-get widget :type-error)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2258 "Invalid field contents")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2259 (widget-put widget :error error-message)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2260 (error error-message)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2261 (widget-value-set widget answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2262 (widget-apply widget :notify widget event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2263 (widget-setup))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2264 (run-hook-with-args 'widget-edit-functions widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2265
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2266 ;(defun widget-field-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2267 ; ;; Move to next field.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2268 ; (widget-forward 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2269 ; (run-hook-with-args 'widget-edit-functions widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2270
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2271 (defun widget-field-validate (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2272 "Valid if the content matches `:valid-regexp'."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2273 (save-excursion ; XEmacs
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2274 (unless (string-match (widget-get widget :valid-regexp)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2275 (widget-apply widget :value-get))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2276 widget)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2277
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2278 (defun widget-field-value-create (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2279 "Create an editable text field."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2280 (let ((size (widget-get widget :size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2281 (value (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2282 (from (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2283 ;; This is changed to a real extent in `widget-setup'. We
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2284 ;; need the end points to behave differently until
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2285 ;; `widget-setup' is called. Should probably be replaced with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2286 ;; a genuine extent, but some things break, then.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2287 (extent (cons (make-marker) (make-marker))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2288 (widget-put widget :field-extent extent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2289 (insert value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2290 (and size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2291 (< (length value) size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2292 (insert-char ?\ (- size (length value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2293 (unless (memq widget widget-field-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2294 (push widget widget-field-new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2295 (move-marker (cdr extent) (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2296 (set-marker-insertion-type (cdr extent) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2297 (when (null size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2298 (insert ?\n))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2299 (move-marker (car extent) from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2300 (set-marker-insertion-type (car extent) t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2301
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2302 (defun widget-field-value-delete (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2303 "Remove the widget from the list of active editing fields."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2304 (setq widget-field-list (delq widget widget-field-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2305 ;; These are nil if the :format string doesn't contain `%v'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2306 (let ((extent (widget-get widget :field-extent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2307 (when extent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2308 (detach-extent extent))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2309
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2310 (defun widget-field-value-get (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2311 "Return current text in editing field."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2312 (let ((from (widget-field-start widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2313 (to (widget-field-end widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2314 (buffer (widget-field-buffer widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2315 (size (widget-get widget :size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2316 (secret (widget-get widget :secret))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2317 (old (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2318 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2319 ((and from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2320 (set-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2321 (while (and size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2322 (not (zerop size))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2323 (> to from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2324 (eq (char-after (1- to)) ?\ ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2325 (setq to (1- to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2326 (let ((result (buffer-substring-no-properties from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2327 (when secret
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2328 (let ((index 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2329 (while (< (+ from index) to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2330 (aset result index
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2331 (get-char-property (+ from index) 'secret))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2332 (incf index))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2333 (set-buffer old)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2334 result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2335 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2336 (widget-get widget :value)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2337
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2338 (defun widget-field-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2339 ;; Match any string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2340 (stringp value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2341
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2342 ;;; The `text' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2343
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2344 (define-widget 'text 'editable-field
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2345 "A multiline text area."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2346 :keymap widget-text-keymap)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2347
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2348 ;;; The `menu-choice' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2349
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2350 (define-widget 'menu-choice 'default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2351 "A menu of options."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2352 :convert-widget 'widget-types-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2353 :format "%[%t%]: %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2354 :case-fold t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2355 :tag "choice"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2356 :void '(item :format "invalid (%t)\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2357 :value-create 'widget-choice-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2358 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2359 :value-get 'widget-choice-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2360 :value-inline 'widget-choice-value-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2361 :default-get 'widget-choice-default-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2362 :mouse-down-action 'widget-choice-mouse-down-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2363 :action 'widget-choice-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2364 :error "Make a choice"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2365 :validate 'widget-choice-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2366 :match 'widget-choice-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2367 :match-inline 'widget-choice-match-inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2368
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2369 (defun widget-choice-value-create (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2370 "Insert the first choice that matches the value."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2371 (let ((value (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2372 (args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2373 (explicit (widget-get widget :explicit-choice))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2374 current)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2375 (if explicit
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2376 (progn
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2377 ;; If the user specified the choice for this value,
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2378 ;; respect that choice as long as the value is the same.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2379 (widget-put widget :children (list (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2380 widget explicit value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2381 (widget-put widget :choice explicit))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2382 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2383 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2384 args (cdr args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2385 (when (widget-apply current :match value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2386 (widget-put widget :children (list (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2387 widget current value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2388 (widget-put widget :choice current)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2389 (setq args nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2390 current nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2391 (when current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2392 (let ((void (widget-get widget :void)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2393 (widget-put widget :children (list (widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2394 widget void :value value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2395 (widget-put widget :choice void))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2396
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2397 (defun widget-choice-value-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2398 ;; Get value of the child widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2399 (widget-value (car (widget-get widget :children))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2400
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2401 (defun widget-choice-value-inline (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2402 ;; Get value of the child widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2403 (widget-apply (car (widget-get widget :children)) :value-inline))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2404
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2405 (defun widget-choice-default-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2406 ;; Get default for the first choice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2407 (widget-default-get (car (widget-get widget :args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2408
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2409 (defcustom widget-choice-toggle nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2410 "If non-nil, a binary choice will just toggle between the values.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2411 Otherwise, the user will explicitly have to choose between the values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2412 when he invoked the menu."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2413 :type 'boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2414 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2415
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2416 (defun widget-choice-mouse-down-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2417 ;; Return non-nil if we need a menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2418 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2419 (old (widget-get widget :choice)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2420 (cond ((not (console-on-window-system-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2421 ;; No place to pop up a menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2422 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2423 ((< (length args) 2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2424 ;; Empty or singleton list, just return the value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2425 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2426 ((> (length args) widget-menu-max-size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2427 ;; Too long, prompt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2428 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2429 ((> (length args) 2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2430 ;; Reasonable sized list, use menu.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2431 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2432 ((and widget-choice-toggle (memq old args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2433 ;; We toggle.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2434 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2435 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2436 ;; Ask which of the two.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2437 t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2438
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2439 (defun widget-choice-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2440 ;; Make a choice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2441 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2442 (old (widget-get widget :choice))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2443 (tag (widget-apply widget :menu-tag-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2444 (completion-ignore-case (widget-get widget :case-fold))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2445 current choices)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2446 ;; Remember old value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2447 (if (and old (not (widget-apply widget :validate)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2448 (let* ((external (widget-value widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2449 (internal (widget-apply old :value-to-internal external)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2450 (widget-put old :value internal)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2451 ;; Find new choice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2452 (setq current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2453 (cond ((= (length args) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2454 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2455 ((= (length args) 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2456 (nth 0 args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2457 ((and widget-choice-toggle
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2458 (= (length args) 2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2459 (memq old args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2460 (if (eq old (nth 0 args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2461 (nth 1 args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2462 (nth 0 args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2463 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2464 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2465 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2466 args (cdr args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2467 (setq choices
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2468 (cons (cons (widget-apply current :menu-tag-get)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2469 current)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2470 choices)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2471 (let ((choice
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2472 (widget-choose tag (reverse choices) event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2473 (widget-put widget :explicit-choice choice)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2474 choice))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2475 (when current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2476 (let ((value (widget-default-get current)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2477 (widget-value-set widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2478 (widget-apply current :value-to-external value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2479 (widget-setup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2480 (widget-apply widget :notify widget event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2481 (run-hook-with-args 'widget-edit-functions widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2482
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2483 (defun widget-choice-validate (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2484 ;; Valid if we have made a valid choice.
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2485 (if (eq (widget-get widget :void) (widget-get widget :choice))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2486 widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2487 (widget-apply (car (widget-get widget :children)) :validate)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2488
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2489 (defun widget-choice-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2490 ;; Matches if one of the choices matches.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2491 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2492 current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2493 (while (and args (not found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2494 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2495 args (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2496 found (widget-apply current :match value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2497 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2498
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2499 (defun widget-choice-match-inline (widget values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2500 ;; Matches if one of the choices matches.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2501 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2502 current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2503 (while (and args (null found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2504 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2505 args (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2506 found (widget-match-inline current values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2507 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2508
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2509 ;;; The `toggle' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2510
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2511 (define-widget 'toggle 'item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2512 "Toggle between two states."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2513 :format "%[%v%]\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2514 :value-create 'widget-toggle-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2515 :action 'widget-toggle-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2516 :match (lambda (widget value) t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2517 :on "on"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2518 :off "off")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2519
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2520 (defun widget-toggle-value-create (widget)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2521 "Insert text representing the `on' and `off' states."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2522 (if (widget-value widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2523 (widget-glyph-insert widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2524 (widget-get widget :on)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2525 (widget-get widget :on-glyph))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2526 (widget-glyph-insert widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2527 (widget-get widget :off)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2528 (widget-get widget :off-glyph))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2529
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2530 (defun widget-toggle-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2531 ;; Toggle value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2532 (widget-value-set widget (not (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2533 (widget-apply widget :notify widget event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2534 (run-hook-with-args 'widget-edit-functions widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2535
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2536 ;;; The `checkbox' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2537
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2538 (define-widget 'checkbox 'toggle
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2539 "A checkbox toggle."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2540 :button-suffix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2541 :button-prefix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2542 :format "%[%v%]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2543 :on "[X]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2544 :on-glyph "check1"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2545 :off "[ ]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2546 :off-glyph "check0"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2547 :action 'widget-checkbox-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2548
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2549 (defun widget-checkbox-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2550 "Toggle checkbox, notify parent, and set active state of sibling."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2551 (widget-toggle-action widget event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2552 (let ((sibling (widget-get-sibling widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2553 (when sibling
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2554 (if (widget-value widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2555 (widget-apply sibling :activate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2556 (widget-apply sibling :deactivate)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2557
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2558 ;;; The `checklist' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2559
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2560 (define-widget 'checklist 'default
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2561 "A set widget, selecting zero or more of many.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2562
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2563 The parent of several `checkbox' widgets, one for each option."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2564 :convert-widget 'widget-types-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2565 :format "%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2566 :offset 4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2567 :entry-format "%b %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2568 :menu-tag "checklist"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2569 :greedy nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2570 :value-create 'widget-checklist-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2571 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2572 :value-get 'widget-checklist-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2573 :validate 'widget-checklist-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2574 :match 'widget-checklist-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2575 :match-inline 'widget-checklist-match-inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2576
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2577 (defun widget-checklist-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2578 ;; Insert all values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2579 (let ((alist (widget-checklist-match-find widget (widget-get widget :value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2580 (args (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2581 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2582 (widget-checklist-add-item widget (car args) (assq (car args) alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2583 (setq args (cdr args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2584 (widget-put widget :children (nreverse (widget-get widget :children)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2585
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2586 (defun widget-checklist-add-item (widget type chosen)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2587 "Create checklist item in WIDGET of type TYPE.
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2588 If the item is checked, CHOSEN is a cons whose cdr is the value."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2589 (and (eq (preceding-char) ?\n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2590 (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2591 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2592 (widget-specify-insert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2593 (let* ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2594 (buttons (widget-get widget :buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2595 (button-args (or (widget-get type :sibling-args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2596 (widget-get widget :button-args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2597 (from (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2598 child button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2599 (insert (widget-get widget :entry-format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2600 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2601 ;; Parse % escapes in format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2602 (while (re-search-forward "%\\([bv%]\\)" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2603 (let ((escape (aref (match-string 1) 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2604 (replace-match "" t t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2605 (cond ((eq escape ?%)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2606 (insert ?%))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2607 ((eq escape ?b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2608 (setq button (apply 'widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2609 widget 'checkbox
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2610 :value (not (null chosen))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2611 button-args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2612 ((eq escape ?v)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2613 (setq child
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2614 (cond ((not chosen)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2615 (let ((child (widget-create-child widget type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2616 (widget-apply child :deactivate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2617 child))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2618 ((widget-get type :inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2619 (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2620 widget type (cdr chosen)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2621 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2622 (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2623 widget type (car (cdr chosen)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2624 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2625 (signal 'error (list "Unknown escape" escape))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2626 ;; Update properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2627 (and button child (widget-put child :button button))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2628 (and button (widget-put widget :buttons (cons button buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2629 (and child (widget-put widget :children (cons child children))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2630
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2631 (defun widget-checklist-match (widget values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2632 ;; All values must match a type in the checklist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2633 (and (listp values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2634 (null (cdr (widget-checklist-match-inline widget values)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2635
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2636 (defun widget-checklist-match-inline (widget values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2637 ;; Find the values which match a type in the checklist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2638 (let ((greedy (widget-get widget :greedy))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2639 (args (copy-sequence (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2640 found rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2641 (while values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2642 (let ((answer (widget-checklist-match-up args values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2643 (cond (answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2644 (let ((vals (widget-match-inline answer values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2645 (setq found (append found (car vals))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2646 values (cdr vals)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2647 args (delq answer args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2648 (greedy
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2649 (setq rest (append rest (list (car values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2650 values (cdr values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2651 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2652 (setq rest (append rest values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2653 values nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2654 (cons found rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2655
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2656 (defun widget-checklist-match-find (widget vals)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2657 "Find the vals which match a type in the checklist.
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2658 Return an alist of (TYPE MATCH)."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2659 (let ((greedy (widget-get widget :greedy))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2660 (args (copy-sequence (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2661 found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2662 (while vals
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2663 (let ((answer (widget-checklist-match-up args vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2664 (cond (answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2665 (let ((match (widget-match-inline answer vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2666 (setq found (cons (cons answer (car match)) found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2667 vals (cdr match)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2668 args (delq answer args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2669 (greedy
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2670 (setq vals (cdr vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2671 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2672 (setq vals nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2673 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2674
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2675 (defun widget-checklist-match-up (args vals)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2676 "Return the first type from ARGS that matches VALS."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2677 (let (current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2678 (while (and args (null found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2679 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2680 args (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2681 found (widget-match-inline current vals)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2682 (if found
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2683 current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2684 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2685
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2686 (defun widget-checklist-value-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2687 ;; The values of all selected items.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2688 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2689 child result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2690 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2691 (setq child (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2692 children (cdr children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2693 (if (widget-value (widget-get child :button))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2694 (setq result (append result (widget-apply child :value-inline)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2695 result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2696
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2697 (defun widget-checklist-validate (widget)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 436
diff changeset
2698 ;; Ticked children must be valid.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2699 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2700 child button found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2701 (while (and children (not found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2702 (setq child (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2703 children (cdr children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2704 button (widget-get child :button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2705 found (and (widget-value button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2706 (widget-apply child :validate))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2707 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2708
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2709 ;;; The `option' Widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2710
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2711 (define-widget 'option 'checklist
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2712 "A widget presenting optional items for inline inclusion in a parent widget."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2713 :inline t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2714
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2715 ;;; The `choice-item' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2716
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2717 (define-widget 'choice-item 'item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2718 "Button items that delegate action events to their parents."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2719 :action 'widget-parent-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2720 :format "%[%t%] \n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2721
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2722 ;;; The `radio-button' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2723
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2724 (define-widget 'radio-button 'toggle
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2725 "A radio button for use in the `radio' widget."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2726 :notify 'widget-radio-button-notify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2727 :format "%[%v%]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2728 :button-suffix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2729 :button-prefix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2730 :on "(*)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2731 :on-glyph '("radio1" nil "radio0")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2732 :off "( )"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2733 :off-glyph "radio0")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2735 (defun widget-radio-button-notify (widget child &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2736 ;; Tell daddy.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2737 (widget-apply (widget-get widget :parent) :action widget event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2738
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2739 ;;; The `radio-button-choice' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2740
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2741 (define-widget 'radio-button-choice 'default
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2742 "A set widget, selecting exactly one of many options.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2743
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
2744 The parent of several `radio-button' widgets, one for each option."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2745 :convert-widget 'widget-types-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2746 :offset 4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2747 :format "%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2748 :entry-format "%b %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2749 :menu-tag "radio"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2750 :value-create 'widget-radio-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2751 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2752 :value-get 'widget-radio-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2753 :value-inline 'widget-radio-value-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2754 :value-set 'widget-radio-value-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2755 :error "You must push one of the buttons"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2756 :validate 'widget-radio-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2757 :match 'widget-choice-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2758 :match-inline 'widget-choice-match-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2759 :action 'widget-radio-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2760
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2761 (defun widget-radio-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2762 ;; Insert all values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2763 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2764 arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2765 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2766 (setq arg (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2767 args (cdr args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2768 (widget-radio-add-item widget arg))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2769
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2770 (defun widget-radio-add-item (widget type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2771 "Add to radio widget WIDGET a new radio button item of type TYPE."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2772 ;; (setq type (widget-convert type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2773 (and (eq (preceding-char) ?\n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2774 (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2775 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2776 (widget-specify-insert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2777 (let* ((value (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2778 (children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2779 (buttons (widget-get widget :buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2780 (button-args (or (widget-get type :sibling-args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2781 (widget-get widget :button-args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2782 (from (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2783 (chosen (and (null (widget-get widget :choice))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2784 (widget-apply type :match value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2785 child button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2786 (insert (widget-get widget :entry-format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2787 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2788 ;; Parse % escapes in format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2789 (while (re-search-forward "%\\([bv%]\\)" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2790 (let ((escape (aref (match-string 1) 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2791 (replace-match "" t t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2792 (cond ((eq escape ?%)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2793 (insert ?%))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2794 ((eq escape ?b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2795 (setq button (apply 'widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2796 widget 'radio-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2797 :value (not (null chosen))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2798 button-args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2799 ((eq escape ?v)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2800 (setq child (if chosen
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2801 (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2802 widget type value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2803 (widget-create-child widget type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2804 (unless chosen
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2805 (widget-apply child :deactivate)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2806 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2807 (signal 'error (list "Unknown escape" escape))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2808 ;; Update properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2809 (when chosen
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2810 (widget-put widget :choice type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2811 (when button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2812 (widget-put child :button button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2813 (widget-put widget :buttons (nconc buttons (list button))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2814 (when child
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2815 (widget-put widget :children (nconc children (list child))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2816 child)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2817
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2818 (defun widget-radio-value-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2819 ;; Get value of the child widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2820 (let ((chosen (widget-radio-chosen widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2821 (and chosen (widget-value chosen))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2822
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2823 (defun widget-radio-chosen (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2824 "Return the widget representing the chosen radio button."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2825 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2826 current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2827 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2828 (setq current (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2829 children (cdr children))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2830 (when (widget-apply (widget-get current :button) :value-get)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2831 (setq found current
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2832 children nil)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2833 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2834
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2835 (defun widget-radio-value-inline (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2836 ;; Get value of the child widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2837 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2838 current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2839 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2840 (setq current (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2841 children (cdr children))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2842 (when (widget-apply (widget-get current :button) :value-get)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2843 (setq found (widget-apply current :value-inline)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2844 children nil)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2845 found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2846
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2847 (defun widget-radio-value-set (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2848 ;; We can't just delete and recreate a radio widget, since children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2849 ;; can be added after the original creation and won't be recreated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2850 ;; by `:create'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2851 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2852 current found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2853 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2854 (setq current (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2855 children (cdr children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2856 (let* ((button (widget-get current :button))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2857 (match (and (not found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2858 (widget-apply current :match value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2859 (widget-value-set button match)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2860 (if match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2861 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2862 (widget-value-set current value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2863 (widget-apply current :activate))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2864 (widget-apply current :deactivate))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2865 (setq found (or found match))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2866
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2867 (defun widget-radio-validate (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2868 ;; Valid if we have made a valid choice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2869 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2870 current found button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2871 (while (and children (not found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2872 (setq current (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2873 children (cdr children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2874 button (widget-get current :button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2875 found (widget-apply button :value-get)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2876 (if found
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2877 (widget-apply current :validate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2878 widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2879
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2880 (defun widget-radio-action (widget child event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2881 ;; Check if a radio button was pressed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2882 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2883 (buttons (widget-get widget :buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2884 current)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2885 (when (memq child buttons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2886 (while children
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2887 (setq current (car children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2888 children (cdr children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2889 (let* ((button (widget-get current :button)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2890 (cond ((eq child button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2891 (widget-value-set button t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2892 (widget-apply current :activate))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2893 ((widget-value button)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2894 (widget-value-set button nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2895 (widget-apply current :deactivate)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2896 ;; Pass notification to parent.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2897 (widget-apply widget :notify child event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2898
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2899 ;;; The `insert-button' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2900
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2901 (define-widget 'insert-button 'push-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2902 "An insert button for the `editable-list' widget."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2903 :tag "INS"
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2904 :help-echo "Insert a new item into the list at this position."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2905 :action 'widget-insert-button-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2906
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2907 (defun widget-insert-button-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2908 ;; Ask the parent to insert a new item.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2909 (widget-apply (widget-get widget :parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2910 :insert-before (widget-get widget :widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2911
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2912 ;;; The `delete-button' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2913
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2914 (define-widget 'delete-button 'push-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2915 "A delete button for the `editable-list' widget."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2916 :tag "DEL"
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
2917 :help-echo "Delete this item from the list."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2918 :action 'widget-delete-button-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2919
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2920 (defun widget-delete-button-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2921 ;; Ask the parent to insert a new item.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2922 (widget-apply (widget-get widget :parent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2923 :delete-at (widget-get widget :widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2924
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2925 ;;; The `editable-list' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2926
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2927 (defcustom widget-editable-list-gui nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2928 "If non nil, use GUI push-buttons in editable list when available."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2929 :type 'boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2930 :group 'widgets)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2931
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2932 (define-widget 'editable-list 'default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2933 "A variable list of widgets of the same type."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2934 :convert-widget 'widget-types-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2935 :offset 12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2936 :format "%v%i\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2937 :format-handler 'widget-editable-list-format-handler
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2938 :entry-format "%i %d %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2939 :menu-tag "editable-list"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2940 :value-create 'widget-editable-list-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2941 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2942 :value-get 'widget-editable-list-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2943 :validate 'widget-children-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2944 :match 'widget-editable-list-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2945 :match-inline 'widget-editable-list-match-inline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2946 :insert-before 'widget-editable-list-insert-before
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2947 :delete-at 'widget-editable-list-delete-at)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2948
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2949 (defun widget-editable-list-format-handler (widget escape)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2950 ;; We recognize the insert button.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2951 (let ((widget-push-button-gui widget-editable-list-gui))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2952 (cond ((eq escape ?i)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2953 (and (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2954 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2955 (apply 'widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2956 widget 'insert-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2957 (widget-get widget :append-button-args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2958 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2959 (widget-default-format-handler widget escape)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2960
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2961 (defun widget-editable-list-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2962 ;; Insert all values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2963 (let* ((value (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2964 (type (nth 0 (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2965 children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2966 (widget-put widget :value-pos (copy-marker (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2967 (set-marker-insertion-type (widget-get widget :value-pos) t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2968 (while value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2969 (let ((answer (widget-match-inline type value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2970 (if answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2971 (setq children (cons (widget-editable-list-entry-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2972 widget
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
2973 (if (widget-get type :inline)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2974 (car answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2975 (car (car answer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2976 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2977 children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2978 value (cdr answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2979 (setq value nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2980 (widget-put widget :children (nreverse children))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2981
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2982 (defun widget-editable-list-value-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2983 ;; Get value of the child widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2984 (apply 'append (mapcar (lambda (child) (widget-apply child :value-inline))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2985 (widget-get widget :children))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2986
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2987 (defun widget-editable-list-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2988 ;; Value must be a list and all the members must match the type.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2989 (and (listp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2990 (null (cdr (widget-editable-list-match-inline widget value)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2991
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2992 (defun widget-editable-list-match-inline (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2993 (let ((type (nth 0 (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2994 (ok t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2995 found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2996 (while (and value ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2997 (let ((answer (widget-match-inline type value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2998 (if answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2999 (setq found (append found (car answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3000 value (cdr answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3001 (setq ok nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3002 (cons found value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3003
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3004 (defun widget-editable-list-insert-before (widget before)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3005 ;; Insert a new child in the list of children.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3006 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3007 (let ((children (widget-get widget :children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3008 (inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3009 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3010 after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3011 (cond (before
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3012 (goto-char (widget-get before :entry-from)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3013 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3014 (goto-char (widget-get widget :value-pos))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3015 (let ((child (widget-editable-list-entry-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3016 widget nil nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3017 (when (< (widget-get child :entry-from) (widget-get widget :from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3018 (set-marker (widget-get widget :from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3019 (widget-get child :entry-from)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3020 (if (eq (car children) before)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3021 (widget-put widget :children (cons child children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3022 (while (not (eq (car (cdr children)) before))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3023 (setq children (cdr children)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3024 (setcdr children (cons child (cdr children)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3025 (widget-setup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3026 (widget-apply widget :notify widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3027
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3028 (defun widget-editable-list-delete-at (widget child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3029 ;; Delete child from list of children.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3030 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3031 (let ((buttons (copy-sequence (widget-get widget :buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3032 button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3033 (inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3034 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3035 after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3036 (while buttons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3037 (setq button (car buttons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3038 buttons (cdr buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3039 (when (eq (widget-get button :widget) child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3040 (widget-put widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3041 :buttons (delq button (widget-get widget :buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3042 (widget-delete button))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3043 (let ((entry-from (widget-get child :entry-from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3044 (entry-to (widget-get child :entry-to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3045 (inhibit-read-only t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3046 before-change-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3047 after-change-functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3048 (widget-delete child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3049 (delete-region entry-from entry-to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3050 (set-marker entry-from nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3051 (set-marker entry-to nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3052 (widget-put widget :children (delq child (widget-get widget :children))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3053 (widget-setup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3054 (widget-apply widget :notify widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3055
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3056 (defun widget-editable-list-entry-create (widget value conv)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3057 ;; Create a new entry to the list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3058 (let ((type (nth 0 (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3059 (widget-push-button-gui widget-editable-list-gui)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3060 child delete insert)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3061 (widget-specify-insert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3062 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3063 (and (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3064 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3065 (insert (widget-get widget :entry-format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3066 ;; Parse % escapes in format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3067 (while (re-search-forward "%\\(.\\)" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3068 (let ((escape (aref (match-string 1) 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3069 (replace-match "" t t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3070 (cond ((eq escape ?%)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3071 (insert ?%))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3072 ((eq escape ?i)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3073 (setq insert (apply 'widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3074 widget 'insert-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3075 (widget-get widget :insert-button-args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3076 ((eq escape ?d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3077 (setq delete (apply 'widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3078 widget 'delete-button
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3079 (widget-get widget :delete-button-args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3080 ((eq escape ?v)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3081 (if conv
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3082 (setq child (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3083 widget type value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3084 (setq child (widget-create-child-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3085 widget type (widget-default-get type)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3086 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3087 (signal 'error (list "Unknown escape" escape))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3088 (widget-put widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3089 :buttons (cons delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3090 (cons insert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3091 (widget-get widget :buttons))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3092 (let ((entry-from (copy-marker (point-min)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3093 (entry-to (copy-marker (point-max))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3094 (set-marker-insertion-type entry-from t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3095 (set-marker-insertion-type entry-to nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3096 (widget-put child :entry-from entry-from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3097 (widget-put child :entry-to entry-to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3098 (widget-put insert :widget child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3099 (widget-put delete :widget child)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3100 child))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3102 ;;; The `group' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3104 (define-widget 'group 'default
652
2cf5d151eeb9 [xemacs-hg @ 2001-08-26 10:25:11 by stephent]
stephent
parents: 454
diff changeset
3105 "A widget which groups other widgets inside."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3106 :convert-widget 'widget-types-convert-widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3107 :format "%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3108 :value-create 'widget-group-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3109 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3110 :value-get 'widget-editable-list-value-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3111 :default-get 'widget-group-default-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3112 :validate 'widget-children-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3113 :match 'widget-group-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3114 :match-inline 'widget-group-match-inline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3115
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3116 (defun widget-group-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3117 ;; Create each component.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3118 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3119 (value (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3120 arg answer children)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3121 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3122 (setq arg (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3123 args (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3124 answer (widget-match-inline arg value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3125 value (cdr answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3126 (and (eq (preceding-char) ?\n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3127 (widget-get widget :indent)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3128 (insert-char ?\ (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3129 (push (cond ((null answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3130 (widget-create-child widget arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3131 ((widget-get arg :inline)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3132 (widget-create-child-value widget arg (car answer)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3133 (t
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3134 (widget-create-child-value widget arg (car (car answer)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3135 children))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3136 (widget-put widget :children (nreverse children))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3137
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3138 (defun widget-group-default-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3139 ;; Get the default of the components.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3140 (mapcar 'widget-default-get (widget-get widget :args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3141
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3142 (defun widget-group-match (widget values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3143 ;; Match if the components match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3144 (and (listp values)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3145 (let ((match (widget-group-match-inline widget values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3146 (and match (null (cdr match))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3147
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3148 (defun widget-group-match-inline (widget vals)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3149 ;; Match if the components match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3150 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3151 argument answer found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3152 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3153 (setq argument (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3154 args (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3155 answer (widget-match-inline argument vals))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3156 (if answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3157 (setq vals (cdr answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3158 found (append found (car answer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3159 (setq vals nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3160 args nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3161 (if answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3162 (cons found vals)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3163 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3164
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3165 ;;; The `visibility' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3166
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3167 (define-widget 'visibility 'item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3168 "An indicator and manipulator for hidden items."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3169 :format "%[%v%]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3170 :button-prefix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3171 :button-suffix ""
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3172 :on "Hide"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3173 :off "Show"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3174 :value-create 'widget-visibility-value-create
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3175 :action 'widget-toggle-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3176 :match (lambda (widget value) t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3178 (defun widget-visibility-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3179 ;; Insert text representing the `on' and `off' states.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3180 (let ((on (widget-get widget :on))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3181 (off (widget-get widget :off)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3182 (if on
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3183 (setq on (concat widget-push-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3184 on
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3185 widget-push-button-suffix))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3186 (setq on ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3187 (if off
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3188 (setq off (concat widget-push-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3189 off
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3190 widget-push-button-suffix))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3191 (setq off ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3192 (if (widget-value widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3193 (widget-glyph-insert widget on '("down" "down-pushed"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3194 (widget-glyph-insert widget off '("right" "right-pushed")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3195
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3196 ;;; The `documentation-link' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3197 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3198 ;; This is a helper widget for `documentation-string'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3199
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3200 (define-widget 'documentation-link 'link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3201 "Link type used in documentation strings."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3202 :tab-order -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3203 :help-echo 'widget-documentation-link-echo-help
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3204 :action 'widget-documentation-link-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3206 (defun widget-documentation-link-echo-help (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3207 "Tell what this link will describe."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3208 (concat "Describe the `" (widget-get widget :value) "' symbol."))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3209
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3210 (defun widget-documentation-link-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3211 "Display documentation for WIDGET's value. Ignore optional argument EVENT."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3212 (let* ((string (widget-get widget :value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3213 (symbol (intern string)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3214 (if (and (fboundp symbol) (boundp symbol))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3215 ;; If there are two doc strings, give the user a way to pick one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3216 (apropos (concat "\\`" (regexp-quote string) "\\'"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3217 (if (fboundp symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3218 (describe-function symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3219 (describe-variable symbol)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3220
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3221 (defcustom widget-documentation-links t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3222 "Add hyperlinks to documentation strings when non-nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3223 :type 'boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3224 :group 'widget-documentation)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3226 (defcustom widget-documentation-link-regexp "`\\([^\n`' ]+\\)'"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3227 "Regexp for matching potential links in documentation strings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3228 The first group should be the link itself."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3229 :type 'regexp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3230 :group 'widget-documentation)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3231
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3232 (defcustom widget-documentation-link-p 'intern-soft
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3233 "Predicate used to test if a string is useful as a link.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3234 The value should be a function. The function will be called one
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3235 argument, a string, and should return non-nil if there should be a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3236 link for that string."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3237 :type 'function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3238 :options '(widget-documentation-link-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3239 :group 'widget-documentation)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3240
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3241 (defcustom widget-documentation-link-type 'documentation-link
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3242 "Widget type used for links in documentation strings."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3243 :type 'symbol
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3244 :group 'widget-documentation)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3245
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3246 (defun widget-documentation-link-add (widget from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3247 (widget-specify-doc widget from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3248 (when widget-documentation-links
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3249 (let ((regexp widget-documentation-link-regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3250 (predicate widget-documentation-link-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3251 (type widget-documentation-link-type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3252 (buttons (widget-get widget :buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3253 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3254 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3255 (while (re-search-forward regexp to t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3256 (let ((name (match-string 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3257 (begin (match-beginning 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3258 (end (match-end 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3259 (when (funcall predicate name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3260 (push (widget-convert-button type begin end :value name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3261 buttons)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3262 (widget-put widget :buttons buttons)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3263 (let ((indent (widget-get widget :indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3264 (when (and indent (not (zerop indent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3265 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3266 (save-restriction
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3267 (narrow-to-region from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3268 (goto-char (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3269 (while (search-forward "\n" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3270 (insert-char ?\ indent)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3271
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3272 ;;; The `documentation-string' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3273
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3274 (define-widget 'documentation-string 'item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3275 "A documentation string."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3276 :format "%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3277 :action 'widget-documentation-string-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3278 :value-delete 'widget-children-value-delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3279 :value-create 'widget-documentation-string-value-create)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3280
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3281 (defun widget-documentation-string-value-create (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3282 ;; Insert documentation string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3283 (let ((doc (widget-value widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3284 (indent (widget-get widget :indent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3285 (shown (widget-get (widget-get widget :parent) :documentation-shown))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3286 (start (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3287 (if (string-match "\n" doc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3288 (let ((before (substring doc 0 (match-beginning 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3289 (after (substring doc (match-beginning 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3290 buttons)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3291 (insert before ?\ )
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3292 (widget-documentation-link-add widget start (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3293 (push (widget-create-child-and-convert
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3294 widget 'visibility
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3295 :help-echo (lambda (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3296 (concat
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3297 (if (widget-value widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3298 "Hide" "Show")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3299 " the rest of the documentation"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3300 :off "More"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3301 :action 'widget-parent-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3302 shown)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3303 buttons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3304 (when shown
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3305 (setq start (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3306 (when indent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3307 (insert-char ?\ indent))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3308 (insert after)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3309 (widget-documentation-link-add widget start (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3310 (widget-put widget :buttons buttons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3311 (insert doc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3312 (widget-documentation-link-add widget start (point))))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3313 (insert ?\n))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3314
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3315 (defun widget-documentation-string-action (widget &rest ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3316 ;; Toggle documentation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3317 (let ((parent (widget-get widget :parent)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3318 (widget-put parent :documentation-shown
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3319 (not (widget-get parent :documentation-shown))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3320 ;; Redraw.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3321 (widget-value-set widget (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3322
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3323
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3324 ;;; The Sexp Widgets.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3325
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3326 (define-widget 'sexp 'editable-field
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3327 "An arbitrary Lisp expression."
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3328 :tag "Lisp expression"
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3329 :format "%{%t%}: %v"
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3330 :value nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3331 :validate 'widget-sexp-validate
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3332 :match (lambda (widget value) t)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3333 :value-to-internal 'widget-sexp-value-to-internal
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3334 :value-to-external (lambda (widget value) (read value))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3335 :prompt-history 'widget-sexp-prompt-value-history
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3336 :prompt-value 'widget-sexp-prompt-value)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3337
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3338 (defun widget-sexp-value-to-internal (widget value)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3339 ;; Use cl-prettyprint for printer representation.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3340 (let ((pp (if (symbolp value)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3341 (prin1-to-string value)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3342 (widget-prettyprint-to-string value))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3343 (if (> (length pp) 40)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3344 (concat "\n" pp)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3345 pp)))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3346
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3347 (defun widget-sexp-validate (widget)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3348 ;; Valid if we can read the string and there is no junk left after it.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3349 (save-excursion
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3350 (let ((buffer (set-buffer (get-buffer-create " *Widget Scratch*"))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3351 (erase-buffer)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3352 (insert (widget-apply widget :value-get))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3353 (goto-char (point-min))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3354 (condition-case data
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3355 (let ((value (read buffer)))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3356 (if (eobp)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3357 (if (widget-apply widget :match value)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3358 nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3359 (widget-put widget :error (widget-get widget :type-error))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3360 widget)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3361 (widget-put widget
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3362 :error (format "Junk at end of expression: %s"
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3363 (buffer-substring (point)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3364 (point-max))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3365 widget))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3366 (error (widget-put widget :error (error-message-string data))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3367 widget)))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3368
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3369 (defvar widget-sexp-prompt-value-history nil
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3370 "History of input to `widget-sexp-prompt-value'.")
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3371
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3372 (defun widget-sexp-prompt-value (widget prompt value unbound)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3373 ;; Read an arbitrary sexp.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3374 (let ((found (read-string prompt
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3375 (if unbound nil (cons (prin1-to-string value) 0))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3376 (widget-get widget :prompt-history))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3377 (save-excursion
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3378 (let ((buffer (set-buffer (get-buffer-create " *Widget Scratch*"))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3379 (erase-buffer)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3380 (insert found)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3381 (goto-char (point-min))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3382 (let ((answer (read buffer)))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3383 (unless (eobp)
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3384 (signal 'error
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3385 (list "Junk at end of expression"
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3386 (buffer-substring (point) (point-max)))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3387 answer)))))
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3388
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3389 ;; Various constant sexps.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3390
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3391 (define-widget 'const 'item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3392 "An immutable sexp."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3393 :prompt-value 'widget-const-prompt-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3394 :format "%t\n%d")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3395
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3396 (defun widget-const-prompt-value (widget prompt value unbound)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3397 ;; Return the value of the const.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3398 (widget-value widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3400 (define-widget 'function-item 'const
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3401 "An immutable function name."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3402 :format "%v\n%h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3403 :documentation-property (lambda (symbol)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3404 (condition-case nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3405 (documentation symbol t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3406 (error nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3407
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3408 (define-widget 'variable-item 'const
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3409 "An immutable variable name."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3410 :format "%v\n%h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3411 :documentation-property 'variable-documentation)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3412
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3413 (define-widget 'other 'sexp
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3414 "Matches any value, but doesn't let the user edit the value.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3415 This is useful as last item in a `choice' widget.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3416 You should use this widget type with a default value,
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3417 as in (other DEFAULT) or (other :tag \"NAME\" DEFAULT).
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3418 If the user selects this alternative, that specifies DEFAULT
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3419 as the value."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3420 :tag "Other"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3421 :format "%t%n"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3422 :value 'other)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3423
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3424 (defvar widget-string-prompt-value-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3425 "History of input to `widget-string-prompt-value'.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3426
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3427 (define-widget 'string 'editable-field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3428 "A string"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3429 :tag "String"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3430 :format "%{%t%}: %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3431 :complete-function 'ispell-complete-word
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3432 :prompt-history 'widget-string-prompt-value-history)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3434 (define-widget 'regexp 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3435 "A regular expression."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3436 :match 'widget-regexp-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3437 :validate 'widget-regexp-validate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3438 ;; Doesn't work well with terminating newline.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3439 ;; :value-face 'widget-single-line-field-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3440 :tag "Regexp")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3441
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3442 (defun widget-regexp-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3443 ;; Match valid regexps.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3444 (and (stringp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3445 (condition-case nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3446 (prog1 t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3447 (string-match value ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3448 (error nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3449
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3450 (defun widget-regexp-validate (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3451 "Check that the value of WIDGET is a valid regexp."
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3452 (condition-case data
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3453 (prog1 nil
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3454 (string-match (widget-value widget) ""))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3455 (error (widget-put widget :error (error-message-string data))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3456 widget)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3457
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3458 (define-widget 'file 'string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3459 "A file widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3460 It will read a file name from the minibuffer when invoked."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3461 :complete-function 'widget-file-complete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3462 :prompt-value 'widget-file-prompt-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3463 :format "%{%t%}: %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3464 ;; Doesn't work well with terminating newline.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3465 ;; :value-face 'widget-single-line-field-face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3466 :tag "File")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3467
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3468 (defun widget-file-complete ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3469 "Perform completion on file name preceding point."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3470 (interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3471 (let* ((end (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3472 (beg (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3473 (skip-chars-backward "^ ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3474 (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3475 (pattern (buffer-substring beg end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3476 (name-part (file-name-nondirectory pattern))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3477 (directory (file-name-directory pattern))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3478 (completion (file-name-completion name-part directory)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3479 (cond ((eq completion t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3480 ((null completion)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3481 (message "Can't find completion for \"%s\"" pattern)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3482 (ding))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3483 ((not (string= name-part completion))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3484 (delete-region beg end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3485 (insert (expand-file-name completion directory)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3486 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3487 (message "Making completion list...")
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3488 (with-output-to-temp-buffer "*Completions*"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3489 (display-completion-list
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3490 (sort (file-name-all-completions name-part directory)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3491 'string<)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3492 (message "Making completion list...%s" "done")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3493
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3494 (defun widget-file-prompt-value (widget prompt value unbound)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3495 ;; Read file from minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3496 (abbreviate-file-name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3497 (if unbound
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3498 (read-file-name prompt)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3499 (let ((prompt2 (format "%s (default %s) " prompt value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3500 (dir (file-name-directory value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3501 (file (file-name-nondirectory value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3502 (must-match (widget-get widget :must-match)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3503 (read-file-name prompt2 dir nil must-match file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3504
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3505 ;;;(defun widget-file-action (widget &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3506 ;;; ;; Read a file name from the minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3507 ;;; (let* ((value (widget-value widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3508 ;;; (dir (file-name-directory value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3509 ;;; (file (file-name-nondirectory value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3510 ;;; (menu-tag (widget-apply widget :menu-tag-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3511 ;;; (must-match (widget-get widget :must-match))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3512 ;;; (answer (read-file-name (concat menu-tag ": (default `" value "') ")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3513 ;;; dir nil must-match file)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3514 ;;; (widget-value-set widget (abbreviate-file-name answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3515 ;;; (widget-setup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3516 ;;; (widget-apply widget :notify widget event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3517
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3518 ;; Fixme: use file-name-as-directory.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3519 (define-widget 'directory 'file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3520 "A directory widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3521 It will read a directory name from the minibuffer when invoked."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3522 :tag "Directory")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3523
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3524 (defvar widget-symbol-prompt-value-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3525 "History of input to `widget-symbol-prompt-value'.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3526
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3527 (define-widget 'symbol 'editable-field
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3528 "A Lisp symbol."
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3529 :value t
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3530 :tag "Symbol"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3531 :format "%{%t%}: %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3532 :match (lambda (widget value) (symbolp value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3533 :complete-function 'lisp-complete-symbol
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3534 :prompt-internal 'widget-symbol-prompt-internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3535 :prompt-match 'symbolp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3536 :prompt-history 'widget-symbol-prompt-value-history
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3537 :value-to-internal (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3538 (if (symbolp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3539 (symbol-name value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3540 value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3541 :value-to-external (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3542 (if (stringp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3543 (intern value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3544 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3545
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3546 (defun widget-symbol-prompt-internal (widget prompt initial history)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3547 ;; Read file from minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3548 (let ((answer (completing-read prompt obarray
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3549 (widget-get widget :prompt-match)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3550 nil initial history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3551 (if (and (stringp answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3552 (not (zerop (length answer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3553 answer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3554 (error "No value"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3555
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3556 (defvar widget-function-prompt-value-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3557 "History of input to `widget-function-prompt-value'.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3558
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3559 (define-widget 'function 'sexp
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3560 "A Lisp function."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3561 :complete-function 'lisp-complete-symbol
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3562 :prompt-value 'widget-field-prompt-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3563 :prompt-internal 'widget-symbol-prompt-internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3564 :prompt-match 'fboundp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3565 :prompt-history 'widget-function-prompt-value-history
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3566 :action 'widget-field-action
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3567 :tag "Function")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3568
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3569 (defvar widget-variable-prompt-value-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3570 "History of input to `widget-variable-prompt-value'.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3571
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3572 (define-widget 'variable 'symbol
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3573 ;; Should complete on variables.
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3574 "A Lisp variable."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3575 :prompt-match 'boundp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3576 :prompt-history 'widget-variable-prompt-value-history
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3577 :tag "Variable")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3578
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3579 ;; This part issues a warning when compiling without Mule. Is there a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3580 ;; way of shutting it up?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3581 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3582 ;; OK, I'll simply comment the whole thing out, until someone decides
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3583 ;; to do something with it.
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3584
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3585 ;; OK, _I_'ll simply comment it back in, so somebody will get irritated and
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3586 ;; do something about it.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3587
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3588 (defvar widget-coding-system-prompt-value-history nil
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3589 "History of input to `widget-coding-system-prompt-value'.")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3590
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3591 (define-widget 'coding-system 'symbol
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3592 "A MULE coding-system."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3593 :format "%{%t%}: %v"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3594 :tag "Coding system"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3595 :prompt-history 'widget-coding-system-prompt-value-history
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3596 :prompt-value 'widget-coding-system-prompt-value
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3597 :action 'widget-coding-system-action)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3598
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3599 (defun widget-coding-system-prompt-value (widget prompt value unbound)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3600 ;; Read coding-system from minibuffer.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3601 (intern
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3602 (completing-read (format "%s (default %s) " prompt value)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3603 (mapcar (lambda (sym)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3604 (list (symbol-name sym)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3605 (coding-system-list)))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3606
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3607 (defun widget-coding-system-action (widget &optional event)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3608 ;; Read a file name from the minibuffer.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3609 (let ((answer
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3610 (widget-coding-system-prompt-value
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3611 widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3612 (widget-apply widget :menu-tag-get)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3613 (widget-value widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3614 t)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3615 (widget-value-set widget answer)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3616 (widget-apply widget :notify widget event)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3617 (widget-setup)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3619 (define-widget 'restricted-sexp 'sexp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3620 "A Lisp expression restricted to values that match.
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3621
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3622 Either the `:match' or the `:match-alternatives' property must be defined."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3623 :type-error "The specified value is not valid"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3624 :match 'widget-restricted-sexp-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3625 :value-to-internal (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3626 (if (widget-apply widget :match value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3627 (prin1-to-string value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3628 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3629
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3630 (defun widget-restricted-sexp-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3631 (let ((alternatives (widget-get widget :match-alternatives))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3632 matched)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3633 (while (and alternatives (not matched))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3634 (if (cond ((functionp (car alternatives))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3635 (funcall (car alternatives) value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3636 ((and (consp (car alternatives))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3637 (eq (car (car alternatives)) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3638 (eq value (nth 1 (car alternatives)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3639 (setq matched t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3640 (setq alternatives (cdr alternatives)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3641 matched))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3642
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3643 (define-widget 'integer 'restricted-sexp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3644 "An integer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3645 :tag "Integer"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3646 :value 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3647 :type-error "This field should contain an integer"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3648 :match-alternatives '(integerp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3649
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3650 (define-widget 'number 'restricted-sexp
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3651 "A number (floating point or integer)."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3652 :tag "Number"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3653 :value 0.0
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3654 :type-error "This field should contain a number (floating point or integer)"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3655 :match-alternatives '(numberp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3656
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3657 (define-widget 'float 'restricted-sexp
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3658 "A floating point number."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3659 :tag "Floating point number"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3660 :value 0.0
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3661 :type-error "This field should contain a floating point number"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3662 :match-alternatives '(floatp))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3663
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3664 (define-widget 'character 'editable-field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3665 "A character."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3666 :tag "Character"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3667 :value ?\0
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3668 :size 1
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3669 :format "%{%t%}: %v"
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3670 ;; #### This is incorrect for Mule.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3671 :valid-regexp "\\`[\0-\377]\\'"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3672 :error "This field should contain a single character"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3673 :value-to-internal (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3674 (if (stringp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3675 value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3676 (char-to-string value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3677 :value-to-external (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3678 (if (stringp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3679 (aref value 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3680 value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3681 :match (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3682 (characterp value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3683
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3684 (define-widget 'list 'group
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3685 "A Lisp list of fixed length with fixed type for each element."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3686 :tag "List"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3687 :format "%{%t%}:\n%v")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3688
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3689 (define-widget 'vector 'group
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3690 "A Lisp vector of fixed length with fixed type for each element."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3691 :tag "Vector"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3692 :format "%{%t%}:\n%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3693 :match 'widget-vector-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3694 :value-to-internal (lambda (widget value) (append value nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3695 :value-to-external (lambda (widget value) (vconcat value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3696
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3697 (defun widget-vector-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3698 (and (vectorp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3699 (widget-group-match widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3700 (widget-apply widget :value-to-internal value))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3701
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3702 (define-widget 'cons 'group
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3703 "A cons-cell."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3704 :tag "Cons-cell"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3705 :format "%{%t%}:\n%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3706 :match 'widget-cons-match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3707 :value-to-internal (lambda (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3708 (list (car value) (cdr value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3709 :value-to-external (lambda (widget value)
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3710 (cons (nth 0 value) (nth 1 value))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3711
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3712 (defun widget-cons-match (widget value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3713 (and (consp value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3714 (widget-group-match widget
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3715 (widget-apply widget :value-to-internal value))))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3716
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3717 ;;; The `plist' Widget.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3718 ;;
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3719 ;; Property lists.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3720
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3721 (define-widget 'plist 'list
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3722 "A property list."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3723 :key-type '(symbol :tag "Key")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3724 :value-type '(sexp :tag "Value")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3725 :convert-widget 'widget-plist-convert-widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3726 :tag "Plist")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3727
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3728 (defvar widget-plist-value-type) ;Dynamic variable
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3729
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3730 (defun widget-plist-convert-widget (widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3731 ;; Handle `:options'.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3732 (let* ((options (widget-get widget :options))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3733 (widget-plist-value-type (widget-get widget :value-type))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3734 (other `(editable-list :inline t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3735 (group :inline t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3736 ,(widget-get widget :key-type)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3737 ,widget-plist-value-type)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3738 (args (if options
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3739 (list `(checklist :inline t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3740 :greedy t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3741 ,@(mapcar 'widget-plist-convert-option
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3742 options))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3743 other)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3744 (list other))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3745 (widget-put widget :args args)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3746 widget))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3747
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3748 (defun widget-plist-convert-option (option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3749 ;; Convert a single plist option.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3750 (let (key-type value-type)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3751 (if (listp option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3752 (let ((key (nth 0 option)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3753 (setq value-type (nth 1 option))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3754 (if (listp key)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3755 (setq key-type key)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3756 (setq key-type `(const ,key))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3757 (setq key-type `(const ,option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3758 value-type widget-plist-value-type))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3759 `(group :format "Key: %v" :inline t ,key-type ,value-type)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3760
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3761
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3762 ;;; The `alist' Widget.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3763 ;;
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3764 ;; Association lists.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3765
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3766 (define-widget 'alist 'list
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3767 "An association list."
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3768 :key-type '(sexp :tag "Key")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3769 :value-type '(sexp :tag "Value")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3770 :convert-widget 'widget-alist-convert-widget
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3771 :tag "Alist")
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3772
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3773 (defvar widget-alist-value-type) ;Dynamic variable
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3774
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3775 (defun widget-alist-convert-widget (widget)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3776 ;; Handle `:options'.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3777 (let* ((options (widget-get widget :options))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3778 (widget-alist-value-type (widget-get widget :value-type))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3779 (other `(editable-list :inline t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3780 (cons :format "%v"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3781 ,(widget-get widget :key-type)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3782 ,widget-alist-value-type)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3783 (args (if options
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3784 (list `(checklist :inline t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3785 :greedy t
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3786 ,@(mapcar 'widget-alist-convert-option
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3787 options))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3788 other)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3789 (list other))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3790 (widget-put widget :args args)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3791 widget))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3792
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3793 (defun widget-alist-convert-option (option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3794 ;; Convert a single alist option.
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3795 (let (key-type value-type)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3796 (if (listp option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3797 (let ((key (nth 0 option)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3798 (setq value-type (nth 1 option))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3799 (if (listp key)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3800 (setq key-type key)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3801 (setq key-type `(const ,key))))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3802 (setq key-type `(const ,option)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3803 value-type widget-alist-value-type))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3804 `(cons :format "Key: %v" ,key-type ,value-type)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3805
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3806
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3807 (define-widget 'choice 'menu-choice
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3808 "A union of several sexp types."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3809 :tag "Choice"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3810 :format "%{%t%}: %[Value Menu%] %v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3811 :button-prefix 'widget-push-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3812 :button-suffix 'widget-push-button-suffix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3813 :prompt-value 'widget-choice-prompt-value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3814
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3815 (defun widget-choice-prompt-value (widget prompt value unbound)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3816 "Make a choice."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3817 (let ((args (widget-get widget :args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3818 (completion-ignore-case (widget-get widget :case-fold))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3819 current choices old)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3820 ;; Find the first arg that matches VALUE.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3821 (let ((look args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3822 (while look
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3823 (if (widget-apply (car look) :match value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3824 (setq old (car look)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3825 look nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3826 (setq look (cdr look)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3827 ;; Find new choice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3828 (setq current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3829 (cond ((= (length args) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3830 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3831 ((= (length args) 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3832 (nth 0 args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3833 ((and (= (length args) 2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3834 (memq old args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3835 (if (eq old (nth 0 args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3836 (nth 1 args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3837 (nth 0 args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3838 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3839 (while args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3840 (setq current (car args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3841 args (cdr args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3842 (setq choices
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3843 (cons (cons (widget-apply current :menu-tag-get)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3844 current)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3845 choices)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3846 (let ((val (completing-read prompt choices nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3847 (if (stringp val)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3848 (let ((try (try-completion val choices)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3849 (when (stringp try)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3850 (setq val try))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3851 (cdr (assoc val choices)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3852 nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3853 (if current
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3854 (widget-prompt-value current prompt nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3855 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3856
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3857 (define-widget 'radio 'radio-button-choice
1362
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3858 "A set widget, selecting exactly one from many.
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3859
cfe4bcb9bdd4 [xemacs-hg @ 2003-03-18 06:58:19 by stephent]
stephent
parents: 1333
diff changeset
3860 The parent of several `radio-button' widgets, one for each option."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3861 :tag "Choice"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3862 :format "%{%t%}:\n%v"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3863 :prompt-value 'widget-choice-prompt-value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3864
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3865 (define-widget 'repeat 'editable-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3866 "A variable length homogeneous list."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3867 :tag "Repeat"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3868 :format "%{%t%}:\n%v%i\n")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3869
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3870 (define-widget 'set 'checklist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3871 "A list of members from a fixed set."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3872 :tag "Set"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3873 :format "%{%t%}:\n%v")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3874
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3875 (define-widget 'boolean 'toggle
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3876 "To be nil or non-nil, that is the question."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3877 :tag "Boolean"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3878 :prompt-value 'widget-boolean-prompt-value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3879 :button-prefix 'widget-push-button-prefix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3880 :button-suffix 'widget-push-button-suffix
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3881 :format "%{%t%}: %[Toggle%] %v\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3882 :on "on (non-nil)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3883 :off "off (nil)")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3884
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3885 (defun widget-boolean-prompt-value (widget prompt value unbound)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3886 ;; Toggle a boolean.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3887 (y-or-n-p prompt))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3888
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3889 ;;; The `color' Widget.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3890
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3891 ;; Fixme: match
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3892 (define-widget 'color 'editable-field
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3893 "Choose a color name (with sample)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3894 :format "%[%t%]: %v (%{sample%})\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3895 :size 10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3896 :tag "Color"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3897 :value "black"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3898 :complete 'widget-color-complete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3899 :sample-face-get 'widget-color-sample-face-get
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3900 :notify 'widget-color-notify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3901 :action 'widget-color-action)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3902
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3903 (defun widget-color-complete (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3904 "Complete the color in WIDGET."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3905 (let* ((prefix (buffer-substring-no-properties (widget-field-start widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3906 (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3907 (list (read-color-completion-table))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3908 (completion (try-completion prefix list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3909 (cond ((eq completion t)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3910 (message "Exact match."))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3911 ((null completion)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3912 (error "Can't find completion for \"%s\"" prefix))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3913 ((not (string-equal prefix completion))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3914 (insert (substring completion (length prefix))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3915 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3916 (message "Making completion list...")
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3917 (with-output-to-temp-buffer "*Completions*"
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3918 (display-completion-list (all-completions prefix list nil)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3919 (message "Making completion list...done")))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3920
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3921 (defun widget-color-sample-face-get (widget)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3922 (or (widget-get widget :sample-face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3923 (let ((color (widget-value widget))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3924 (face (make-face (gensym "sample-face-") nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3925 ;; Use the face object, not its name, to prevent lossage if gc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3926 ;; happens before applying the face.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3927 (widget-put widget :sample-face face)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3928 (and color
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3929 (not (equal color ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3930 (valid-color-name-p color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3931 (set-face-foreground face color))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3932 face)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3933
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3934 (defvar widget-color-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3935 "History of entered colors.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3936
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3937 (defun widget-color-action (widget &optional event)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3938 "Prompt for a color."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3939 (let* ((tag (widget-apply widget :menu-tag-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3940 (answer (read-color (concat tag ": "))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3941 (unless (zerop (length answer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3942 (widget-value-set widget answer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3943 (widget-setup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3944 (widget-apply widget :notify widget event))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3945
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3946 (defun widget-color-notify (widget child &optional event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3947 "Update the sample, and notify the parent."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3948 (let* ((face (widget-apply widget :sample-face-get))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3949 (color (widget-value widget)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3950 (if (valid-color-name-p color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3951 (set-face-foreground face color)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3952 (remove-face-property face 'foreground)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3953 (widget-default-notify widget child event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3954
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3955 ;;; The Help Echo
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3956
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3957 (defun widget-echo-help (pos)
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
3958 "Display the help-echo text for widget at POS."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3959 (let* ((widget (widget-at pos))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3960 (help-echo (and widget (widget-get widget :help-echo))))
1309
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3961 (if (functionp help-echo)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3962 (setq help-echo (funcall help-echo widget)))
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3963 (if (stringp help-echo)
00abb1091204 [xemacs-hg @ 2003-02-17 14:50:55 by stephent]
stephent
parents: 1173
diff changeset
3964 (display-message 'help-echo help-echo))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3965
1833
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3966 (define-widget 'lazy 'default
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3967 "Base widget for recursive datastructures.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3968
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3969 The `lazy' widget will, when instantiated, contain a single inferior
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3970 widget, of the widget type specified by the :type parameter. The
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3971 value of the `lazy' widget is the same as the value of the inferior
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3972 widget. When deriving a new widget from the 'lazy' widget, the :type
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3973 parameter is allowed to refer to the widget currently being defined,
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3974 thus allowing recursive datastructures to be described.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3975
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3976 The:type parameter takes the same arguments as the defcustom
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3977 parameter with the same name.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3978
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3979 Most composite widgets, i.e. widgets containing other widgets, does
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3980 not allow recursion. That is, when you define a new widget type, none
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3981 of the inferior widgets may be of the same type you are currently
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3982 defining.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3983
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3984 In Lisp, however, it is custom to define datastructures in terms of
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3985 themselves. A list, for example, is defined as either nil, or a cons
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3986 cell whose cdr itself is a list. The obvious way to translate this
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3987 into a widget type would be
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3988
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3989 (define-widget 'my-list 'choice
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3990 \"A list of sexps.\"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3991 :tag \"Sexp list\"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3992 :args '((const nil) (cons :value (nil) sexp my-list)))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3993
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3994 Here we attempt to define my-list as a choice of either the constant
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3995 nil, or a cons-cell containing a sexp and my-lisp. This will not work
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3996 because the `choice' widget does not allow recursion.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3997
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3998 Using the `lazy' widget you can overcome this problem, as in this
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
3999 example:
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4000
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4001 (define-widget 'sexp-list 'lazy
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4002 \"A list of sexps.\"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4003 :tag \"Sexp list\"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4004 :type '(choice (const nil) (cons :value (nil) sexp sexp-list)))"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4005 :format "%{%t%}: %v"
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4006 ;; We don't convert :type because we want to allow recursive
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4007 ;; datastructures. This is slow, so we should not create speed
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4008 ;; critical widgets by deriving from this.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4009 :convert-widget 'widget-value-convert-widget
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4010 :value-create 'widget-type-value-create
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4011 :value-delete 'widget-children-value-delete
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4012 :value-get 'widget-child-value-get
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4013 :value-inline 'widget-child-value-inline
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4014 :default-get 'widget-type-default-get
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4015 :match 'widget-type-match
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4016 :validate 'widget-child-validate)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4017
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4018 (defun widget-child-value-get (widget)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4019 "Get the value of the first member of :children in WIDGET."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4020 (widget-value (car (widget-get widget :children))))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4021
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4022 (defun widget-child-value-inline (widget)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4023 "Get the inline value of the first member of :children in WIDGET."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4024 (widget-apply (car (widget-get widget :children)) :value-inline))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4025
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4026 (defun widget-child-validate (widget)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4027 "The result of validating the first member of :children in WIDGET."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4028 (widget-apply (car (widget-get widget :children)) :validate))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4029
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4030 (defun widget-type-value-create (widget)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4031 "Convert and instantiate the value of the :type attribute of WIDGET.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4032 Store the newly created widget in the :children attribute.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4033
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4034 The value of the :type attribute should be an unconverted widget type."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4035 (let ((value (widget-get widget :value))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4036 (type (widget-get widget :type)))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4037 (widget-put widget :children
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4038 (list (widget-create-child-value widget
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4039 (widget-convert type)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4040 value)))))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4041
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4042 (defun widget-type-default-get (widget)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4043 "Get default value from the :type attribute of WIDGET.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4044
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4045 The value of the :type attribute should be an unconverted widget type."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4046 (widget-default-get (widget-convert (widget-get widget :type))))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4047
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4048 (defun widget-type-match (widget value)
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4049 "Non-nil if the :type value of WIDGET matches VALUE.
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4050
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4051 The value of the :type attribute should be an unconverted widget type."
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4052 (widget-apply (widget-convert (widget-get widget :type)) :match value))
eed841acc858 [xemacs-hg @ 2003-12-19 14:28:45 by youngs]
youngs
parents: 1736
diff changeset
4053
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4054 ;;; The End:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4055
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4056 (provide 'wid-edit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4057
1173
315720febed1 [xemacs-hg @ 2002-12-26 15:52:41 by stephent]
stephent
parents: 776
diff changeset
4058 ;;; wid-edit.el ends here