From 770a95e888849f0756c98079a90164b832b1825f Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Mon, 14 Nov 2016 14:43:10 +1100 Subject: Edit and search menu items now grey themselves out when appropriate --- src/adapad.adb | 47 ++++++++++++++++++++++++--------- src/fltk_binding/c_fl_menu.cpp | 15 +++++++++++ src/fltk_binding/c_fl_menu.h | 3 +++ src/fltk_binding/c_fl_text_buffer.cpp | 5 ++++ src/fltk_binding/c_fl_text_buffer.h | 1 + src/fltk_binding/fltk-text_buffers.adb | 15 +++++++++++ src/fltk_binding/fltk-text_buffers.ads | 5 ++++ src/fltk_binding/fltk-widgets-menus.adb | 47 +++++++++++++++++++++++++++++++++ src/fltk_binding/fltk-widgets-menus.ads | 14 ++++++++++ to_do.txt | 3 +-- 10 files changed, 140 insertions(+), 15 deletions(-) diff --git a/src/adapad.adb b/src/adapad.adb index dd5afd5..78b0684 100644 --- a/src/adapad.adb +++ b/src/adapad.adb @@ -11,9 +11,6 @@ with Windows.Replace; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; -with Ada.Text_IO; - - package body Adapad is @@ -306,11 +303,29 @@ package body Adapad is Deleted_Text : in String) is use type FLTK.Text_Buffers.Modification; + Bar : FLTK.Widgets.Menus.Menu_Cursor := Editor.Get_Menu_Bar; + Pop : FLTK.Widgets.Menus.Menu_Cursor := Editor.Get_Rightclick_Menu; begin if Action = FLTK.Text_Buffers.Insert or Action = FLTK.Text_Buffers.Delete then Changed := True; + Set_Title; + end if; + + if Buffer.Has_Selection then + Bar.Find_Item ("&Edit/Cu&t").Activate; + Bar.Find_Item ("&Edit/&Copy").Activate; + Bar.Find_Item ("&Edit/&Delete").Activate; + Pop.Find_Item ("Cu&t").Activate; + Pop.Find_Item ("&Copy").Activate; + Pop.Find_Item ("&Delete").Activate; + else + Bar.Find_Item ("&Edit/Cu&t").Deactivate; + Bar.Find_Item ("&Edit/&Copy").Deactivate; + Bar.Find_Item ("&Edit/&Delete").Deactivate; + Pop.Find_Item ("Cu&t").Deactivate; + Pop.Find_Item ("&Copy").Deactivate; + Pop.Find_Item ("&Delete").Deactivate; end if; - Set_Title; end Mod_CB; @@ -324,6 +339,7 @@ package body Adapad is Facing : in Windows.Find.Direction) is use type Windows.Find.Direction; + Bar : FLTK.Widgets.Menus.Menu_Cursor := Editor.Get_Menu_Bar; Current_Position, Select_Start, Select_End, Found_At : Natural; Was_Found : Boolean; begin @@ -352,12 +368,16 @@ package body Adapad is or else Buffer.Search_Backward (Buffer.Length, Item, Found_At, Match_Case); end if; - if Was_Found then + if Item /= "" and Was_Found then Buffer.Set_Selection (Found_At, Found_At + Item'Length); Editor.Set_Insert_Position (Found_At + Item'Length); Editor.Show_Insert_Position; + Bar.Find_Item ("&Search/Find &Next").Activate; + Bar.Find_Item ("&Search/Find &Previous").Activate; else FLTK.Dialogs.Alert ("No occurrences of '" & Item & "' found!"); + Bar.Find_Item ("&Search/Find &Next").Deactivate; + Bar.Find_Item ("&Search/Find &Previous").Deactivate; end if; end Do_Find_CB; @@ -514,6 +534,7 @@ package body Adapad is begin + -- definitely need to work out a better tabular structure for this code block declare use FLTK.Widgets.Menus; Bar : Menu_Cursor := Editor.Get_Menu_Bar; @@ -527,16 +548,16 @@ begin Bar.Add (Text => "&Edit", Flags => Flag_Submenu); Bar.Add ("Edit/&Undo", Undo_CB'Access, Mod_Ctrl + 'z', Flag_Divider); - Bar.Add ("Edit/Cu&t", Cut_CB'Access, Mod_Ctrl + 'x'); - Bar.Add ("Edit/&Copy", Copy_CB'Access, Mod_Ctrl + 'c'); + Bar.Add ("Edit/Cu&t", Cut_CB'Access, Mod_Ctrl + 'x', Flag_Inactive); + Bar.Add ("Edit/&Copy", Copy_CB'Access, Mod_Ctrl + 'c', Flag_Inactive); Bar.Add ("Edit/&Paste", Paste_CB'Access, Mod_Ctrl + 'v'); - Bar.Add ("Edit/&Delete", Delete_CB'Access, No_Key, Flag_Divider); + Bar.Add ("Edit/&Delete", Delete_CB'Access, No_Key, Flag_Inactive + Flag_Divider); Bar.Add ("Edit/Select &All", Select_All_CB'Access, Mod_Ctrl + 'a'); Bar.Add (Text => "&Search", Flags => Flag_Submenu); Bar.Add ("Search/&Find...", Find_CB'Access, Mod_Ctrl + 'f'); - Bar.Add ("Search/Find &Next", Find_Next_CB'Access, Mod_Ctrl + 'g'); - Bar.Add ("Search/Find &Previous", Find_Prev_CB'Access, Mod_Shift + Mod_Ctrl + 'g'); + Bar.Add ("Search/Find &Next", Find_Next_CB'Access, Mod_Ctrl + 'g', Flag_Inactive); + Bar.Add ("Search/Find &Previous", Find_Prev_CB'Access, Mod_Shift + Mod_Ctrl + 'g', Flag_Inactive); Bar.Add ("Search/&Replace...", Replace_CB'Access, Mod_Ctrl + 'h', Flag_Divider); Bar.Add ("Search/Jump To...", Jump_CB'Access, Mod_Ctrl + 'j'); Bar.Add ("Search/Word Count", Count_CB'Access); @@ -554,10 +575,10 @@ begin use FLTK.Widgets.Menus; Pop : Menu_Cursor := Editor.Get_Rightclick_Menu; begin - Pop.Add ("Cu&t", Cut_CB'Access); - Pop.Add ("&Copy", Copy_CB'Access); + Pop.Add ("Cu&t", Cut_CB'Access, No_Key, Flag_Inactive); + Pop.Add ("&Copy", Copy_CB'Access, No_Key, Flag_Inactive); Pop.Add ("&Paste", Paste_CB'Access); - Pop.Add ("&Delete", Delete_CB'Access, No_Key, Flag_Divider); + Pop.Add ("&Delete", Delete_CB'Access, No_Key, Flag_Inactive + Flag_Divider); Pop.Add ("Select &All", Select_All_CB'Access); end; diff --git a/src/fltk_binding/c_fl_menu.cpp b/src/fltk_binding/c_fl_menu.cpp index 0455e51..f8c7b9e 100644 --- a/src/fltk_binding/c_fl_menu.cpp +++ b/src/fltk_binding/c_fl_menu.cpp @@ -10,6 +10,11 @@ int fl_menu_add(MENU m, const char * t, unsigned long s, void * c, void * u, uns } +const void * fl_menu_find_item(MENU m, const char * t) { + return reinterpret_cast(m)->find_item(t); +} + + const void * fl_menu_mvalue(MENU m) { return reinterpret_cast(m)->mvalue(); } @@ -21,3 +26,13 @@ int fl_menuitem_value(void * mi) { return reinterpret_cast(mi)->value(); } + +void fl_menuitem_activate(void * mi) { + reinterpret_cast(mi)->activate(); +} + + +void fl_menuitem_deactivate(void * mi) { + reinterpret_cast(mi)->deactivate(); +} + diff --git a/src/fltk_binding/c_fl_menu.h b/src/fltk_binding/c_fl_menu.h index 1599334..2b9aa68 100644 --- a/src/fltk_binding/c_fl_menu.h +++ b/src/fltk_binding/c_fl_menu.h @@ -9,10 +9,13 @@ typedef void* MENU; extern "C" int fl_menu_add(MENU m, const char * t, unsigned long s, void * c, void * u, unsigned long f); +extern "C" const void * fl_menu_find_item(MENU m, const char * t); extern "C" const void * fl_menu_mvalue(MENU m); extern "C" int fl_menuitem_value(void * mi); +extern "C" void fl_menuitem_activate(void * mi); +extern "C" void fl_menuitem_deactivate(void * mi); #endif diff --git a/src/fltk_binding/c_fl_text_buffer.cpp b/src/fltk_binding/c_fl_text_buffer.cpp index 623aea7..966f142 100644 --- a/src/fltk_binding/c_fl_text_buffer.cpp +++ b/src/fltk_binding/c_fl_text_buffer.cpp @@ -80,6 +80,11 @@ int fl_text_buffer_selection_position(TEXTBUFFER tb, int * s, int * e) { } +int fl_text_buffer_selected(TEXTBUFFER tb) { + return reinterpret_cast(tb)->selected(); +} + + int fl_text_buffer_skip_lines(TEXTBUFFER tb, int s, int l) { return reinterpret_cast(tb)->skip_lines(s, l); } diff --git a/src/fltk_binding/c_fl_text_buffer.h b/src/fltk_binding/c_fl_text_buffer.h index 4c5edb3..a7b954b 100644 --- a/src/fltk_binding/c_fl_text_buffer.h +++ b/src/fltk_binding/c_fl_text_buffer.h @@ -24,6 +24,7 @@ extern "C" int fl_text_buffer_search_forward(TEXTBUFFER tb, int start, const cha extern "C" int fl_text_buffer_search_backward(TEXTBUFFER tb, int start, const char * item, int * found, int mcase); extern "C" void fl_text_buffer_select(TEXTBUFFER tb, int s, int e); extern "C" int fl_text_buffer_selection_position(TEXTBUFFER tb, int * s, int * e); +extern "C" int fl_text_buffer_selected(TEXTBUFFER tb); extern "C" int fl_text_buffer_skip_lines(TEXTBUFFER tb, int s, int l); extern "C" int fl_text_buffer_rewind_lines(TEXTBUFFER tb, int s, int l); extern "C" unsigned int fl_text_buffer_char_at(TEXTBUFFER tb, int p); diff --git a/src/fltk_binding/fltk-text_buffers.adb b/src/fltk_binding/fltk-text_buffers.adb index 6ff5b55..38e6632 100644 --- a/src/fltk_binding/fltk-text_buffers.adb +++ b/src/fltk_binding/fltk-text_buffers.adb @@ -99,6 +99,11 @@ package body FLTK.Text_Buffers is return Interfaces.C.int; pragma Import (C, fl_text_buffer_selection_position, "fl_text_buffer_selection_position"); + function fl_text_buffer_selected + (TB : in System.Address) + return Interfaces.C.int; + pragma Import (C, fl_text_buffer_selected, "fl_text_buffer_selected"); + function fl_text_buffer_skip_lines (TB : in System.Address; S, L : in Interfaces.C.int) @@ -418,6 +423,16 @@ package body FLTK.Text_Buffers is + function Has_Selection + (This : in Text_Buffer) + return Boolean is + begin + return fl_text_buffer_selected (This.Void_Ptr) /= 0; + end Has_Selection; + + + + function Skip_Lines (This : in out Text_Buffer; Start, Lines : in Natural) diff --git a/src/fltk_binding/fltk-text_buffers.ads b/src/fltk_binding/fltk-text_buffers.ads index 582de1d..c17b020 100644 --- a/src/fltk_binding/fltk-text_buffers.ads +++ b/src/fltk_binding/fltk-text_buffers.ads @@ -106,6 +106,11 @@ package FLTK.Text_Buffers is return Boolean; + function Has_Selection + (This : in Text_Buffer) + return Boolean; + + -- only takes into account newline characters, not word wrap function Skip_Lines (This : in out Text_Buffer; diff --git a/src/fltk_binding/fltk-widgets-menus.adb b/src/fltk_binding/fltk-widgets-menus.adb index 169e71d..b1ffd9a 100644 --- a/src/fltk_binding/fltk-widgets-menus.adb +++ b/src/fltk_binding/fltk-widgets-menus.adb @@ -91,6 +91,12 @@ package body FLTK.Widgets.Menus is return Interfaces.C.int; pragma Import (C, fl_menu_add, "fl_menu_add"); + function fl_menu_find_item + (M : in System.Address; + T : in Interfaces.C.char_array) + return System.Address; + pragma Import (C, fl_menu_find_item, "fl_menu_find_item"); + function fl_menu_mvalue (M : in System.Address) return System.Address; @@ -101,6 +107,14 @@ package body FLTK.Widgets.Menus is return Interfaces.C.int; pragma Import (C, fl_menuitem_value, "fl_menuitem_value"); + procedure fl_menuitem_activate + (MI : in System.Address); + pragma Import (C, fl_menuitem_activate, "fl_menuitem_activate"); + + procedure fl_menuitem_deactivate + (MI : in System.Address); + pragma Import (C, fl_menuitem_deactivate, "fl_menuitem_deactivate"); + @@ -150,6 +164,21 @@ package body FLTK.Widgets.Menus is + function Find_Item + (This : in Menu'Class; + Name : in String) + return Menu_Item is + begin + return Item : Menu_Item do + Item.Void_Ptr := fl_menu_find_item + (This.Void_Ptr, + Interfaces.C.To_C (Name)); + end return; + end Find_Item; + + + + function Chosen (This : in Menu'Class) return Menu_Item is @@ -170,5 +199,23 @@ package body FLTK.Widgets.Menus is end Value; + + + procedure Activate + (Item : in Menu_Item) is + begin + fl_menuitem_activate (Item.Void_Ptr); + end Activate; + + + + + procedure Deactivate + (Item : in Menu_Item) is + begin + fl_menuitem_deactivate (Item.Void_Ptr); + end Deactivate; + + end FLTK.Widgets.Menus; diff --git a/src/fltk_binding/fltk-widgets-menus.ads b/src/fltk_binding/fltk-widgets-menus.ads index cf6fcf7..0346d2d 100644 --- a/src/fltk_binding/fltk-widgets-menus.ads +++ b/src/fltk_binding/fltk-widgets-menus.ads @@ -60,6 +60,12 @@ package FLTK.Widgets.Menus is Flags : in Menu_Flag := Flag_Normal); + function Find_Item + (This : in Menu'Class; + Name : in String) + return Menu_Item; + + function Chosen (This : in Menu'Class) return Menu_Item; @@ -70,6 +76,14 @@ package FLTK.Widgets.Menus is return Boolean; + procedure Activate + (Item : in Menu_Item); + + + procedure Deactivate + (Item : in Menu_Item); + + private diff --git a/to_do.txt b/to_do.txt index 8921ea9..e9934f4 100644 --- a/to_do.txt +++ b/to_do.txt @@ -4,9 +4,8 @@ To Do: - change build to be dynamically linked - improve replace, undo/redo, jump to -- grey out menu entries when appropriate - suppress unnecessary left/right scrollbar -- clean up menu widget code +- clean up menu widget code, adapad menu and callback code - introduce maybe type to eliminate out parameters in search_forward/search_backward - eliminate image/text_buffer runtime warnings - separate fltk binding into its own repo -- cgit