radialmenu — u_pbt_radialmenu #
← Komponentenreferenz · Inhalt des Handbuchs
Radiales Kontextmenü: die Befehle als Kranz um den Cursor, nach Richtung gewählt statt in einer Liste gelesen.
▶ Live ansehen — Demoanwendung, Kachel Radial menu: die Vorschau, der erzeugende Code und diese Seite nebeneinander.
Kurz gefasst #
| Userobject | u_pbt_radialmenu |
| Elementklasse | n_pbt_radialmenu_item (of_item(keys)) |
| Dient zu | Eine Handvoll häufiger Befehle dort anbieten, wo die Hand schon ist |
| Prinzip | Sie beschreiben die Zweige; das Rad, die Form und die Navigation sind unsere Sache |
Schnellstart #
// Ein Rad, gebaut fuer das, was unter dem Mauszeiger liegt
uo_wheel.of_add_item(/*keys*/ "cut", /*text*/ "Cut")
uo_wheel.of_add_item(/*keys*/ "copy", /*text*/ "Copy")
uo_wheel.of_add_item(/*keys*/ "paste", /*text*/ "Paste")
uo_wheel.of_add_item(/*keys*/ "delete", /*text*/ "Delete")
// Es oeffnet sich beim Loslassen der rechten Maustaste: siehe ue_rclicked
Öffnen, dann wählen #
Das Rad öffnet sich beim Loslassen der rechten Maustaste, und erst ein zweiter Klick wählt aus. Das ist kein Implementierungsdetail: Öffnete es sich beim Drücken, würde das Loslassen desselben Klicks sofort den Sektor unter dem Cursor auswählen, und der Benutzer löste einen Befehl aus, ohne ihn je gesehen zu haben.
Deshalb wird of_show() aus dem Rechtsklick-Ereignis des Steuerelements aufgerufen, auf dem die Geste stattfindet (einem statictext, einem button, einem Raster…): Dann ist die Taste bereits oben, und der nächste Klick ist wirklich der wählende. Das radiale Menü selbst hat keine Oberfläche — also auch kein eigenes Mausereignis.
Die Komponente selbst ist unsichtbar: Sie belegt keinen Platz im Fenster. Legen Sie sie irgendwo ab, geben Sie ihr Breite und Höhe null — sie existiert nur, solange das Rad offen ist.
Der angezeigte Zweig — per Maus oder Tastatur — zeigt seine vollständige Beschriftung, über seinen Nachbarn: Ein Sektor behält höchstens zwei Zeilen (eine ab mehr als acht Zweigen), und genau das erlaubt ihm eine kurze Beschriftung, ohne über seine Wirkung zu täuschen. Die Nabe in der Mitte ist der Ausgang: Ein Klick darauf schließt das Rad; in einem Unterrad führt er eine Ebene zurück. Solange das Rad offen ist, läuft die Anwendung weiter: Ein inzwischen entfernter, ausgegrauter oder ausgeblendeter Zweig lässt sich nicht mehr wählen (stattdessen ue_dismissed), und of_clear, of_remove_item oder of_reset schließen das offene Rad.
// Es oeffnet sich beim Loslassen der rechten Maustaste: siehe ue_rclicked
uo_wheel.of_show()
Per Tastatur durchlaufen die Pfeiltasten die Zweige und überspringen ausgegraute, Eingabe oder Leertaste wählt, ← und Rücktaste gehen eine Ebene zurück, und Escape verlässt eine Ebene eines Unterrads — das Rad schließt es nur auf der obersten Ebene. Keine dieser Tasten erreicht die Anwendung, solange das Rad offen ist. Bei Leserichtung von rechts nach links dreht sich der Kranz in die andere Richtung, und ← und → tauschen die Rollen: → geht eine Ebene zurück.
Unterräder #
Eine Adresse hängt Zweige unter einen anderen: export/pdf. Den übergeordneten Zweig zu wählen wählt nichts: Das Rad wird durch das seiner Kinder ersetzt, und die Nabe wird zum Rückweg.
Warum ersetzen statt einen zweiten Ring hinzufügen? Weil ein äußerer Ring die Sektoren auf jeder Ebene halbieren würde. Acht Zweige sind bereits das lesbare Maximum; für zwei Ebenen gleichzeitig ist kein Platz.
Das Ereignis ue_item_selected meldet die vollständige Adresse (export/pdf), nicht den bloßen Blattschlüssel. Zwei Unterräder dürfen ihre Zweige also gleich benennen.
// A branch, then two entries at its address
uo_wheel.of_add_item(/*keys*/ "export", /*text*/ "Export")
uo_wheel.of_add_item(/*keys*/ "export/pdf", /*text*/ "PDF")
uo_wheel.of_add_item(/*keys*/ "export/csv", /*text*/ "CSV")
Um einen Zweig — samt Unterrad — zu entfernen, ohne das ganze Rad neu aufzubauen: of_remove_item("export/csv"). Die anderen Zweige bleiben an ihrem Platz.
Wenn es zu viele Zweige gibt #
Ein Rad wird nach Richtung gelesen, und jenseits von acht Sektoren lassen sich die Segmente nicht mehr unterscheiden. ii_max_sectors setzt diese Obergrenze (3 bis 12, standardmäßig 8).
Darüber hinausgehende Zweige gehen nicht verloren: Der letzte Platz im Kranz wird zu einem Zweig, der sie alle enthält und sich als Unterrad öffnet. Ein Menü, das seinen Rest fallen ließe, wäre ein Menü, das über sein Angebot täuscht.
Den Kranz zu verengen ist oft ein Gewinn: Vier breite Zweige trifft man schneller als acht schmale.
Eigenschaften #
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
ii_max_sectors | integer | 8 | Wie viele Zweige ein Kranz tragen darf (3 bis 12). Was darüber hinausgeht, wandert unter einen letzten Zweig, der sich als Unterrad öffnet. Über acht hinaus wird das Rad dichter (kleineres Symbol, einzeilige Beschriftung), damit sich die Beschriftungen nicht überlappen |
is_theme_style | string | "" | Visueller Stil der Komponente (Konstanten THEME_STYLE_*); leer = der der Anwendung, bei jeder Änderung übernommen |
is_theme_mode | string | "" | Helle oder dunkle Variante (Konstanten THEME_MODE_*); leer = die der Anwendung, bei jeder Änderung übernommen |
il_theme_accent | long | -1 | Akzentfarbe dieser Komponente (-1 = Akzent der Anwendung, sonst der des Designs) |
is_tooltip | string | "" | Einfacher Tooltip. Aus Kompatibilitätsgründen beibehalten: Der Auslöser ist unsichtbar, hat keine Fläche zum Überfahren, und nichts zeigt ihn an |
is_super_tooltip_title | string | "" | Titel des erweiterten Tooltips. Aus Kompatibilitätsgründen beibehalten, nie angezeigt — siehe is_tooltip |
is_super_tooltip_text | string | "" | Text des erweiterten Tooltips. Aus Kompatibilitätsgründen beibehalten, nie angezeigt — siehe is_tooltip |
is_super_tooltip_image | string | "" | Bild des erweiterten Tooltips. Aus Kompatibilitätsgründen beibehalten, nie angezeigt — siehe is_tooltip |
Methoden #
| Methode | Rolle | |
|---|---|---|
of_add_item (string as_keys, string as_text) | Fügt einen Zweig an seiner Adresse hinzu: format/strike hängt unter Format, das bereits existieren muss. Genau diese Adresse kommt in ue_item_selected zurück, wenn er gewählt wird. Liefert 0 nach dem Hinzufügen, -5 wenn die Adresse abgelehnt wird (Elternteil nicht gefunden, Adresse schon vergeben, leere Ebene wie export/ oder /pdf, Schlüssel mit ` | oder beginnend mit __), -2` wenn die Komponente nicht erzeugt ist |
of_add_item (string as_keys, string as_text, string as_image, boolean ab_checked) | Dasselbe, mit Symbol und Markierung — das Symbol als drittes Argument, wie überall sonst in der Bibliothek. Ein Zweig wird über sein Handle ausgegraut: of_item(keys).ib_enabled = false. Liefert 0 nach dem Hinzufügen, -5 wenn die Adresse abgelehnt wird (Elternteil nicht gefunden, Adresse schon vergeben, leere Ebene wie export/ oder /pdf, Schlüssel mit ` | oder beginnend mit __), -2` wenn die Komponente nicht erzeugt ist |
of_clear ( ) | Leert das Rad und gibt die über of_item erhaltenen Handles frei (jedes bezeichnete einen Zweig, den es nicht mehr gibt). Liefert 0 nach der Anwendung, -2 wenn die Komponente nicht erzeugt ist | |
long of_show ( ) | Öffnet das Rad zentriert auf dem Cursor. Aus dem Rechtsklick des Steuerelements aufrufen, das die Geste empfängt. Ein Rad ohne sichtbaren Zweig öffnet sich nicht: ue_dismissed wird ausgelöst. Liefert 0 nach der Anforderung, -2 wenn die Komponente nicht erzeugt ist | |
long of_show (long al_x, long al_y) | Dasselbe, zentriert auf einer Bildschirmposition in Pixeln. Negative Koordinaten sind ein echter Punkt, (-1, -1) eingeschlossen: ein Bildschirm links oder oberhalb des Hauptbildschirms. Liefert 0 nach der Anforderung, -2 wenn die Komponente nicht erzeugt ist | |
of_item (string as_keys) | Liefert das Handle eines Zweigs über seine Adresse, um ihn später zu ändern (Beschriftung, Zustand, Farben). Ein bloßer Schlüssel wird in die vollständige Adresse des einzigen Zweigs aufgelöst, der ihn trägt: of_item("csv") und of_item("import/csv") liefern dann dasselbe Handle. Mehrdeutig oder von keinem Zweig getragen, liefert er ein Handle, das nichts ändert, statt den falschen Zweig. of_key() des Handles liefert den Schlüssel der letzten Ebene | |
of_remove_item (string as_keys) | Entfernt einen Zweig samt Unterrad; die anderen bleiben. Liefert 0 nach dem Entfernen, -5 wenn unter dieser Adresse kein Zweig existiert, -2 wenn die Komponente nicht erzeugt ist | |
of_reset ( ) | Leert das Rad und setzt alle Eigenschaften auf ihren Ausgangswert zurück. Liefert 0 nach der Anwendung, -2 wenn die Komponente nicht erzeugt ist |
Ereignisse #
| Ereignis | Ausgelöst wenn |
|---|---|
ue_item_selected (string as_keys) | Der Benutzer hat einen Zweig gewählt. as_keys ist seine vollständige Adresse (export/pdf), nicht der bloße Blattschlüssel. Ein Ereignis je Geste: Ein Doppelklick wählt nur einmal |
ue_dismissed ( ) | Das Rad wurde geschlossen, ohne dass ein Zweig gewählt wurde: Klick auf die Nabe, Klick außerhalb des Rades, Escape auf der obersten Ebene — und auch, wenn of_show nichts anzuzeigen hatte |
Ein Klick in eine Ecke des Fensters, außerhalb der Scheibe, zählt als Klick außerhalb: Das Rad schließt sich (
ue_dismissed), und der Klick geht an die dahinterliegende Anwendung, statt von einem unsichtbaren Rechteck verschluckt zu werden.
Elementeigenschaften #
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
is_text | string | "" | Beschriftung des Zweigs. Halten Sie sie kurz: Ein Sektor ist ein Segment, keine Zeile, und zeigt höchstens zwei Zeilen — der angezeigte Zweig zeigt seine vollständige Beschriftung. Leer wird der Schlüssel angezeigt |
ib_enabled | boolean | true | Auf false ist der Zweig ausgegraut und sein Sektor ignoriert jeden Klick |
ib_visible | boolean | true | Auf false verlässt der Zweig das Rad — Unterrad inbegriffen — ohne entfernt zu werden; die Sektoren rücken zusammen, und er kommt unverändert zurück. Ein Zweig, dessen Untereinträge alle ausgeblendet sind, bleibt ausgegraut auf dem Rad: Er hat nichts mehr zu öffnen und lässt sich nicht wie ein Blatt wählen |
ib_checked | boolean | false | Auf true markiert ein feiner Bogen unter dem Band den Zweig als aktiv |
il_accent | long | -1 | Akzent dieses Zweigs: sein Band, wenn er angezeigt wird, und seine Markierung (-1 = der der Komponente) |
il_back_color | long | -1 | Band dieses Zweigs im Ruhezustand (-1 = das des Themas) |
il_text_color | long | -1 | Beschriftungsfarbe dieses Zweigs (-1 = die des Themas) |
il_back_color_hover | long | -1 | Sektor dieses Zweigs, während er angezeigt wird (-1 = der des Themas) |
il_text_color_hover | long | -1 | Beschriftungsfarbe dieses Zweigs, während er angezeigt wird (-1 = die des Themas) |
Ein Zweig zeigt keinen Tooltip: Das runde Fenster hat außerhalb seiner Scheibe keinen Platz. Das vom Handle geerbte is_tooltip bleibt erhalten und lässt sich zurücklesen, wird aber nie angezeigt — der angezeigte Zweig zeigt seine vollständige Beschriftung.
Beispiele #
Ein Rad je Kontext #
// Ein Rad, gebaut fuer das, was unter dem Mauszeiger liegt
uo_wheel.of_clear()
uo_wheel.of_add_item(/*keys*/ "bold", /*text*/ "Bold", /*image*/ "mono:img\packimages.dll:svg/samples/bold", /*checked*/ true)
uo_wheel.of_add_item(/*keys*/ "find", /*text*/ "Find", /*image*/ "mono:img\packimages.dll:svg/samples/find", /*checked*/ false)
Auf den gewählten Pfad reagieren #
// Ereignis ue_item_selected des Radialmenues
// as_keys traegt den vollstaendigen Pfad, z. B. "export/pdf"
choose case as_keys
case "export/pdf"
of_export_pdf()
case "delete"
of_delete_selection()
end choose
Markieren, ausgrauen, verengen #
// Mark a branch as being on
uo_wheel.of_item(/*keys*/ "bold").ib_checked = true
// Grey out the one that makes no sense here
uo_wheel.of_item(/*keys*/ "paste").ib_enabled = false
// Hoechstens vier Zweige auf einem Ring
uo_wheel.ii_max_sectors = 4
Bewährte Praxis #
- Beim LOSGELASSENEN Rechtsklick des Steuerelements öffnen, nie beim Drücken. Das trennt das Öffnen vom Wählen, und der Benutzer braucht beides.
- Kurze Beschriftungen. Ein oder zwei Wörter. Der Sektor ist für die Richtung da; der ganze Text ist erst lesbar, wenn der Zweig angezeigt wird.
- Vier bis sechs Zweige schlagen acht. Ein Rad merkt man sich über die Position; je weniger Positionen, desto schneller sind sie gelernt.
- Die häufigsten Befehle nach oben und unten. Das sind die beiden Richtungen, die die Hand ohne Nachdenken trifft.
- Halten Sie die Reihenfolge stabil von einer Öffnung zur nächsten: Der ganze Sinn eines Rades ist, dass die Geste dem Lesen vorauseilt.
- Ein radiales Menü ersetzt kein Listenmenü. Zwanzig seltene Befehle liest man besser in einer Liste; behalten Sie das Rad für die ständig benutzte Handvoll.
Vom gemeinsamen Sockel geerbt #
Diese Mitglieder gibt es bei jeder visuellen Komponente — sie sind nicht dieser eigen. Sie werden einmal in den übergreifenden Kapiteln beschrieben; diese Tabelle sagt nur, wo man sie liest.
| Mitglieder | Rolle | Beschrieben in |
|---|---|---|
of_count · of_keys_at · of_has | Durchlaufen, was die Komponente enthält | 3.2 Die Items |
of_reset | Die Komponente zurücksetzen | 3.6 Eine Komponente zurücksetzen: of_reset() |
of_register_shortcut · of_clear_shortcuts | Tastenkürzel der Komponente | 3.5 Tastenkombinationen |
of_is_created · of_is_ready · of_get_last_error | Ob sie entstanden ist, ob sie bereit ist, was fehlschlug | 3.7 Diagnose |
of_save_as_png · of_save_as_jpg | Die Darstellung als Bild exportieren | 3.8 Die Darstellung als Bild exportieren |
of_set_redraw | Änderungen zu einem einzigen Neuzeichnen bündeln | 3.10 Best Practices |
of_preload_icons | Symbole ohne Verzögerung | Sofortige Anzeige: of_icon |
of_set_translation | Eine Beschriftung der Komponente übersetzen | 5.2 Eine Beschriftung anpassen: of_set_translation |
of_focus_webview | Der Komponente den Fokus geben | 6.4 Tastatur und Fokus |
of_print · of_print_to_pdf | Drucken oder ein PDF schreiben | 6.9 Drucken |
of_set_property · of_get_property · of_component_name | Eine Eigenschaft über ihren Namen steuern | 3.1 Die Eigenschaften-Engine |
Zwei Helfer werden nicht geerbt: of_icon und of_escape_markup liegen auf n_pbt_utils. Deklarieren Sie eines — n_pbt_utils lnv_utils, nichts zu erzeugen — und rufen Sie sie darauf auf.