rawpython / remi

Python REMote Interface library. Platform independent. In about 100 Kbytes, perfect for your diet.
Apache License 2.0
3.51k stars 401 forks source link

Nested MenuItem displays off the right side of the screen #406

Closed jwrothwell2 closed 3 years ago

jwrothwell2 commented 4 years ago

Using gui.MenuItem appended to Menu appended to Container, with both Container and Menu widths=100%, the second-level dropdown MenuItems display beyond the right-side window border.

Would it be possible for the menu widget(s) to be aware of their display coordinates and be rendered to the left when they would otherwise fall off the screen?

Normal Display - menu items cut off:

Normal Display - menu items cut off

After sliding display to left

After sliding display to left

dddomodossola commented 4 years ago

@jwrothwell2 I have to change the style css file to create a specific version for you. I will do it today. ;-)

jwrothwell2 commented 4 years ago

Please...take your time. You're obviously a very busy man. :-)

dddomodossola commented 4 years ago

@jwrothwell2 I tried to find out the correct css style to fit the screen but with no success. Maybe you can use a treeview to show the entire top menu. Here is an example:

import remi.gui as gui
from remi import start, App
import os

class MyApp(App):
    def main(self):

        # creating a container VBox type, vertical (you can use also HBox or Widget)
        self.main_container = gui.Container(width='100%', height='100%', style={'margin': '0px auto'})

        self.menu = gui.Container(width='100%', height='100%', style={'margin': '0px auto', 'background-color':'darkgray'})
        self.tree = gui.TreeView(width='100%')
        ti1 = gui.TreeItem("Item1")
        ti1.onclick.do(self.close_menu)
        ti2 = gui.TreeItem("Item2")
        # ti2 has sub menu items, so I don't close it on click, to allow fold/unfold
        # ti2.onclick.do(self.close_menu)
        ti3 = gui.TreeItem("Item3")
        ti3.onclick.do(self.close_menu)
        subti1 = gui.TreeItem("Sub Item1")
        subti1.onclick.do(self.close_menu)
        subti2 = gui.TreeItem("Sub Item2")
        subti2.onclick.do(self.close_menu)
        subti3 = gui.TreeItem("Sub Item3")
        subti3.onclick.do(self.close_menu)
        subti4 = gui.TreeItem("Sub Item4")
        # subti4 has sub menu items, so I don't close it on click, to allow fold/unfold
        # subti4.onclick.do(self.close_menu)
        subsubti1 = gui.TreeItem("Sub Sub Item1")
        subsubti1.onclick.do(self.close_menu)
        subsubti2 = gui.TreeItem("Sub Sub Item2")
        subsubti2.onclick.do(self.close_menu)
        subsubti3 = gui.TreeItem("Sub Sub Item3")
        subsubti3.onclick.do(self.close_menu)
        self.tree.append([ti1, ti2, ti3])
        ti2.append([subti1, subti2, subti3, subti4])
        subti4.append([subsubti1, subsubti2, subsubti3])
        self.menu.append(self.tree)

        self.bt_open_menu = gui.Button('MENU', width=50, height=50, style={'position':'absolute', 'right':'3px', 'top':'3px'})
        self.bt_open_menu.onclick.do(self.open_menu)

        self.main_container.append(self.bt_open_menu)

        # returning the root widget
        return self.main_container

    def open_menu(self, emitter):
        self.set_root_widget(self.menu)

    def close_menu(self, emitter):
        self.set_root_widget(self.main_container)

if __name__ == "__main__":
    # starts the webserver
    start(MyApp, address='0.0.0.0', port=0, start_browser=True, enable_file_cache=False)
jwrothwell2 commented 4 years ago

@dddomodossola Thanks for this -- I'll give it a try and see how it compares.

I had wondered how you would implement a conditional in CSS. I thought you might somehow use @media to condition styling to display size. But if it's not doable completely within CSS, would a combination of some injected javascript with CSS work? Something along the lines of: if( (location+width) < display_width) ){

; } else {
; } (Not that I'm in desperate need of this -- just as an academic exercise.)
jwrothwell2 commented 4 years ago

Sorry, couldn't seem to get all my code to display (was trying to show 2 different divs with two css classes to select right- or left-float) but you probably get the idea...

dddomodossola commented 4 years ago

@jwrothwell2 Please excuse me the delay. I will provide you an example soon! ;-)

jwrothwell2 commented 4 years ago

@dddomodossola Please -- no hurry, I know you're busy, and you've already given me a work-around. Whenever you're free...

dddomodossola commented 4 years ago

@jwrothwell2 Here is the example for you

python script:

import remi.gui as gui
from remi import start, App
import os

class MyApp(App):
    def __init__(self, *args):
        #CREATE a style.css file inside a folder ./res_folder/
        res_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res_folder')
        super(MyApp, self).__init__(*args, static_file_path={'res':res_path})

    def main(self):
        main_container = gui.VBox(width=300, height=200, style={'margin': '0px auto'})
        #main_container.add_class("custom_css_class")

        return main_container

if __name__ == "__main__":
    start(MyApp, address='0.0.0.0', port=0, start_browser=True, enable_file_cache=False)

style.css file to be placed in folder "./res_folder" :

@media only screen and (max-width: 600px) {
    div{
        background-color: red;
    }
}

@media only screen and (min-width: 600px) {
    div{
        background-color: yellow;
    }
}

run the script and resize the browser window, you will see the rectangle changing color between yellow and red ;-)