next up previous contents
Nächste Seite: Canvas Aufwärts: Die Komponenten Vorherige Seite: Frame   Inhalt


Menu

Hauptbestandteil fast aller graphischen Benutzeroberflächen sind die Menüs, die sich in der Regel am oberen Fenterrand befinden. Dieses Kapitel soll einen Überblick schaffen, wie unter unter Japi solche Menues erstellt und dynamisch verändert werden können. Voraussetzung für die Menüs ist eine Menüleiste, in die die Menüs eingebettet werden koennen. Eine Menuleiste ist mit der Funktion


    j_menubar(int frame);

in einen Frame zu integrieren. Die Funktion liefert einen Identifier zurueck, der für die einzelnen Menupunkte benötigt wird. In diese Menuleiste können nun mit der Funktion


    j_menu(int menubar, char* title);

einzelne Menupunkte eingebaut werden. An jeden Menupunkt werden mit der Funktion


    j_menuitem(int menu, char* titel);

Untermenüpunkte angehängt, die bei anklicken eines Menupunktes sichtbar werden.

Abbildung: Ein einfaches Menü
simplemenu.eps

Mit diesen Funktionen läß sich bereit eine funktionale Menüleiste realisieren. Das folgende Beispiel beschränkt sich zunächst auf einen Menüeintrag mit einem Menuitem:


/* Example simplemenu.c */

#include <stdio.h>
#include "japi.h"

int main()
{
    int frame,menubar,file,quit,obj;

    if(j_start()<0)
        printf("can't connect to server\n"),exit(0);

    frame   = j_frame("");
    menubar = j_menubar(frame);
    file    = j_menu(menubar,"File");
    quit    = j_menuitem(file,"Quit");

    j_show(frame);

    while(1)
    {
        obj =  j_nextaction();
        if((obj==quit) || (obj == frame))
            break;
    }

    j_quit();
    exit(0);
}

Die zeigt die Abbildung 2.2 zeigt die programmierte Oberfläche. An die Menüleiste wurde ein Menü angehängt, das die Beschriftung ''File'' trägt. Wird dieser Menüpunkt angeklickt, so klappt eine Menüleiste auf, die einen weiteren Menüpunkt enthält, der die Beschriftung ''Quit'' trägt. Wird dieser Menüpunkt angewählt, so liefert der Japiserver die Identifikationsnummer dieses Menüpunktes zurück. In der modifizierten Endlosschleife


    obj =  j_nextaction();
    if((obj==quit) || (obj == frame))
        break;

wird nun diese ID ebenfalls berücksichtigt. Sie führt im Beispiel ebenfalls zum Abbruch des Programms, was nicht weiter verwundert.

Die eben vorgestellten Funktionen sind das Grundgerüst aller Menüleisten. Neben diesen Funktionen existieren jedoch noch eine Vielzahl weiterer Funktionen, die weitere Menüpunkte und Modifikationen von Menüpunkten erlauben. Das nächste (schon ausführlichere) Beipielprogramm zeigt alle vorhandenen Menüarten, und einige der Manipulationsmöglichkeiten


    /* Example menu.c */

    if(j_start()<0)
        printf("can't connect to server\n"),exit(0);

    /* Generate Graphical Objects */
    frame    = j_frame(NULL);

    menubar  = j_menubar(frame);
    file     = j_menu(menubar,"File");
    edit     = j_menu(menubar,"Edit");
    options  = j_menu(menubar,"Options");
    submenu  = j_menu(options,"Settings");
    help     = j_helpmenu(menubar,"Help");

    open     = j_menuitem(file,"Open");
    save     = j_menuitem(file,"Save");
    j_seperator(file);
    quit     = j_menuitem(file,"Quit");
    j_disable(save);
    j_setshortcut(quit,'q');

    cut      = j_menuitem(edit,"Cut");
    copy     = j_menuitem(edit,"Copy");
    paste    = j_menuitem(edit,"Paste");

    about    = j_menuitem(help,"About");

    enable   = j_checkmenuitem(submenu,"Enable Settings");
    settings = j_menuitem(submenu,"Settings");
    j_disable(settings);

    j_show(frame);

    /* Waiting for actions */
    while(1)
    {
        obj=j_nextaction();

        if(obj==enable)
        {
            if(j_getstate(enable)==J_FALSE)
                j_disable(settings);
            else
                j_enable(settings);
        }
        if(obj==cut)
        {
            j_gettext(cut,inhalt);
            if(strcmp(inhalt,"Cut")==0)
                j_settext(cut,"Ausschneiden");
            else
                j_settext(cut,"Cut");
        }
        if(obj==copy)
        {
            j_gettext(copy,inhalt);
            if(strcmp(inhalt,"Copy")==0)
                j_settext(copy,"Kopieren");
            else
                j_settext(copy,"Copy");
        }
        if(obj==paste)
        {
            j_gettext(paste,inhalt);
            if(strcmp(inhalt,"Paste")==0)
                j_settext(paste,"Einfuegen");
            else
                j_settext(paste,"Paste");
        }

        if((obj==quit) || (obj==frame))
            break;

    }
    j_quit();

Abbildung: Alle Menüs
menu.eps

Keine Bange, auch dieses Listing ist mit einigen Erläuterungen leicht zu verstehen. Zunächst einmal zeigt die Abbildung diese Oberfläche mit den Obermenüpunkten. Die ersten Zeilen des Programms sind schon bekannt. Neben der Menübar werden zunächst 3 Menüpunkte an diese Menübar angehängt.


    menubar  = j_menubar(frame);
    file     = j_menu(menubar,"File");
    edit     = j_menu(menubar,"Edit");
    options  = j_menu(menubar,"Options");

Sie erscheinen in der Reihenfolge, in der sie erzeugt werden von links nach rechts. Mit dem nächsten Befehl


    submenu  = j_menu(options,"Settings");

wird nun ein Menüpunkt nicht an die Menüleiste, sondern an einen Menüeintrag angehängt. Der Menüpunkt ''Settings'' erscheint somit nicht in der Menüleiste, sondern als Untermenüpunkt innerhalb der Menüleiste ''Options''.

Mit dem Befehl j_helpmenu() wird ein Hilfe-Menüpunkt in die Menübar eingefügt, der je nach Oberfläche auch rechtbündig erscheinen kann. Funktionell gibt es keinen Unterschied zwischen j_menu() und j_helpmenu(), außer daß ein Hilfemenü kein Untermenüpunkt sein kann. Er muß daher immer an eine Menüleiste gebunden werden (siehe Abbildung 2.3).


    help     = j_helpmenu(menubar,"Help");

Der nächste neue Befehl ist j_sepearator(). Dieser Befehl erzeugt eine Trennlinie innerhalb einer Menüauswahl. Mit diesen Trennlinien lassen sich die Menüpunkte übersichtlicher anordnen (Siehe Abbildung 2.4).


    j_seperator(file);     

Mit der Funktion j_disable(save) wird der Menüpunkt ''Save'' disabled, sodaß dieser nun nicht mehr angewählt werden kann. Die Schrift dieses Menüpunktes erscheint in hellgrauer Schrift. Mit der Funktion j_enable() können solche Menüeinträge wieder aktiviert werden. Auf diese Weise lassen sich Menüeintrage temporär als ungültig markieren.

Abbildung: Der erste Menüpunkt mit Seperator, disableten Menüeintrag und Shortcut
menu1.eps

Die nächste Zeile enthält eine Funktion, mir der einzelnen Menüeinträgen sogenannte Shortcuts zugewiesen werden können:


    japi_setshortcut(quit,'q');

Ein Shortcut ist eine Tastaturkombination, die dasselbe bewirkt, wie ein Anklicken den Menüeintrages mit der Maus. Die Kombination besteht immer aus einer Modifier Taste und dem übergebenen Zeichen. Die Modifiertaste ist wiederum vom System abhängig. Unter Unix und Windows ist es die 'Control' (bzw. 'Strg') Taste, unter Macintosh heißt diese Taste 'Command'. Die angegebene Programmzeile bewirkt also, daß das Programm nun zusätzlich durch gleichzeitiges Drücken von Modifiertaste und der Taste 'Q' beendet werden kann.

Die Menüpunkte ''cut'', ''copy'' und ''paste'' werden bei Auswahl ins Englische und bei erneuter Auswahl wieder ins Deutsche übersetzt. Dazu wird in der Eventloop mittels der Funktion j_gettext() der Inhalt der Menüs ermittelt, und entsprechend mit der Funktion j_settext() agiert:


    if(obj==cut)
    {
        j_gettext(cut,inhalt);
        if(strcmp(inhalt,"Cut")==0)
            j_settext(cut,"Ausschneiden");
        else
            j_settext(cut,"Cut");
    }

Abbildung: Der zweite Menüpunkt, bei dem die Menüitems die Sprache wechseln.
menu2.eps

Die Funktion


    enable   = j_checkmenuitem(submenu,"Enable Settings");
 

erzeugt einen Menüeintrag, der zusätzlich mit einer Checkbox ausgestattet ist. Klick man einen solchen Menüpunkt an, so wechselt der Status der Checkbox. Den Status kann man jederzeit mit der Funktion j_getstate() abfragen, und mit j_setstate() setzen. Der Defaultzustand nach den Erzeugen des Menüeintrages ist gesetzt.

Wird das Checkboxmenü ''enable'' vom Benutzter angewählt, so wird zunäscht mit der Funktion j_getstate() der Zustand des Menüs abgefragt:


    if(obj==enable)
    {
        if(j_getstate(enable)==J_FALSE)
            j_disable(settings);
        else
            j_enable(settings);
    }

Ist dieser gesetzt (Returnwert = J_TRUE ), so wird der Menüeintrag ''settings'' enabled. Ist die Checkbox nicht gesetzt, wird dieser Menüpunkt disabled.

Abbildung: Der dritte Menüpunkt mit einem Untermenü und einem Checkboxmenü.
menu3.eps

Wird der Menüpunkt ''quit'' angewählt, so wird die Eventloop verlassen.


    if((obj==quit) || (obj==frame))
        break;

Das Beispielprogramm stellt die wichtigsten Manipulationsmöglichkeiten der Menüeinträge vor. Eine komplette Liste aller möglichen Funktionen ist im Reference Teil bei den jeweiligen Menüelementen beschrieben.


next up previous contents
Nächste Seite: Canvas Aufwärts: Die Komponenten Vorherige Seite: Frame   Inhalt
Merten Joost 2003-02-26