Custom PopUp / ContextualAction Menu (Without Extensions)

Hi everyone,

Today I finished a project I’d had in mind for a long time.
The idea is to display a PopUp / Contextual Action Menu next to any component.

I’d like to emphasize, as always, that since everything is created with native components, we’ll have maximum customization.
In fact, this menu will include a progress bar, checkboxes, and sliders (just to showcase its potential).

ezgif-4befe3aded8ea6d2

alignHorizontal=center, alignVertical=bottom

Now, you might say,
“But Gian, isn’t it enough to use Animation Utilities and move the menu layout to the XY position of the clicked component?”

Yes and no :grin:, as long as all components are arranged vertically within the same arrangement, it’s quite simple to do this.
However, once we start adding Horizontal Arrangements, Vertical Arrangements, or any other layout, things get more complicated.
The positions of components begin to be calculated relative to their container, making it difficult to locate.

Not accepting defeat, I decided to find a way to solve this problem, and here we are!
Let’s see what I came up with.

Layout

We’re going to overlap two layouts:

  • VA_Layout: which will contain our layout or virtual screens.
  • VA_Menu: which will overlap VA_Layout and is where our menu will move freely.

VA_Main will contain these two layouts and will be used to find the coordinates of the screen edges.

Blocks

InitializeLayouts

This function will initialize the layouts

  • set VA_Layout to the height of VA_Main
  • set VA_Menu with a negative margin equal to the height of VA_Main
  • also set VA_Menu to the height of VA_Main so it fully covers VA_Layout
  • and finally hide VA_Menu

getCoordinatesDictionary

This function will help us obtain a clean dictionary of all the key information for the target where we need to show the dialog, top, left, bottom, right, height, width, centerX, centerY.
It will receive the target component as a parameter and return all these values as a dictionary.

moveTo

This is the function that will calculate the position of our CV_Menu.
It may seem complex, but once you understand how it works it will be very simple.

It will receive the following parameters:

  • containerList: this parameter is very important and I want to explain it well.
    As mentioned earlier:

    once we start adding Horizontal Arrangements, Vertical Arrangements, or any other layout, things get more complicated :scream:.
    The positions of components begin to be calculated relative to their container, making it difficult to locate.

    This parameter will be a list of all the containers (Layouts) starting from the outermost one and going down to our target.

  • alignHorizontal: accepts left, center or right and sets the menu’s horizontal alignment.

  • alignVertical: same but for vertical alignment.

Inside the function we’ll create 5 variables:

  • The two target variables targetX and targetY will represent the X and Y position of our target in this case one of the buttons, we will later see how to calculate them.
  • containerListLength: simply the length of containerList
  • menuCoordinatesDictionary: calls getCoordinatesDictionary to obtain the menu’s coordinates.
  • targetCoordinatesDictionary: We will obtain them later.

Steps:

  • First we calculate the target’s position, to do this we loop through all layouts in containerList with a for each number.

  • Create a variable component that selects the layout from the containerList.

  • On each iteration add the layout’s X and Y to targetX and targetY until we reach the final component, the target,

  • where we set targetCoordinatesDictionary with its info and based on the alignHorizontal and alignVertical parameters we calculate different X and Y values.

    To avoid a wall of text I won’t explain every block, but I’m happy to go into detail if anyone’s interested, just ask.

  • Using OvershootHorizontal and OvershootVertical we move the dialog to targetX and targetY.

    why I didn’t simply set endPosition to the corresponding targetX/Y variables?
    if you select a button near the bottom, the menu would go off-screen.
    The calculations prevent this by computing how much it would overflow and subtracting that from the target coordinates.

  • Finally, set VA_Menu to visible.

    This layout will be clickable so that if the user clicks anywhere outside the menu, it will be hidden.

when Button1_HA1.Click

Here we will call our moveTo procedure with the parameters explained earlier.

When Any Button.Click

I also created an event for AnyButton in which I made a dictionary with

keys = button components 
values = their `containerList`

Finish :partying_face:

AIA

Bonus:
while I was making the final adjustments and exporting the AIA, I thought an animation would be nice to see.
So, you just need to enable this block in moveTo under the overshoots animation


to get a slide-in effect from the top.
ezgif-41a66fb285349ad7

PopUpMenuPopUpContextualActionMenu.aia (14.2 KB)

3 Likes

Exceptional work!

Your guide delivers a precise, well-structure explanatio of the complexities behind layout positioning in Kodular. The overlapping-layou strategy, combined with your clean initialization logic, showcases impressive technical insight and practical problem-solving. The clarity of your visuals makes the entire process intuitive and easy to implement.

And honestly, if you ever start creating extensions, you’ll be unstoppable.:face_savoring_food::face_savoring_food:

Thanks for sharing such a high-quality, valuable resource.

:saluting_face:

1 Like

I’m speechless,
thank you so much for all these compliments, you’ve been really kind.
I hope I can always provide this level of quality, if not more, and maybe one day get into the world of extensions (In which you will have to help me :grin:)

Thank you, thank you so much, dear :heart_hands:

1 Like