[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-usability
Subject:    Re: kmenu concept
From:       Eric Ellsworth <whalesuit () softhome ! net>
Date:       2002-06-07 21:12:55
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>
> yes, i was going to add those as well but ran out of time ... attached is
> another revision, based on your revision =)

Getting better...
I really like the Music, Movies, and Media menu - the title helps explain that 
in computers, "Media" refers to stuff like Movies and Music.  And it is a 
natural introduction to adding and changing menu items.  So we should look 
for wording for  "Configure Task Group" that explains (as best you can in 4 
word :} that this is where you add and change programs".  Huh, how about "Add 
and Change Programs"?

> there is a "Configure Task Groups" item, which i envision bringin up a
> dialog that would allow the user to add / remove / edit task groups
> (submenus) .. i'd also like to see these submenus appear as .desktop files
> somewhere in the kicker hierarchy so that various collections of them can
> be provided (e.g. Development, Visual Arts, System Administration,
> Gaming.....) and they can easily be shown/hidden.. 
I was thinking something along these lines, too.  Bear in mind that for any 
managed computer, there are sysadmin-controlled menu items and 
user-controlled menu items, and as someone who sometimes sysadmins, I think 
it's important that the sysadmin be able to control at least some menu items.  

> much like the special menus are shown/hidden.
Can we default these off?  I know lots of people like them, but I think 
they're overkill for a novice.  Let's also:
	Rename "Special Menus" - why are they special, what do they do.  Or put 
another way, what kind of task group are they?
	Turn off Run Command (put in with the Special Menus, with Kicker KCM control) 
by default
	Turn off Lock Screen - I claim (based only on my opinion) that Lock Screen is 
a more advanced command than 
	I might even look for a new home for "Find Files" for total novices.

The attached file makes most of these changes.

> > I've made a few modifications to pass on - mostly just filled out some
> > menus. I thought we could evaluate just putting documents on the Recent
> > Items menu - this is more "document-centric" for what that's worth
>
> ok.. i've moved the Recently Used Applications menu to the Tasks area near
> the More Applications entry ...

Much better - the Recent Applications reminds me of the Apple Menu on old 
Macs.  And I like the menu title "Tasks", followed by a menu item to 
configure the menus.
A couple points.  The word Configure strikes me somewhat intimidating to a 
techneophyte.  Is there another word?  What are the words for arranging your 
kitchen, car, house, VCR, TV, office the way you like them?  Can we use one 
of these phrases instead of "Configure Settings"?
Likewise the word "Task Group" also strikes me as technical.  What words do 
you use to refer to Task Groups in real life?
And I'd substitute the word "Program" for "Application" - same reason, the 
former sounds less technical.

I also noticed that when you pop the menu out into its own window, the titles 
disappear, which makes the items confusing.  How should we handle this?

> > (Cdn$.00001 :)  ).  I also notice when I tried to fill out the Music and
> > Movies - Multimedia seems like a vague term to me that there's lots of
> > disparate actions here
> > Seeing as we're not likely to get all those applications to be condensed
> > any time soon, perhaps we better think about a slightly modified way of
> > addressing this menu....
>
> and that won't be a unique situation either.. i'm thinking the solution
> might be "bite the bullet" and keep the task groups small by default ...

You mean just leave stuff out?  Yeah, I think we'll have to do that.  I'd love 
to be the communications genius that figures out how to present huge numbers 
of words without it being intimdating, but that ain't likely to happen.  
Let's keep it short and easy to add to.

> if there is indeed interest in pursuing this as a kmenu option, i'll merge
> it into kicker as a kmenuext (since that's the easiest to package up) so we
> can play with it with icons and as a part of the panel and commit it
> kdenonbeta so others can access it and hack on it with ease.

Sounds good, but I see a couple issues to address before it's general:
	o Where is the hierarchy of menus read from?  In the case of a KMenu, how do 
you merge sysadmin-generated menus with user-generated menus 
	o A very powerful feature of a menu with a change-apps wizard built in is 
that users classify their applications by configuring it.  I'd really like to 
write a back end that takes advantage of this fact and makes their 
classification available to the rest of KDE.  Without revisiting the kde-look 
metadata wars, let me just point out that this is valuable metadata about 
apps....
	o How does this task and classification scheme work within apps?

> /me looks over at kspread, knowing what this means =(
Oh, you mean make this of general use for other menus... Now that's genius! =)

EE
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9ASHZPdSoslpx+lkRAivEAJ92MbkStEstm5C/77Hrqyl5IzW/aQCgkV3o
xXLMg4m4jIAUX6Q6qJEQ12A=
=HsSH
-----END PGP SIGNATURE-----

["kmenu_playing.cc" (text/x-c++src)]

#include <qcursor.h>
#include <kaboutdata.h>
#include <kpopupmenu.h>
#include <kcmdlineargs.h>
#include <kmainwindow.h>
#include <kmenubar.h>
#include <qmenubar.h>
#include <kapplication.h>
#include <kstdaction.h>
#include <iostream>

class rmbPopup : public KPopupMenu
{
    Q_OBJECT

    public:
        rmbPopup(QWidget* parent = 0, const char* name = 0)
            : KPopupMenu(parent, name),
              m_ctxMenu(0),
              continueCtxMenuShow(true)
        {
            installEventFilter(this);
        }

        ~rmbPopup() 
        {
            delete m_ctxMenu;

            if (s_contextedMenu == this)
            {
                s_contextedMenu = 0;
                s_highlightedItem = -1;
            }
        }

        KPopupMenu* contextMenu()
        {
            if (!m_ctxMenu)
            {
                m_ctxMenu = new KPopupMenu(this);
                connect(m_ctxMenu, SIGNAL(aboutToHide()), this, \
SLOT(ctxMenuHiding()));  }

            return m_ctxMenu;
        }

        void cancelContextMenuShow()
        {
            continueCtxMenuShow = false;
        }

        static int contextMenuFocusItem()
        {
            return s_highlightedItem;
        }

        static QPopupMenu* contextMenuFocus()
        {
            return s_contextedMenu;
        }

    signals:
        void aboutToShowContextMenu(rmbPopup* menu, int menuItem, \
KPopupMenu* ctxMenu);

    protected slots:
        void itemHighlighted(int whichItem)
        {
            if (!m_ctxMenu ||  !m_ctxMenu->isVisible())
            {
                return;
            }

            m_ctxMenu->hide();
            showCtxMenu(mapFromGlobal(QCursor::pos()));
        }

        void showCtxMenu(QPoint pos)
        {
            s_highlightedItem = idAt(pos);

            if (s_highlightedItem == -1)
            {
                    s_contextedMenu = 0;
                    return;
            }

            emit aboutToShowContextMenu(this, s_highlightedItem, \
m_ctxMenu);

            if (!continueCtxMenuShow)
            {
                continueCtxMenuShow = true;
                return;
            }

            s_contextedMenu = this;
            m_ctxMenu->popup(this->mapToGlobal(pos));
            connect(this, SIGNAL(highlighted(int)), this, \
SLOT(itemHighlighted(int)));  }

        void ctxMenuHiding()
        {
            disconnect(this, SIGNAL(highlighted(int)), this, \
SLOT(itemHighlighted(int)));  }

    protected:
        bool eventFilter(QObject* obj, QEvent* event)
        {
            if (m_ctxMenu && obj == this)
            {
                if (event->type() == QEvent::MouseButtonRelease)
                {
                    if (m_ctxMenu->isVisible())
                    {
                        return true;
                    }
                }
                else if (event->type() ==  QEvent::ContextMenu )
                {
                    showCtxMenu(mapFromGlobal(QCursor::pos()));
                    return true;
                }
            }

            return QWidget::eventFilter(obj, event);
        }

        void hideEvent(QHideEvent*)
        {
            if (m_ctxMenu)
            {
                m_ctxMenu->hide();
            }
        }

    private:
        KPopupMenu* m_ctxMenu;
        bool continueCtxMenuShow;
        static int s_highlightedItem;
        static KPopupMenu* s_contextedMenu;
};

int rmbPopup::s_highlightedItem = -1;
KPopupMenu* rmbPopup::s_contextedMenu = 0;

const static int configureMenuID = 1000;

class ctxMenuDriver : public QObject
{
    Q_OBJECT

    public:
        ctxMenuDriver()
        {
        }

        ~ctxMenuDriver()
        {
        }

    public slots:
        void contextualize(rmbPopup* menu, int menuItem, KPopupMenu* \
ctxMenu)  {
            if (menuItem == configureMenuID)
            {
                menu->cancelContextMenuShow();
                return;
            }
            
            QString shortcutText("Create a button on the panel for this \
item");  QString editText("Edit this item");
            QString deleteText("Delete this item");
            QString insertText("Insert a new item");
            
            ctxMenu->clear();
            ctxMenu->insertTitle(QString(menu->name()).append(": " + \
menu->text(menuItem)));  ctxMenu->insertItem(shortcutText);
            ctxMenu->insertItem(editText);
            ctxMenu->insertItem(deleteText, this, SLOT(removeAppItem()));
            ctxMenu->insertItem(insertText);
        }

        void removeAppItem()
        {
            rmbPopup::contextMenuFocus()->removeItem(rmbPopup::contextMenuFocusItem());
  }
};

#include "kmenu_playing.moc.cc"
#include <iostream>
int main(int argc, char* argv[])
{
    KAboutData about("menuExtTest", "menuExtTest", "0.1", "Testing \
KPopupMenu Extensions");  KCmdLineArgs::init(argc, argv, &about);
    KApplication foo;
    KMainWindow* testWindow = new KMainWindow(0);
    foo.setMainWidget(testWindow);
    ctxMenuDriver* driver = new ctxMenuDriver();
    
    rmbPopup* kMenu = new rmbPopup(testWindow, "File Menu");
    kMenu->setKeyboardShortcutsEnabled(true);
    kMenu->insertTitle("Recently Used Documents");
    rmbPopup* recentDocs = new rmbPopup(testWindow, "recentDocs");
    kMenu->insertItem("kmenu_playing.cc");
    //recentDocs->insertItem("kmenu_playing.cc");
    //kMenu->insertItem("Applications", recentApps);
    
    kMenu->insertTitle("Tasks");
    
    rmbPopup* apps = new rmbPopup(testWindow, "Internet");
    apps->setKeyboardShortcutsEnabled(true);
    apps->insertItem("Browse the Web (Konqueror)");
    apps->insertItem("Check Email (Kmail)");
    apps->insertItem("Instant Messaging (Kopete)");
    apps->insertItem("VNC (Keystone)");
    apps->insertItem("FTP (KBear)");
    apps->insertSeparator();
    apps->insertItem("  Other programs like this", configureMenuID);
    KPopupMenu* rmbMenu = apps->contextMenu();
    rmbMenu->insertTitle("Internet Menu Editor");
    QObject::connect(apps, SIGNAL(aboutToShowContextMenu(rmbPopup*, int, \
                KPopupMenu*)),
                     driver, SLOT(contextualize(rmbPopup*, int, \
KPopupMenu*)));  kMenu->insertItem("Use the Internet", apps);
    
    apps = new rmbPopup(testWindow, "Office Work");
    apps->setKeyboardShortcutsEnabled(true);
    apps->insertItem("Word Processing (OpenOffice.org)");
    apps->insertItem("Spreadsheets (Gnumeric)");
    apps->insertItem("Presentations (KPresenter)");
    apps->insertItem("Drawing (The GIMP)");
    apps->insertSeparator();
    apps->insertItem("  Other programs like this", configureMenuID);
    rmbMenu = apps->contextMenu();
    rmbMenu->insertTitle("Office Work Menu Editor");
    QObject::connect(apps, SIGNAL(aboutToShowContextMenu(rmbPopup*, int, \
                KPopupMenu*)),
                     driver, SLOT(contextualize(rmbPopup*, int, \
KPopupMenu*)));  kMenu->insertItem("Office Work", apps);
    
    apps = new rmbPopup(testWindow, "Multimedia");
    apps->setKeyboardShortcutsEnabled(true);
    apps->insertItem("Play music (XMMS)");
    apps->insertItem("Watch movies (aKtion)");
    apps->insertItem("Download Music (KNapster)");
    apps->insertItem("Record CD onto my computer");
    apps->insertSeparator();
    apps->insertItem("  Other programs like this", configureMenuID);
    rmbMenu = apps->contextMenu();

    rmbMenu->insertTitle("Multimedia Menu Editor");
    QObject::connect(apps, SIGNAL(aboutToShowContextMenu(rmbPopup*, int, \
                KPopupMenu*)),
                     driver, SLOT(contextualize(rmbPopup*, int, \
KPopupMenu*)));  kMenu->insertItem("Music, Movies and Media", apps);
    kMenu->insertItem("More Applications", apps);

    rmbPopup* recentApps = new rmbPopup(testWindow, "recentApps");
    recentApps->setKeyboardShortcutsEnabled(true);
    recentApps->insertItem("Lt. Skat");
    recentApps->insertItem("Konsole");
    recentApps->insertSeparator();
    recentApps->insertItem("Configure This Menu", configureMenuID);
    
    apps = new rmbPopup(testWindow, "More Applications");

    apps->insertSeparator();
    apps->insertItem("Configure This Menu", configureMenuID);

    kMenu->insertSeparator();
    kMenu->insertItem("Change groups of tasks");
 
    /*    kMenu->insertTitle("Special Menus");
    rmbPopup* specialMenu = new rmbPopup(testWindow, "KPrint");
    kMenu->insertItem("Run A Command..."); 
    kMenu->insertItem("Printing", specialMenu); */

    kMenu->insertTitle("Getting Started");
    kMenu->insertItem("Help");
    kMenu->insertItem("Set up your desktop (Control Center)");
    kMenu->insertItem("Find Files");
    kMenu->insertItem("Home ($username's Personal Files)");
    kMenu->insertSeparator();
    /*    kMenu->insertItem("Lock Screen"); */
    kMenu->insertItem("Logout $username");
    kMenu->insertTearOffHandle();

    KStdAction::quit(kapp, SLOT(quit()), testWindow->actionCollection());
    testWindow->menuBar()->insertItem("KMenu", kMenu);
    testWindow->show();
    int rc = kapp->exec();
 
    
    delete driver;
    return rc;
}

/*
 /usr/lib/qt3/bin/moc kmenu_playing.cc -o kmenu_playing.moc.cc
 g++ -o kmenu_playing kmenu_playing.cc -L/usr/lib/qt3/lib -L/opt/kde3/lib \
                -lqt-mt -lkdeui -lkdecore -I/usr/lib/qt3/include \
                -I/opt/kde3/include
 ./kmenu_playing
 */


_______________________________________________
kde-usability mailing list
kde-usability@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-usability

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic