How to put a menu in a bubble?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How to put a menu in a bubble?

voger
I am trying to replicate the bubble menu of the OS X menu without much
success. Here is a sample of what I mean http://i.imgur.com/ib6wVkL.jpg

My biggest stumbling block is how to add that arrow in the bottom of the
menu.

What I tried so far is

1. Create a custom widget subclassed from qx.ui.popup.Popup() with two
qx.ui.container.Composite(). One acts as childrenContainer and one just
to be styled as the arrow. This works. I have a nice popup with the
arrow et al.  Still it is imposible to add menu items directly in the
popup. I added the menu itself but then when the popup is displayed the
menu remains closed. Plus that I get plenty of errors most of them I
can't understand and I don't know where to look for debugging.

Also this seems kind of naive approach since the menu itself is a popup
and it is a pity to try and duplicate its functionality.

2. My other approach that I try right now is to create just the menu and
style it. So far I have this http://i.imgur.com/NVq5286.png which means
that I can style the menu as I wish. But how can I add that arrow below
the menu to create that bubble effect? This is my latest attempt
https://gist.github.com/voger/481f2f0fb8360338a2d0



------------------------------------------------------------------------------

_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

group-applications-by-category-mac.jpg (88K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to put a menu in a bubble?

voger
Thanks. This makes me notice that many online tutorials use the ::after
pseudo-element to create the arrow (they call it "nubble"). This hints
me that I need to write a decorator mixin.

But how do I get the ::before and ::after pseudo-classes? I have found
this older example from Phyo Arkar
http://qooxdoo.678.n2.nabble.com/Set-margin-between-listitems-tp7587446p7587489.html 
where he makes use of the :before pseudo-element.

For now my mixin looks like this (for debugging purposes):

qx.Mixin.define("qssite.util.MNubbin", {
     properties: {
         showNubbin: {
             nullable: false,
             init: false,
             check: "Boolean",
             apply: "_applyShowNubbin"
         }
     },

     members: {

         _styleShowNubbin: function(styles){
             //how I get the ::after?
             console.log(":before - " + styles[":before"]);
             console.log(":after - " + styles[":after"]);
         },

         _applyShowNubbin: function(){
          //apply stuff
         }
     }
});

and I get in the console

:before - [object Object]
:after - undefined

On 20/11/2015 05:44 μμ, Sanne Peters wrote:

> Hi,
>
> You will probably need to do some advanced css. I'd suggest asking this
> on stack overflow.
>
> regards,
>
> Sanne Peters
> *Interaction Design*
>
> Realtime Solutions B.V.
> Torenallee 20
> 5617 BC Eindhoven
>
> *Tel:* 040 4022 726 | *E-mail:*
> <mailto:[hidden email]>[hidden email]
> | *Website:*
> <http://www.realtimesolutions.nl>http://www.realtimesolutions.nl
>
> On 19/11/15 20:43, voger wrote:
>> I am trying to replicate the bubble menu of the OS X menu without much
>> success. Here is a sample of what I mean http://i.imgur.com/ib6wVkL.jpg
>>
>> My biggest stumbling block is how to add that arrow in the bottom of
>> the menu.
>>
>> What I tried so far is
>>
>> 1. Create a custom widget subclassed from qx.ui.popup.Popup() with two
>> qx.ui.container.Composite(). One acts as childrenContainer and one
>> just to be styled as the arrow. This works. I have a nice popup with
>> the arrow et al.  Still it is imposible to add menu items directly in
>> the popup. I added the menu itself but then when the popup is
>> displayed the menu remains closed. Plus that I get plenty of errors
>> most of them I can't understand and I don't know where to look for
>> debugging.
>>
>> Also this seems kind of naive approach since the menu itself is a
>> popup and it is a pity to try and duplicate its functionality.
>>
>> 2. My other approach that I try right now is to create just the menu
>> and style it. So far I have this http://i.imgur.com/NVq5286.png which
>> means that I can style the menu as I wish. But how can I add that
>> arrow below the menu to create that bubble effect? This is my latest
>> attempt https://gist.github.com/voger/481f2f0fb8360338a2d0
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>>
>>
>> _______________________________________________
>> qooxdoo-devel mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
>
>
>
> ------------------------------------------------------------------------------
>
>
>
> _______________________________________________
> qooxdoo-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
>


------------------------------------------------------------------------------
_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
Reply | Threaded
Open this post in threaded view
|

Re: How to put a menu in a bubble?

voger
I finally did it. I wrote a decorator mixin to add that triangle on the
bottom. I am posting it here just in case someone else finds it useful.
It does have some hardcoded values and some assumptions but it is good
enough for now.


qx.Mixin.define("qssite.util.MNubbin", {
     properties: {
         showNubbin: {
             nullable: false,
             init: false,
             check: "Boolean",
             apply: "_applyShowNubbin"
         }
     },

     members: {

         _styleShowNubbin: function(styles){

             if (this.isShowNubbin()) {

                 // split <div>'s border bottom style
                 // borderBottom[0]: width
                 // borderBottom[1]: style
                 // borderBottom[2]: color
                 var borderBottom = styles["border-bottom"].split(" ");


                 styles[":before"] = {
                     "content": '""',
                     "position": "absolute",
                     "width": 0,
                     "height": 0,
                     "border-style": "solid",
                     "border-color": "transparent",
                     "border-bottom": 0,
                     "bottom": "-16px",
                     "left": "10px",
                     /* If 1px darken stroke slightly */
                     "border-top-color": borderBottom[2],
                     "border-width": "16px"
                 };

                 //get the size of the overlay
                 var overlay =
parseInt(styles[":before"]["border-width"]) - parseInt(borderBottom[0]);
                 qx.core.Assert.assertPositiveInteger(overlay,
                                                      "border-bottom
should be smaller than nubbin's border-width");

                 var position = parseInt(styles[":before"]["left"]) +
parseInt(borderBottom[0]);

                 styles[":after"] = {
                     "content": '""',
                     "position": "absolute",
                     "width": 0,
                     "height": 0,
                     "border-style": "solid",
                     "border-color": "transparent",
                     "border-bottom": 0,
                     "bottom": (-1) * overlay +1 + "px",
                     "left": position + "px",
                     "border-top-color": styles["background-color"],
                     "border-width": overlay + "px"
                 };
               }

         },

         _applyShowNubbin: function(){
             if (qx.core.Environment.get("qx.debug")) {
                 if (this._isInitialized()) {
                     throw new Error("This decorator is already in-use.
Modification is not possible anymore!");
                 }
             }
         }
     }
});

How to use

1)
//add a showNubbin property to the widget
qx.Class.patch(qx.ui.decoration.Decorator, qssite.util.MNubbin);

2)
widget.setAppearance("my-awesome-widget");

3)
//add an event listener for the widget for the on "appear" event and
//set visibility to visible.
__onAppear: function(e){
    //set overflow to vissible. It is needed to show the ::before and
    //::after
    qx.bom.element.Style.set(this.getContentElement().getDomElement(),
"overflow", "visible");
    }

4)
in the decorator set showNubbin to true
  showNubbin: true,


------------------------------------------------------------------------------
_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel