summaryrefslogtreecommitdiffstats
path: root/widget/gtk/nsMenuObject.h
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gtk/nsMenuObject.h')
-rw-r--r--widget/gtk/nsMenuObject.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/widget/gtk/nsMenuObject.h b/widget/gtk/nsMenuObject.h
new file mode 100644
index 000000000..c7637cd05
--- /dev/null
+++ b/widget/gtk/nsMenuObject.h
@@ -0,0 +1,165 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __nsMenuObject_h__
+#define __nsMenuObject_h__
+
+#include "mozilla/Attributes.h"
+#include "nsCOMPtr.h"
+
+#include "nsDbusmenu.h"
+#include "nsNativeMenuDocListener.h"
+
+class nsIAtom;
+class nsIContent;
+class nsStyleContext;
+class nsMenuContainer;
+class nsMenuObjectIconLoader;
+
+#define DBUSMENU_PROPERTIES \
+ DBUSMENU_PROPERTY(Label, DBUSMENU_MENUITEM_PROP_LABEL, 0) \
+ DBUSMENU_PROPERTY(Enabled, DBUSMENU_MENUITEM_PROP_ENABLED, 1) \
+ DBUSMENU_PROPERTY(Visible, DBUSMENU_MENUITEM_PROP_VISIBLE, 2) \
+ DBUSMENU_PROPERTY(IconData, DBUSMENU_MENUITEM_PROP_ICON_DATA, 3) \
+ DBUSMENU_PROPERTY(Type, DBUSMENU_MENUITEM_PROP_TYPE, 4) \
+ DBUSMENU_PROPERTY(Shortcut, DBUSMENU_MENUITEM_PROP_SHORTCUT, 5) \
+ DBUSMENU_PROPERTY(ToggleType, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, 6) \
+ DBUSMENU_PROPERTY(ToggleState, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, 7) \
+ DBUSMENU_PROPERTY(ChildDisplay, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, 8)
+
+/*
+ * This is the base class for all menu nodes. Each instance represents
+ * a single node in the menu hierarchy. It wraps the corresponding DOM node and
+ * native menu node, keeps them in sync and transfers events between the two.
+ * It is not reference counted - each node is owned by its parent (the top
+ * level menubar is owned by the window) and keeps a weak pointer to its
+ * parent (which is guaranteed to always be valid because a node will never
+ * outlive its parent). It is not safe to keep a reference to nsMenuObject
+ * externally.
+ */
+class nsMenuObject : public nsNativeMenuChangeObserver {
+public:
+ enum EType {
+ eType_MenuBar,
+ eType_Menu,
+ eType_MenuItem
+ };
+
+ virtual ~nsMenuObject();
+
+ // Get the native menu item node
+ DbusmenuMenuitem* GetNativeData() const { return mNativeData; }
+
+ // Get the parent menu object
+ nsMenuContainer* Parent() const { return mParent; }
+
+ // Get the content node
+ nsIContent* ContentNode() const { return mContent; }
+
+ // Get the type of this node. Must be provided by subclasses
+ virtual EType Type() const = 0;
+
+ // Get the document listener
+ nsNativeMenuDocListener* DocListener() const { return mListener; }
+
+ // Create the native menu item node (called by containers)
+ void CreateNativeData();
+
+ // Adopt the specified native menu item node (called by containers)
+ nsresult AdoptNativeData(DbusmenuMenuitem* aNativeData);
+
+ // Called by the container to tell us that it's opening
+ void ContainerIsOpening();
+
+protected:
+ nsMenuObject(nsMenuContainer* aParent, nsIContent* aContent);
+ nsMenuObject(nsNativeMenuDocListener* aListener, nsIContent* aContent);
+
+ enum PropertyFlags {
+#define DBUSMENU_PROPERTY(e, s, b) eProp##e = (1 << b),
+ DBUSMENU_PROPERTIES
+#undef DBUSMENU_PROPERTY
+ };
+
+ void UpdateLabel();
+ void UpdateVisibility(nsStyleContext* aStyleContext);
+ void UpdateSensitivity();
+ void UpdateIcon(nsStyleContext* aStyleContext);
+
+ already_AddRefed<nsStyleContext> GetStyleContext();
+
+private:
+ friend class nsMenuObjectIconLoader;
+
+ // Set up initial properties on the native data, connect to signals etc.
+ // This should be implemented by subclasses
+ virtual void InitializeNativeData();
+
+ // Return the properties that this menu object type supports
+ // This should be implemented by subclasses
+ virtual PropertyFlags SupportedProperties() const;
+
+ // Determine whether this menu object could use the specified
+ // native item. Returns true by default but can be overridden by subclasses
+ virtual bool
+ IsCompatibleWithNativeData(DbusmenuMenuitem* aNativeData) const;
+
+ // Update attributes on this objects content node when the container opens.
+ // This is called before style resolution, and should be implemented by
+ // subclasses who want to modify attributes that might affect style.
+ // This will not be called when there are script blockers
+ virtual void UpdateContentAttributes();
+
+ // Update properties that should be refreshed when the container opens.
+ // This should be implemented by subclasses that have properties which
+ // need refreshing
+ virtual void Update(nsStyleContext* aStyleContext);
+
+ bool ShouldShowIcon() const;
+ void ClearIcon();
+
+ nsCOMPtr<nsIContent> mContent;
+ // mListener is a strong ref for simplicity - someone in the tree needs to
+ // own it, and this only really needs to be the top-level object (as no
+ // children outlives their parent). However, we need to keep it alive until
+ // after running the nsMenuObject destructor for the top-level menu object,
+ // hence the strong ref
+ RefPtr<nsNativeMenuDocListener> mListener;
+ nsMenuContainer* mParent; // [weak]
+ DbusmenuMenuitem* mNativeData; // [strong]
+ RefPtr<nsMenuObjectIconLoader> mIconLoader;
+};
+
+// Keep a weak pointer to a menu object
+class nsWeakMenuObject {
+public:
+ nsWeakMenuObject() : mPrev(nullptr), mMenuObject(nullptr) {}
+
+ nsWeakMenuObject(nsMenuObject* aMenuObject) :
+ mPrev(nullptr), mMenuObject(aMenuObject)
+ {
+ AddWeakReference(this);
+ }
+
+ ~nsWeakMenuObject() { RemoveWeakReference(this); }
+
+ nsMenuObject* get() const { return mMenuObject; }
+
+ nsMenuObject* operator->() const { return mMenuObject; }
+
+ explicit operator bool() const { return !!mMenuObject; }
+
+ static void NotifyDestroyed(nsMenuObject* aMenuObject);
+
+private:
+ static void AddWeakReference(nsWeakMenuObject* aWeak);
+ static void RemoveWeakReference(nsWeakMenuObject* aWeak);
+
+ nsWeakMenuObject* mPrev;
+ static nsWeakMenuObject* sHead;
+
+ nsMenuObject* mMenuObject;
+};
+
+#endif /* __nsMenuObject_h__ */