grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [GITGRUB] New menu interface (second draft)


From: Michal Suchanek
Subject: Re: [GITGRUB] New menu interface (second draft)
Date: Thu, 10 Sep 2009 09:26:25 +0200

2009/9/10 Bean <address@hidden>:
> On Thu, Sep 10, 2009 at 8:38 AM, Michal Suchanek <address@hidden> wrote:
>> hello
>>
>> 2009/9/9 Bean <address@hidden>:
>>> On Wed, Sep 9, 2009 at 6:53 PM, Michal Suchanek<address@hidden> wrote:
>>>> 2009/9/8 Bean <address@hidden>:
>>>>> Hi,
>>>>>
>>>>> After more consideration, perhaps we should use the following
>>>>> component structure:
>>>>>
>>>>> frame - window border
>>>>> panel - layout manager with scroll bar support
>>>>> window - frame + panel
>>>>
>>>> What has window that frame+panel does no have?
>>>>
>>>> I think it is reasonable to just put two elements when this
>>>> functionality is wanted.
>>>
>>> Hi,
>>>
>>> Windows can also has a title bar. Although this function may not be
>>> implemented in the first version, it's better to keep the component
>>
>> What for? It's of some use in complex multiwindow environments where
>> users are hopelessly lost. We do not wan  to get there with grub (and
>> cannot for lack of threading) so it is quite pointless to have a title
>> bar.
>>
>> And in case you do want a titlebar for your window you can add a panel
>> around it with a text label. With the added flexibility that you can
>> change the directions in which elements are packed in the panel at
>> whim even in a theme so you can get the title next to the window
>> content (perhaps to stuff more menu items into a small widescreen).
>>
>
> Hi,
>
> There are other uses for window. For example, you can move/resize the
> window, or click a button to maximize/close it. Although this requires
> mouse support, so perhaps this component can wait until later
> versions.

I don't know why you would move or resize a window. If there is only
one window displayed it should get sized and placed reasonably from
the start. Since grub has no threading you cannot have something like
two applications running in parallel. At least we have nothing
remotely similar to that now and I do not know about any plans for
that either.

>
>>> there. And the frame+panel combo is often used, so having a window
>>> component would make the config file cleaner.
>>
>> If you add a panel border there is much less need for yet another one.
>>
>> And the config is going to be repetitive whatever you do. Adding a
>> keyword and a pair of bracers somewhere is nothing compared to the
>> long kernel argument lists.
>>
>>>
>>>>> label - text
>>>>> image - image
>>>>
>>>> I don't think that image is a useful user-acessible component. Even if
>>>> images are internally rendered differently from text there is no
>>>> reason for image to be a separate component. Grub has no means of
>>>> converting images to ascii art for displaying in text mode. Even if it
>>>> did there is no guarantee that two images that looked distinct
>>>> originally are converted to ascii art blobs that can be told apart.
>>>>
>>>> If you envision using ascii art a lot in grub then perhaps it should
>>>> be implemented as a special graphics format that can be also displayed
>>>> in text console. Still ascii art does not work on dumb terminals,
>>>> braille terminals, etc.
>>>>
>>>> IMHO we should not encourage components that have only graphical (or
>>>> semi-graphical) representation that cannot be represented as plain
>>>> text. If an icon or image is wanted it should be packed into a label
>>>> with a plaintext description. It is possible to hide the description
>>>> when the element is shown on display that can render graphics (or use
>>>> an empty description) but there should be no image-only component.
>>>>
>>>
>>> Originally, I  add image so that component only implement one
>>> function, for example, if we merge label and image, we need to use
>>> switch statement on the attributes to know if it's a label or image.
>>
>> It's not a label or image, it's a label with an image (both optional,
>> you can have anonymous items if you really want I guess). And this
>> will be much more common than a frame with a panel once yous start
>> with images. Putting a Tux (or Mandriva star logo) image next to each
>> Linux kernel menu item would require either an element that can
>> display an image with description or a three element combo panel {
>> image{} text{} } for each item.
>>
>
> Oh, image plus text looks composite component to me, although if it's
> used often enough, we can write a C component to handle this combo.

There are two reasons to make this the basic label component:

 - if you need just text the image is simply omitted at no cost to the user
 - if you want an image and there is only a component that displays an
image and text it should hint the user to also include a description
 - adding icons to boot menu items is probably going to be the most
common use of images so managing the compound in a single component
should ease writing config files
 - you can probably add the image later like

+ panel {
class = main
 + label {
   class = grub_title
   text = Grub $version
  }
 + panel {
  class = boot_menu
  + label {
   class = linux
   action {
    linux /boot/vmlinuz...
 ...

style (class = linux) {
  icon = Tux.png
  icon-position = left
}
>
>>>
>>> But on the other hand, I believe background image is quite common and
>>> could be used by other component, so why not just make background
>>> image an optional parameter for all components. To have a plain image,
>>> we can use a panel with the specific background.
>>
>> Yes, people will certainly want background images and decorations.
>>
>>>
>>>>> button - button
>>>>
>>>> What's the difference between label and button?
>>>> What would the button typically do?
>>>
>>> Button is a panel with text in the middle, it's quite common in dialog
>>> boxes such as YES/NO/CANCE, so I guess it deserves its own component.
>>
>> I don't think so.
>>
>>>
>>> On second through, this component should not be implemented in C,
>>> perhaps we can add component tree so that users can write customized
>>> component in config file, something like this:
>>>
>>> + component
>>> {
>>>  + button
>>>  {
>>>    + panel
>>>    {
>>>      + text
>>>      {
>>>        valign = "center"
>>>        halign = "center"
>>>        text = "$text"
>>>      }
>>>    }
>>>  }
>>>
>>> Then we can create buttons like this:
>>>
>>> + button
>>> {
>>>  text = "hello"
>>> }
>>>
>>> Although implementation is not trivial, so this may be come up in a
>>> later version.
>>
>>
>> Why not just
>>
>> label {
>> class = button
>> text = YES
>> }
>>
>> style (class = button) {
>>>        valign = "center"
>>>        halign = "center"
>> }
>>
>
> Right, for simple types like button, it could be merged with label.
> But it'd still be useful to allow users to create new component type
> in config file by customizing existing components. But this feature is
> not easy to implement, it could be added in a later version.

I think that styling based on some user-defined selectors (shown as
class in the mockups) gives pretty much all you can get this way
without scripting new components in lua or something.

Unfortunately the components written in C probably would not be very
extensible. If I decided I am bored with rectangular panels and wanted
a different shape it would be probably hard to write a new layout
manager for panel in lua and add it to the existing panel.

>
>>>
>>>>
>>>>> list - list box
>>>>
>>>> What's the difference between panel containing multiple labels and a list 
>>>> box?
>>>>
>>>
>>> List box has actions like select an item, jump to next item. And it
>>> could scroll the panel if we jump to items outside the viewport.
>>
>> This should be part of any panel. It should allow selecting any child
>> that can get focus (is or contains a label with a bound action)
>>
>> If you get unexpectedly small screen space you should be able to
>> scroll any panel that does not fit.
>>
>>>
>>>>> edit - multi-line edit box
>>>>
>>>> Yes, this is actually useful compound element. A multiline edit is
>>>> more that a bunch of single line edits stacked inside a panel.
>>>>
>>>> I guess it should be possible to have a single-line edit or password
>>>> edit. Currently grub does not have passwords in gfxterm so no such
>>>> thing is used but they are in planning.
>>>> This is probably also possible by limiting the multiline edit to single 
>>>> line.
>>>>
>>>>> term - terminal emulator  (extends edit component)
>>>>> menu - menu list (extends list box)
>>>>
>>>> How does it differ from a listbox?
>>>
>>> Menu has specific actions like reading the menu items from environment
>>
>> When this would be used?
>>
>>> variable, boot menu item, edit menu item.
>>
>> It should be possible to bind an action ( arbitrary editable list of
>> grub commands ) to any label.
>>
>> It may be desirable to disable editing of some actions or have editing
>> (or even starting) the action protected by password.
>>
>>>
>>>> I would rather have as few elements as possible.
>>>>
>>>> This way the implementation of the elements should be smaller and
>>>> easier to maintain.
>>>>
>>>> Styling the menu should be easier with fewer elements with fewer
>>>> baroque properties and obscure limitations.
>>>
>>> Yep, perhaps some of the above component can be implemented as user
>>> defined component in config file. The UI is quite straightforward,
>>> just stack the components together, but action are a little tricky,
>>> each component should have a set of default handler. Perhaps we need
>>> to export some of the component functions to be used in config
>>> scripts.
>>
>> What the default handler should be?
>>
>> In a GUI with panel and label elements (or similar) the panels should
>> be able to switch between their children that can get focus, and the
>> labels execute their bound action (if any).
>>
>> This means that a handler for executing, editing, and password
>> protecting an action is needed for labels.
>>
>> Getting focus somewhere without a mouse can be tricky so I suggest
>> replicating the functionality present in gfxterm at first: one menu
>> that has focus initially and can be used to select boot commands.
>>
>> Either the menu that gets focus can be specified explicitly (and will
>> be the only element usable except for hotkeys) or a more general
>> solution that determines the correct item automatically can be
>> implemented.
>>
>> To this end first the system should determine which elements can get
>> focus when they are created. Labels without actions do not get focus.
>> Labels with action and a hotkey normally do not need focus so they
>> should not get it unless explicitly specified.
>>
>> If a panel contains a focusable label it can get focus, If it contains
>> only one it cannot switch focus which is somewhat important.
>>
>> A vertically stacked panel (like the menu in gfxterm) that contains
>> only elements that cannot switch focus (labels and single label
>> panels) can handle up and down arrow keys (and perhaps pgup/pgdn) or
>> equivalent by switching focus between its children. Optionally if a
>> vertical panel that only contains horizontal panels it can still use
>> the keys for vertical movement. And the other way around.
>>
>> A panel that contains multiple elements that can switch focus should
>> handle tab key by switching to the next element if it is not on the
>> last element (in which case it will let the parent panel to handle the
>> key). If it also contains an element that cannot switch focus and
>> focus is in that element it can handle directional keys but this
>> situation is generally not desirable and should be prevented by
>> building balanced element structure.
>>
>> Finally a focused label can handle Enter or Space or similar by
>> executing its action (or asking a password first if required) and some
>> hotkey like E by opening action editor.
>>
>> This way you should never notice any trickery with a simple menu like
>> the one in gfxterm but should be able to get to any focusable element
>> of any structure.
>>
>
> The above handling sounds good, but I'd prefer not to use fixed keys.
> Each component can define certain actions, and we bind them to
> specific key using the onkey handler.

I am using the current key bindings in gfxterm to make this clear.
Obviously these can be changed but the default should mimic current
gfxterm to ease transition from older grub.

>
>>>>>
>>>>> We should be able to construct more powerful component using the above
>>>>> simple ones, I'm considering adding a dialog tree:
>>>>>
>>>>> + dialog
>>>>> {
>>>>>  + edit
>>>>>  {
>>>>>    + window
>>>>>    {
>>>>>      class = "edit"
>>>>>      + edit
>>>>>      {
>>>>>      }
>>>>>    }
>>>>>  }
>>>>>  + message
>>>>>  {
>>>>>    + window
>>>>>     {
>>>>>       class = "message"
>>>>>       + label
>>>>>       {
>>>>>         text = $1
>>>>>       }
>>>>>     }
>>>>>  }
>>>>> }
>>>>
>>>> Couldn't this be done as a function in the support shell scripts that
>>>> are used for generating the grub.cfg?
>>>>
>>>>>
>>>>> Then we can use something like this to show a popup message dialog:
>>>>>
>>>>> popup message "Hello World"
>>>>
>>>> What would you report in these popups?
>>>>
>>>> Currently grub messages only happen outside of the menu while booting.
>>>>
>>>
>>> For example, when user press F1, we can show a help box. Or if
>>
>> That sounds useful but I would probably make it a shell function in
>> the library of functions that are used in grub.d like
>>
>> message ()
>> {
>> cat <<END
>> + panel {
>>  class = message
>>  + label {
>>   class = message_text
>>   text = $1
>>  }
>>  + panel {
>>  class = buttonbar
>>  + label {
>>   class = button,ok
>>   text=OK
>>  }
>>  }
>> }
>> END
>> }
>>
>> style (class = message) { direction = bottom }
>> style (class = buttonbar) { direction = left } #stack buttons from the right
>
> Yep, this would be useful. But using tree structure means we can reuse
> the parser for component, otherwise we need to modified sh parser to
> handle the new syntax. It's doable, but require more work, perhaps we
> can delay it until later version.

We don't need a shell parser, it's in the shell already, and we cannot
modify it, it's outside of grub.

I do not get what you meant here.

The shell is already used to execute /etc/grub.d/* and
/usr/lib/grub/grub-mkconfig_lib and there are many utility functions
in /usr/lib/grub/grub-mkconfig_lib for creating grub.cfg snippets.

There is no need to make everything in grub if it's simple enough to
be written in a shell function outside of grub.

Thanks

Michal




reply via email to

[Prev in Thread] Current Thread [Next in Thread]