Native Options Menu

BogDan bog_dan_ro at yahoo.com
Thu Feb 16 13:21:42 UTC 2012


Hi,

+ necessitas-devel  in CC

  I believe our goal should be to easily port an application *and* that application should look and fell the same with native applications, otherwise Android users will fell the difference and some (most) of them will reject any application which looks odd. So IMHO we should focus on this matter.


  Regarding active window thing, yes I've seen that message, but I didn't had time to dig more and to find a proper solution. A quick and dirty solution will be to set the last top level widget as the active one, but sounds too easy to be the right solution :).

Cheers,
BogDan.

________________________________
From:  Marijn Kruisselbrink <mkruisselbrink at kde.org>; 
To:  BogDan <bog_dan_ro at yahoo.com>; 
Cc:  Chris Browet <cbro at semperpax.com>; 
Subject:  Re: Native Options Menu 
Sent:  Thu, Feb 16, 2012 7:27:55 AM 


I don't have a particularly strong opinion either way, for my purposes having 
just QMainWindow be able to have a menu would be fine, but that might indeed 
not be flexible enough. For QML and android 3.x and later we might want to 
somehow expose some sort of actionbar api to get among other things a "native" 
option menu? Although I'm not sure what our goal there is, minimal effort to 
port an application, or being able to use qt/qml to make an app that looks and 
feels native?

For the activeWindow issue, there is actually a comment in QWidget::destroy in 
qwidget_qpa.cpp "we don't have proper focus event handling yet" in one of the 
places where activeWindow should be updated to some correct value, but is 
always set to 0 instead. Not sure how hard it would be to fix that though (not 
sure if there is anything in Qt5 that solves the
problem in a way that might 
be back-portable).

Marijn

On Wednesday, February 15, 2012 02:29:35 PM BogDan wrote:
> Hi Chris,
>  
> 
> >Hi BogDan,
> >
> >I think your approach is too restrictive for at least 2 reasons:
> >
> >1) If only QMainWindow is taken into account, it would be impossible to
> >create an options menu for, e.g., a QDialog descendant
> 
> You are right !
> 
> >2) I already coded a mechanism in the QML components for Android that
> >would allow to display an options menu in QML, too. It involves adding
> >QAction's to the QDeclarativeView (not via a QMenuBar).
> 
> I'll try to backport platform menu from Qt5 [1], this way you can set the
> menu easily from QML and it will fix the first issue as well.
> 
> 
> 
> Cheers,
> BogDan.
> 
> 
> [1]
> http://qt.gitorious.org/qt/qtbase/blobs/master/src/widgets/kernel/qplatfor
> mmenu_qpa.h
> 
> >- Chris -
> >
> >
> >On Wed, Feb 15, 2012 at 11:23, BogDan <bog_dan_ro at yahoo.com> wrote:
> >
> >Hello everyone,
> >
> >>  First and foremost I'd like to thank you for your work !
> >>
> >>  I almost finish the review, I've done some trivial changes to your
> >>code. I want to discuss with you a particular change which I'm not very
> >>sure it's ok. It's about "prepareOptionsMenu" which I'd like to simplify
> >>it a little bit.
> >>
> >>  The biggest change in that function is that
I suppose that *ONLY* a
> >>QMainWindow may have menus, and *ONLY* if that window is the active one
> >>I'm going to show the menu.  Of course I must fix the
> >>QApplication::activeWindow() issue first :) !
> >>
> >>
> >>Here is the new code:
> >>
> >>
> >>static jboolean prepareOptionsMenu(JNIEnv *env, jobject /*thiz*/, jobject
> >>menu) {
> >>    // remove all actions from the menu first
> >>    env->CallVoidMethod(menu, s_menu_removeGroup, menuGroupId);
> >>
> >>    // if the main window is not the active one (e.g a dialog is
> >>displayed), don't show the menu !  const QMainWindow* window =
> >>qobject_cast<QMainWindow*>(QApplication::activeWindow()); if (!window ||
> >>!window->menuBar())
>
>>        return JNI_FALSE;
> >>
> >>    QList<QAction*> actions = window->menuBar()->actions();
> >>
> >>    // and add actions to menu
> >>    foreach (QAction* action, actions)
> >>    {
> >>        QMenu *subMenu = action->menu();
> >>        if (subMenu)
> >>        {
> >>            QString txt = action->text();
> >>            jstring str = env->NewString(reinterpret_cast<const
> >>jchar*>(txt.data()), txt.length()); jobject submenu = 
> >>env->CallObjectMethod(menu, s_menu_addSubMenu, menuGroupId, jint(-1),
> >>jint(0) /*order*/, str);
env->DeleteLocalRef(str);
> >>
> >>            foreach (QAction* subAction, subMenu->actions())
> >>                addActionToMenu(env, submenu, subAction);
> >>
> >>            env->DeleteLocalRef(submenu);
> >>        }
> >>        else
> >>            addActionToMenu(env, menu, action);
> >>    }
> >>    return JNI_TRUE;
> >>}
> >>
> >>
> >>Let me know if this approach is ok for you !
> >>
> >>
> >>Cheers,
> >>BogDan.


More information about the Necessitas-devel mailing list