Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
NtuiCreator
#41
Mit Vorschriften in der GUI solltest du eher vorsichtig sein. Ich weiss die NTUI Prefs noch nicht gehen, aber dann kann der User besser entscheiden wie es auf seinem System aussieht.
Also das Menu in eine "MenuBar" packen, keine Größenangaben ausser wenn es unbedingt sein muss, kein useAISS, und bei den Images kein TBImage: davor. So sähe das bei mir aus:

[ATTACHMENT NOT FOUND]
Zitieren
#42
Also ich habe mal das ntui_Rethink mit *holder und *engine probiert...

Bekomme da bei *engine aber einen Reaperhit (wegklickbar) aber die Menüs erscheinen trotzdem nicht.
Zitieren
#43
Das mit der Gui werde ich ändern...

TBImages: habe ich doch gar nicht angegeben
Zitieren
#44
Rethink repeart? Hm... Könntest du mir den Source zukommen lassen, damit ich das reproduzieren kann? Ich hatte das auch schonmal, aber bei keinem meiner aktuellen Projekte wo ich das nutze.
Zitieren
#45
Ok, ich glaube ich sehe das Problem.
Das Menu ist nicht sichtbar, aber deine GUI ist bereits offen, richtig?
Dann wird das Layout übersprungen. Ausserdem wird der Fenster Pointer geholt, aber nicht getestet. d.h. der *holder hat ja kein Fenster, wenn er nicht aufgeklappt ist.

Kannst du mir trotzdem mal den Source geben?
Zitieren
#46
Wenn ichs heute abend noch schaffe pack ich das mal und schicks dir zu...
Muss erstmal zum Zahnarzt und dann noch einkaufen, der Hund will auch bespasst werden usw... Confusedhock:

Wo ist sie nur hin, die schöne Zeit.......als man davon noch hatte meinte ich jetzt :?

:lol:
Zitieren
#47
Der Wanderer schrieb:Das Menu ist nicht sichtbar, aber deine GUI ist bereits offen, richtig?

Ich mache das so, ich generiere die engine, lese dann die Gadgets ein und erst dann zeige ich die fertige GUi per ntui_ShowWindow.
Aber das siehste ja dann im source
Zitieren
#48
So, Source ist gerade raus an dich, nun muss ich zum Doc

bis dann 8-)
Zitieren
#49
Das ist ein - sagen wir mal Bug - im SubMenu. Das SubMenu erlaubt es nicht, direkt Child Objects dranzuhängen, da es automatisch ein Fenster als Child hat. Eigentlich müsstest du es also an das Fenster hängen, welches das Child vom SubMenu ist. Da kommst du aber nicht ran. Das ist hässlich, da muss ich mir was überlegen.

Es funktioniert, wenn du eine Gruppe unter das SubMenu hängst, und dort die "Holder" Id angibst:
Code:
            <MenuTitle Label='Objects' image='button'>
                <SubMenu Label='Gadgets'>
                    <VGroup id='NCGadgetListHolder'>

Fragment.xml: ====================================================== snip!
<MenuItem id='NCGadgetListItem' image='button' onClick='AddTag' />
==================================================================== snap!

                    </VGroup>
                </SubMenu>
                <MenuItem Label='Comment'     onClick='AddComment'/>
                <MenuItem Label='Engine'      onClick='AddTag'/>
                <MenuItem Label='Requester'   onClick='AddTag'/>
                <MenuItem Label='Window'      onClick='AddTag'/>
            </MenuTitle>

... und der AB3 code:
[ab3]Case "AddTag"
*obj.tuiObject = ntui_GetNotifyObject{*Notify}
If *obj
ntui_GetAttr{*obj, #TUIMIA_LABEL, &*tagNameP.b}
If *tagNameP Then name.s = Peek$(*tagNameP) : Else name = ""
If tagName><""
creator_SetCursorText{"<"+tagName+" />"}
creator_ScanAttributeToListView{tagName}
End If
End If[/ab3]

Dann brauchst du für Tags nur *einen* Notify String, da der Tag-Name aus dem Label geholt wird.
Ob die nun kapitalisiert sind oder nicht hängt davon ab, wie du das Label setzt oder nachbearbeitest. Ich würde lowercase bevorzugen.

Der Scanner sieht dann so aus:
[ab3]Statement creator_ScanGadgetClasses{layoutPath.s}
; Prerequisites
holderId.s = "NCGadgetListHolder"
itemId.s = "NCGadgetListItem"
layoutFile.s = dos_AddPart{layoutPath,"NCMenuItemFragment.xml"}

; Get the menuitem holder
*holder.tuiObject = ntui_GetObjectByID{*engine,holderId}
If *holder = Null
error{holderId+" not found!"}
Statement Return
End If

; Scan the class names
*shclass.ntuiScanHandle = ntui_BeginScanClasses{""}
Repeat
className.s = ntui_GetNextScanName{*shclass}
If (className)
; Build menuitem fragment
*fragment.tuiObject = ntui_BuildFromXMLFile{*holder,layoutFile}
If *fragment
; find the actual menuitem object
*item.tuiObject = ntui_GetObjectByID{*fragment,itemId}
If *item
; set the label to the class name
ntui_SetAttr{*item,#TUIMIA_LABEL,&className}
Else
error{itemId+" was not created in " + layoutFile + "!"}
EndIf
Else
error{"Unable to build fragment from " + layoutFile + "!"}
EndIf
EndIf
Until className = ""

ntui_EndScan{*shclass}

End Statement[/ab3]
Zitieren
#50
Ein paar sog. "Nit-Picks":

A) IT Sprache ist Englisch (ich weis, ich weis...)

B) Typos: "Menu" ("Menue" = Speisekarte), "Cancel", "Prepare"

C) Keine globalen Variablen. Zumindest nicht mit SHARED innerhalb einer Funktion, da man dann die weis, was man kriegt. Eine Ausnahme kann man mit dem App-Context machen, aber der sollte auch wirklich nur dort verwendet werden, wo man keine Wiederverwertbarkeit braucht (also Library API). Um den Effekt einer Funktion zu beeinflussen, hat man Parameter!

D) Am Ende eines "Select" sollte immer ein "Default" stehen, um sicher zu gehen nichts zu "verpassen". Im Falle des Notify Selects solltest du eine Fehlermeldung machen, z.B.
[ab3]...
Case "NCActive" ; <- ist mir gleich aufgefallen dass du das nicht testest!
Default:
error{"Unhandled notification: " + ntui_GetNotifyID{*Notify}}
End Select[/ab3]

E) Der-App Context besteht normalerweise aus drei Teilen:
1. Preferences (werden i.A. nur gelesen, schreiben darf nur eine Preferences-Funktion wenn man auf "Apply" drückt oder vom Icon/Configfile lädt.
2. State (da darf rücksichtslos geschrieben und gelesen werden, ist aber nicht Teil der Preferences (die gespeichert werden), sondern ausschliesslich Laufzeitinformationen. Der State sollte möglichst klein gehalten werden. (State-Automaten Hölle!)
3. Datenbank (dort werden die zu manipulierenden Daten verwaltet, idealerweise völlig unabhängig von der GUI, abgekapselt über eine API, damit man nicht an ein bestimmtes GUI System gebunden ist, und es lässt sich leicht ein Commandline Interface oder AREXX Schnittstelle bauen.

F) XML tags und parameter sind Case-Insensitiv. Z.B. schlagen deine Tests nach der Fenster ID fehl:
[ab3]tagname.s = _ntui_NextXMLTag{*tf}
If tagname = "Window"
...[/ab3]

besser:
[ab3]tagname.s = _ntui_NextXMLTag{*tf}
If lcase$(tagname) = "window"
...[/ab3]

G) Daten selbser parsen sollte man nicht. Da kann wahnsinnig viel schief gehen. Vielleicht entscheiden wir uns ja morgen für JSON als GUI definition, dann geht der Code nicht mehr.
Du kommst auf die Fenster einfacher indem du einfach die Engine durchsuchst.
[ab3]Statement creator_ShowAllWindows{*engine.tuiEngine}

*obj.tuiObject = ntui_GetChildObject{*engine}
While *obj
ntui_GetAttr{*obj, #TUIA_CLASSID, &classId.l}
If (classId = #TUICLASS_WINDOW)
ntui_ShowWindow{(.tuiWindow)*obj}
End If
*obj = ntui_GetNextObject{*obj}
Wend

End Statement[/ab3]

H) Die *engine für das Testen sollte eine andere sein als die Engine des NTuiCreators.
Dafür machst du einfach in creator_ShowWindow:
[ab3]If (creator\state\testEngine) Then ntui_Free{creator\state\testEngine}
creator\state\testEngine = ntui_BuildFromXMLMem{Null,*TextBox\doc\text}[/ab3]
Sonst kann dir die GUI den NTuiCreator zerschiessen, ausserdem willst du sie auch einfach wieder löschen können.

I) *TextBox\doc\text ist kein "legaler" Weg um an den Text zu kommen. Generell darfst du nicht auf die Newtypes zugreifen.
Du müsstest dir den Text holen mit
[ab3]ntui_GetAttr{*TextBox, #TUITBA_TEXT, &*textP.b}[/ab3]
Leider bekommst du derzeit nur die erste Zeile, ich werde das gleich ändern.

J) "ntui_Rethink" wird nur benötigt, wenn du eine *sichtbare" GUI manipulierst, also Objekte löschst oder hinzufügst. Wenn du nur ein Attribute änderst, musst du normalerweise nichts tun.

Habe dir den Code zurückgeschickt, am besten mal mit WinMerge o.ä. Tool diffen damit du siehst was ich geändert habe.
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 3 Gast/Gäste