; Module/File: RecentFilesPrivate_Demo.pb ; Function: Show private multi-RecentFile handling on menus and popups - Linux gtk2/gtk3 ; Author: Omi ; Date: Nov. 04, 2015 ; Version: 0.1 ; Target Compiler: PureBasic 5.22/5.31/5.40 ; Target OS: Linux: (X/K/L)ubuntu, Mint, 32/64, Ascii/Uni ;-------------------------------------------------------------- ;Private RecentFiles: ; Extensive code, but there's no PB-MenuItemID-query ... ; works for WindowMenus AND Popup on Gadgets (i.e. ButtonGadgets) ; More then one RecentFile Submenu or Popup is possible ; Auto-Hide of unused items ; Auto-Disable the 'Call' element With an empty Recent File menu ; Creating the RecentFile menu ... ; WindowMenu: Place the 'Recent files'-item in the 1. MenuBarItem, in Linux beneath the 'Open ...' items ; Place the Submenu with an arbitrary number of entries as usual. Important: The entries must have an ascending order. ; Create the Menu ; Popup : Place a Gadget (i.e.) Button to open the Popup ; Create the Popup ; Init (Call init for any RecentFile-Container) ... ; WindowMenu: Menu_RecentFileInit(RecentFiles(NUMBER), PB-MENU_NUMBER, #Null, "TEXT OF RECENT FILE ITEM", SUBMENU FIRST_ITEM_NO, SUBMENU FIRST_ITEM_NO) ; Popup : Menu_RecentFileInit(RecentFiles(NUMBER), PB-POPUP_NUMBER, GADGET_TO_OPEN, "", POPUP FIRST_ITEM_NO, POPUP FIRST_ITEM_NO) ; Add Item ... ; Menu_RecentFileAdd(RecentFiles(NUMBER), "TEXT TO ADD") ; Clear Items ... ; Menu_RecentFilesClear(RecentFiles(NUMBER)) EnableExplicit ImportC "" gtk_container_get_children(*container.GtkContainer) gtk_menu_get_attach_widget(*menu.GtkMenu) gtk_menu_item_get_label(*menu_item.GtkMenuItem) gtk_menu_item_get_submenu(*menu_item.GtkMenuItem) gtk_widget_get_name(*widget.GtkWidget) EndImport ; Object constants #Win_Main = 0 #But1 = 0; for menu #But2 = 1 #But3 = 2; for popup #But4 = 3 #But5 = 4 Enumeration #Mn1 #Pu1 EndEnumeration Enumeration; Create Menu with RecentFile submenu #Mn1_Item11 #Mn1_Item12 ; #Mn1_Item13; not needed, the 'open' item #Mn1_Item130; for RecentFiles, ascending! #Mn1_Item131 #Mn1_Item132 #Mn1_Item133 #Mn1_Item134 #Mn1_Item135 #Mn1_Item136 #Mn1_Item137 #Mn1_Item138 #Mn1_Item139; so far #Mn1_Item14 #Mn1_Item15 #Mn1_Item16 EndEnumeration Enumeration #PB_Compiler_EnumerationValue; Create indices for Popup #Pu1_Item10; for RecentFiles, ascending! #Pu1_Item11 #Pu1_Item12 #Pu1_Item13 #Pu1_Item14 #Pu1_Item15 #Pu1_Item16 #Pu1_Item17 #Pu1_Item18 #Pu1_Item19 EndEnumeration Structure RECENT_FILES PbMenu.i; PB number for menu *menuitem.GtkWidget; widget for submenu *menu.GtkContainer; container widget for submenu title.s; item title for submenu widget fItem.i; PB-index for 1. item in RecentFile container lItem.i; PB-index for last item in RecentFile container Adds.i; counter for all added files Num.i; counter for used entries EndStructure Global Dim RecentFiles.RECENT_FILES(1) Global.i gEvent, gMnEvent, gQuit Global.s gGtkSubSytem ;- ;- RecentFile-Library (until PB returns the widgets-adr ;-)_____________ Procedure.s GetGtkSubSytem() CompilerIf #PB_Compiler_Version < 540 CompilerIf Subsystem("gtk3") gGtkSubSytem= "gtk3" CompilerElse gGtkSubSytem= "gtk2" CompilerEndIf CompilerElse CompilerIf Subsystem("gtk2") gGtkSubSytem= "gtk2" CompilerElse gGtkSubSytem= "gtk3" CompilerEndIf CompilerEndIf ProcedureReturn gGtkSubSytem EndProcedure Procedure.s Menu_GetItemLabel(*widget.GtkWidget); works for popups, menus, submenus Protected *subType.GtkImageMenuItem Protected.s ItemType, ItemLabel If *widget ItemType= PeekS(gtk_widget_get_name_(*widget), -1, #PB_UTF8); Menu item type If gGtkSubSytem= "gtk3" If ItemType <> "GtkSeparatorMenuItem"; else separator is harmed ItemLabel= PeekS(gtk_menu_item_get_label(*widget), -1, #PB_UTF8); Label always in item EndIf Else; gtk2 *subType= *widget If *subType\menu_item\item\bin\child If PeekS(gtk_widget_get_name_(*subType\menu_item\item\bin\child), -1, #PB_UTF8) = "GtkAccelLabel"; gtk2 uses subitems for labels ItemLabel= PeekS(gtk_label_get_text_(*subType\menu_item\item\bin\child), -1, #PB_UTF8) EndIf EndIf EndIf ItemLabel= RemoveString(ItemLabel, "_", #PB_String_CaseSensitive, 1, 1); remove "_" EndIf ProcedureReturn ItemLabel EndProcedure Procedure.i Menu_FindItemByID(*menu, Menu, Title.s, ItemID, Hide) Protected *widget.GtkWidget, *SubMenu.GtkWidget Protected *list.GList= gtk_container_get_children(*menu) Protected *Agree= #Null Protected.s ItemLabel, sItemLabel= StringField(GetMenuItemText(Menu, ItemID), 1, #TAB$) Protected.i I For I= 0 To g_list_length_(*list)- 1 *widget= g_list_nth_data_(*list, I) If *widget *SubMenu= gtk_menu_item_get_submenu(*widget) ItemLabel= Menu_GetItemLabel(*widget) If sItemLabel = ItemLabel If gtk_menu_get_attach_widget(*menu) If Menu_GetItemLabel(gtk_menu_get_attach_widget(*menu)) = Title *Agree= *widget Break EndIf Else If Title = "" *Agree= *widget Break EndIf EndIf EndIf If *SubMenu *Agree= Menu_FindItemByID(*SubMenu, Menu, Title, ItemID, Hide) If *Agree : Break : EndIf EndIf EndIf Next I g_list_free_(*list) ProcedureReturn *Agree EndProcedure Procedure Menu_RecentFileInit(*RF.RECENT_FILES, Menu, Attach, Title.s, RfFItem, RfLItem) Protected *list.GList Protected *menu.GtkContainer, *widget.GtkWidget Protected.s ItemLabel Protected.i I, Num *widget= Menu_FindItemByID(MenuID(Menu), Menu, Title, RfFItem, #True) If *widget *menu= gtk_widget_get_parent_(*widget) EndIf If *menu With *RF \PbMenu = Menu \menu = *menu If Title = "" And Attach > -1; seems to be a Popup \menuitem= GadgetID(Attach) Else; a (sub)menu with it's trigger item \menuitem= gtk_menu_get_attach_widget (*menu) EndIf \fItem = RfFItem \lItem = RfLItem \title = Title EndWith *list= gtk_container_get_children(*menu) For I= g_list_length_(*list)- 1 To 0 Step -1 *widget= g_list_nth_data_(*list, I) If *widget ItemLabel= Menu_GetItemLabel(*widget) If ItemLabel = "" gtk_widget_hide_(*widget) Else gtk_widget_show_(*widget) Num+ 1 EndIf EndIf Next I *RF\Num = Num *RF\Adds= Num If Num = 0 And *RF\menuitem gtk_widget_set_sensitive_(*RF\menuitem, #False) EndIf g_list_free_(*list) EndIf EndProcedure Procedure Menu_RecentFileAdd(*RF.RECENT_FILES, entry.s); add from top Protected *list.GList, *widget.GtkWidget Protected.i listLen Protected.i I, Num, Dup If *RF\menu *list= gtk_container_get_children(*RF\menu) listLen= g_list_length_(*list)- 1 Dup= listLen For I= 0 To listLen If GetMenuItemText(*RF\PbMenu, *RF\fItem+ I) = entry Dup= I Break EndIf Next I For I= Dup To 1 Step -1 *widget= g_list_nth_data_(*list, I) If *widget SetMenuItemText(*RF\PbMenu, *RF\fItem+ I, GetMenuItemText(*RF\PbMenu, *RF\fItem+ I- 1)) If GetMenuItemText(*RF\PbMenu, *RF\fItem+ I) <> "" gtk_widget_show_(*widget) Num+ 1 EndIf EndIf Next I SetMenuItemText(*RF\PbMenu, *RF\fItem, entry) *widget= g_list_nth_data_(*list, 0) gtk_widget_show_(*widget) *RF\Num = Num+ 1 *RF\Adds+ 1 If *RF\menuitem gtk_widget_set_sensitive_(*RF\menuitem, #True) EndIf g_list_free_(*list) EndIf EndProcedure Procedure Menu_RecentFilesClear(*RF.RECENT_FILES) Protected *list.GList, *widget.GtkWidget Protected.i I If *RF\menu *list= gtk_container_get_children(*RF\menu) For I= 0 To g_list_length_(*list)- 1 *widget= g_list_nth_data_(*list, I) If *widget SetMenuItemText(*RF\PbMenu, *RF\fItem+ I, "") gtk_widget_hide_(*widget) EndIf Next I *RF\Num= 0 g_list_free_(*list) EndIf If *RF\menuitem gtk_widget_set_sensitive_(*RF\menuitem, #False) EndIf EndProcedure ;- ;- Main _____________ Procedure CreateWindow_Main() OpenWindow(#Win_Main, 0, 0, 400, 300, "RecentFiles on menu & popup", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) ButtonGadget(#But1, 15, 5, 370, 26, "Add Menu RecentFile") ButtonGadget(#But2, 15, 35, 370, 26, "Clear Menu RecentFiles") ButtonGadget(#But3, 5, 85, 390, 32, "Open Popup") ButtonGadget(#But4, 15, 125, 370, 26, "Add Popup RecentFile") ButtonGadget(#But5, 15, 155, 370, 26, "Clear Popup RecentFiles") EndProcedure Procedure Create_Mn1() CreateMenu(#Mn1, WindowID(#Win_Main)) MenuTitle("File") MenuItem(#Mn1_Item11, "&New" + #TAB$ + "Ctrl+N") MenuBar() MenuItem(#Mn1_Item12, "&Open" + #TAB$ + "Ctrl+O") OpenSubMenu("Recent files") MenuItem(#Mn1_Item130, "") MenuItem(#Mn1_Item131, "") MenuItem(#Mn1_Item132, "") MenuItem(#Mn1_Item133, "") MenuItem(#Mn1_Item134, "") MenuItem(#Mn1_Item135, "") MenuItem(#Mn1_Item136, "") MenuItem(#Mn1_Item137, "") MenuItem(#Mn1_Item138, "") MenuItem(#Mn1_Item139, "") CloseSubMenu() MenuBar() MenuItem(#Mn1_Item14, "&Save" + #TAB$ + "Ctrl+S") MenuBar() MenuItem(#Mn1_Item15, "&Print" + #TAB$ + "Ctrl+P") MenuBar() MenuItem(#Mn1_Item16, "Quit") EndProcedure Procedure Create_Pu1() CreatePopupMenu(#Pu1) MenuItem(#Pu1_Item10, "") MenuItem(#Pu1_Item11, "") MenuItem(#Pu1_Item12, "") MenuItem(#Pu1_Item13, "") MenuItem(#Pu1_Item14, "") MenuItem(#Pu1_Item15, "") MenuItem(#Pu1_Item16, "") MenuItem(#Pu1_Item17, "") MenuItem(#Pu1_Item18, "") MenuItem(#Pu1_Item19, "") EndProcedure gGtkSubSytem= GetGtkSubSytem() CreateWindow_Main() Create_Mn1() Create_Pu1() Menu_RecentFileInit(RecentFiles(0), #Mn1, #Null, "Recent files", #Mn1_Item130, #Mn1_Item139) Menu_RecentFileInit(RecentFiles(1), #Pu1, #But3, "", #Pu1_Item10, #Pu1_Item19) Repeat gEvent= WaitWindowEvent() Select gEvent Case #PB_Event_CloseWindow gQuit= #True Case #PB_Event_Gadget Select EventGadget() Case #But1 Menu_RecentFileAdd(RecentFiles(0), "/home/user-linux/Programming/PBSource/mnsource "+ Str(RecentFiles(0)\Adds+1) + ".pb") Case #But2 Menu_RecentFilesClear(RecentFiles(0)) Case #But3 DisplayPopupMenu(#Pu1, WindowID(#Win_Main), WindowX(#Win_Main, #PB_Window_InnerCoordinate)+ GadgetX(#But3), WindowY(#Win_Main, #PB_Window_InnerCoordinate)+ GadgetY(#But3)+ GadgetHeight(#But3)) Case #But4 Menu_RecentFileAdd(RecentFiles(1), "/home/user-linux/Programming/PBSource/pusource "+ Str(RecentFiles(1)\Adds+1) + ".pb") Case #But5 Menu_RecentFilesClear(RecentFiles(1)) EndSelect Case #PB_Event_Menu gMnEvent= EventMenu() Select gMnEvent Case #Mn1_Item130 To #Mn1_Item139 Debug GetMenuItemText(#Mn1, gMnEvent) Case #Pu1_Item10 To #Pu1_Item19 Debug GetMenuItemText(#Pu1, gMnEvent) EndSelect EndSelect Until gQuit ; IDE Options = PureBasic 5.40 LTS (Linux - x64) ; CursorPosition = 30 ; Folding = --- ; EnableUnicode ; EnableXP