summaryrefslogtreecommitdiff
path: root/amiga/selectmenu.c
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-05 16:38:48 +0100
committerChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-05 16:38:48 +0100
commit1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93 (patch)
tree25a05797dd3cbcb1ea60966dee4ec301b38db666 /amiga/selectmenu.c
parent2e4bfc5dc3ae3d6c13fbc6f956b611354ed37257 (diff)
parent5b880e586c9358db0ae86bb95edb2559f16d5da4 (diff)
downloadnetsurf-1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93.tar.gz
netsurf-1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93.tar.bz2
Merge branch 'chris/menuclass'
This replaces the old popupmenu.class-based context menus with Intuition-based ones. This provides the following advantages: - No more RMBTrap, so menu shortcuts work without having to be manually handled - Standard menus now display when not over a contextual zone, so the not-really-contextual menu items have been removed - No buggy system crash problems, so they are always enabled now - Menus can be attached directly to gadgets, so the history menu is now attached directly to the back/forward buttons (however they now need to be periodically refreshed as they can't be created on demand) Additionally, the menu items now have images. popupmenu.class is now only used (optionally) for form select menus. This code has been bug-fixed and is now toggleable from the prefs GUI. However, due to the inability to display more items than fit on the screen, it still isn't recommended to use it.
Diffstat (limited to 'amiga/selectmenu.c')
-rw-r--r--amiga/selectmenu.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/amiga/selectmenu.c b/amiga/selectmenu.c
new file mode 100644
index 000000000..e6eae2a99
--- /dev/null
+++ b/amiga/selectmenu.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008 - 2011 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __amigaos4__
+
+#include <stdbool.h>
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/popupmenu.h>
+#include <proto/utility.h>
+#include <reaction/reaction_macros.h>
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "render/form.h"
+#include "desktop/mouse.h"
+
+#include "amiga/gui.h"
+#include "amiga/selectmenu.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+/* Maximum number of items for a popupmenu.class select menu.
+ * 50 is about the limit for my screen, and popupmenu doesn't scroll.
+ */
+#define AMI_SELECTMENU_MAX 50
+
+/** Exported interface documented in selectmenu.h **/
+BOOL ami_selectmenu_is_safe(void)
+{
+ struct Library *PopupMenuBase;
+ BOOL popupmenu_lib_ok = FALSE;
+
+ if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) {
+ LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version, PopupMenuBase->lib_Revision);
+ if(LIB_IS_AT_LEAST((struct Library *)PopupMenuBase, 53, 11))
+ popupmenu_lib_ok = TRUE;
+ CloseLibrary(PopupMenuBase);
+ }
+
+ return popupmenu_lib_ok;
+}
+
+HOOKF(uint32, ami_popup_hook, Object *, item, APTR)
+{
+ uint32 itemid = 0;
+ struct gui_window *gwin = hook->h_Data;
+
+ if(GetAttr(PMIA_ID, item, &itemid)) {
+ form_select_process_selection(gwin->shared->control, itemid);
+ }
+
+ return itemid;
+}
+
+void gui_create_form_select_menu(struct gui_window *g,
+ struct form_control *control)
+{
+ struct Library *PopupMenuBase = NULL;
+ struct PopupMenuIFace *IPopupMenu = NULL;
+ struct Hook selectmenuhook;
+ Object *selectmenuobj;
+ char *selectmenu_item[AMI_SELECTMENU_MAX];
+ struct form_option *opt = form_select_get_option(control, 0);
+ ULONG i = 0;
+
+ if(ami_selectmenu_is_safe() == FALSE) return;
+
+ if((PopupMenuBase = OpenLibrary("popupmenu.class", 0))) {
+ IPopupMenu = (struct PopupMenuIFace *)GetInterface(PopupMenuBase, "main", 1, NULL);
+ }
+
+ if(IPopupMenu == NULL) return;
+
+ ClearMem(selectmenu_item, AMI_SELECTMENU_MAX * 4);
+
+ selectmenuhook.h_Entry = ami_popup_hook;
+ selectmenuhook.h_SubEntry = NULL;
+ selectmenuhook.h_Data = g;
+
+ g->shared->control = control;
+
+ selectmenuobj = PMMENU(form_control_get_name(control)),
+ PMA_MenuHandler, &selectmenuhook, End;
+
+ while(opt) {
+ selectmenu_item[i] = ami_utf8_easy(opt->text);
+
+ IDoMethod(selectmenuobj, PM_INSERT,
+ NewObject(POPUPMENU_GetItemClass(), NULL,
+ PMIA_Title, (ULONG)selectmenu_item[i],
+ PMIA_ID, i,
+ PMIA_CheckIt, TRUE,
+ PMIA_Checked, opt->selected,
+ TAG_DONE),
+ ~0);
+
+ opt = opt->next;
+ i++;
+
+ if(i >= AMI_SELECTMENU_MAX) break;
+ }
+
+ ami_set_pointer(g->shared, GUI_POINTER_DEFAULT, false); // Clear the menu-style pointer
+
+ IDoMethod(selectmenuobj, PM_OPEN, g->shared->win);
+
+ /* PM_OPEN is blocking, so dispose menu immediately... */
+ if(selectmenuobj) DisposeObject(selectmenuobj);
+
+ /* ...and get rid of popupmenu.class ASAP */
+ if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu);
+ if(PopupMenuBase) CloseLibrary(PopupMenuBase);
+
+ /* Free the menu labels */
+ for(i = 0; i < AMI_SELECTMENU_MAX; i++) {
+ if(selectmenu_item[i] != NULL) {
+ ami_utf8_free(selectmenu_item[i]);
+ selectmenu_item[i] = NULL;
+ }
+ }
+}
+
+#else
+#include "amiga/selectmenu.h"
+void gui_create_form_select_menu(struct gui_window *g, struct form_control *control)
+{
+}
+
+BOOL ami_selectmenu_is_safe()
+{
+ return FALSE;
+}
+#endif
+