Startseite
Amiforce 2.1     Amiforce-News Amiforce-News Amiforce-Forum Amiforce-Forum Amiforce-Chat/IRC-Chat Amiforce-Chat/IRC-Chat Gästebuch Gästebuch Kontakt mit dem Webmaster aufnehmen Kontakt mit dem Webmaster aufnehmen

Amiblitz3
Amiblitz2(alt)
Storm Wizard
Abakus-Design
Helpguide
Toolsguide
Tipps&Tricks
Gamesfun
Links
Download
Musik

Bugfixes am Forum
Subdomains aktiviert
Counterscript entfernt
  Navigation:   Index / 
Amiforce Forum - Project: NTUI - a GUI Toolkit
Registrierung Häufig gestellte Fragen Suche Mitgliederliste Moderatoren und Administratoren Startseite Bugtracker Chat Irc
Amiforce Forum » AmiBlitz2/3 (Archiv) » Projekte (Vorstellung) (Archiv) » Project: NTUI - a GUI Toolkit » Hallo Gast [registrieren|anmelden]
« Vorheriges Thema | Nächstes Thema » Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Autor
Beitrag
Der_Wanderer
Foren Gott




Dabei seit: März 2006
Herkunft: Karlsruhe, Baden-Württemberg
Beiträge: 3564
  Project: NTUI - a GUI ToolkitAntwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Der_Wanderer suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Welcome all!

I present this project in English, since it may be of a quite wide interest, also across Amiblitz3 borders.

NTUI (New TUI) will be a new gui toolkit based on TUI (Thilo's User Interface), which is currently available as Amiblitz3 sourcecode (tui.include).
Example Applications for TUI are HD-Rec, ScreenCam, PerlinFX, TuiTED, PostED etc.

Whereas "based on TUI" means concept-based, not sourcecode-based. NTUI is a complete re-write from scratch, eleminating all the nasty traps and glitches, and the inflationary amount of functions of TUI that are a result of the "evolutionary" development rather than "planned" developement. This is probably the main reason, why nobody (except me) used it before.

So as I said, NTUI iswell structured and ready to be extended by user written Widgets, that could be re-used by everybody.

What kind of other Toolkit it will be based on? , you might ask.
Will it use GadTools, Reaction, MUI, Feeling or what?
The answer is it *might* use ALL of them, if someone writes a "backend" for it.
For the first shot, it will use NONE of them, it comes with its own, simple rendering engine, and later a skinned rendering will follow.

Here are the reasons why I do this at all:
- fun fun fun (I think this is obvious)
- MUI and Reaction are dead on OS3.x, but we want more than the dead can offer: 24bit gfx, skins etc.
- Feelin is ok, but it doesn't work correct on my machine, at least the Aminet Version
- Gadtools/StormWizzard are old, don't support 24bit either, many features are out-dated (string gadget, cycle gadget)
- Amiblitz3 needs a new, fresh GUI system that works on all target Platforms without problems, workarounds or hacks

What I want from the GUI Toolkit:
- easy programming interface, no more functions/parameters than necessary
- optimized internal refresh, that means the programmer doesn't need to take care to avoid duplicate refreshes
- all the standard widgets like Button, CheckBox, String, Cycle etc.
- ... plus some more, like a real multiline TextBox
- nice look with 24bit support, but should also work on a 4 color WB Screen
- auto layout is a must - developers should not start to count pixels
- source code level integration in Amiblitz3 programs (means never problems with missing libraries or wrong versions)
- centralized TUI Preferences
- improve all the anoying glitches from the past:
* Copy&Paste for String Gadget
* 1:1 homogenious look for all button types
* REAL cycle Gadget that doesn't need Cycle2Menu patch
* direct AISS support that developers don't need to be GFX artists anymore to have nice images
- support for Drag&Drop and Iconify without doing some extra work
- advanced stuff like docking/undocking of toolbars etc.
- integrated AREXX Port that pipes in the same message loop
- Mouse-Over Effects without extra work
- Bubble-Help without extra work
- fully Keyboard controllable without extra work

What others might want from the GUI Toolkit:
- a GUI builder
- a shared library so that other languages can use it
- open source code, so everybody can improve it anytime
- complete independency from other BlitzLibs/Includes, for smooth migration
(means you still can have Blitz Windows, use "Event" or intuition.inlcude etc., the NTUI message loop is entirely encapsuled)

I try to satisfy all those needs.
If anybody wants to extent this list, please go ahead while I am developing it.

I will present the GUI toolkit step by step as a Tutorial, while I am implementing the various features.
If you give immidiate feedback, we can avoid a confusing API.

Let's start...

P.S.: @Helmut: bitte keine Meldung draus machen bis es nicht fertig ist, danke!


__________________
Check out http://www.hd-rec.de !

Dieser Beitrag wurde von Der_Wanderer am 14.10.2008, 11:17 Uhr editiert.

13.10.2008, 16:29 Der_Wanderer ist offline   Profil von Der_Wanderer Füge Der_Wanderer deiner Freunde-Liste hinzu Email an Der_Wanderer senden Homepage von Der_Wanderer
Der_Wanderer
Foren Gott




Dabei seit: März 2006
Herkunft: Karlsruhe, Baden-Württemberg
Beiträge: 3564
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Der_Wanderer suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Lesson#1: At the beginning, there was a Button...
------------------------------------------------------

No wait, actually there needs to be a Window first, where the Button can be placed! And the more I think about it, there needs to be a "Context" that knows about the Window and can iconify it, query IDCMP messages and so on. This is the tuiEngine.
And how to create the tuiEngine? This is a function of the ntui.library, or ntui.include if we are programing Amiblitz3.

Here is how the hirarchy looks like:



Let's watch the image for a while, looks maybe confusing at the first sight.

So what we have is the ntui.library, which is currently programmed in Amiblitz3, but in a very portable, C-Style way. To be a true library, the code needs to be completely re-entrant, no global objects are allowed. This is why we cannot follow the Basic concept of fix ID numbers (what if two programs want to use Window #5?), but you will see that it doesn't matter, it'll be still easy. The ntui.include does not conflict with any Blitzlib, because it doesn't use any of them. You can even still have a message loop listening to IDCMP Events from a BlitzBasic window, while using NTUI in parallel. Or use 2 tuiEngines in parallel (does that makes any sense? on two different screens, perhaps).

What we need to do first is to create such a tuiEngine, that can hold all our GUI data:

code:

*tuiEngine.tuiObject = ntui_CreateEngine{"MyEngineName"}


Note that all "objects" within a tuiEngine are "tuiObject"s, including the tuiEngine itself. That means a window is a tuiObject, a button is a tuiObject and so on, and all have a standard behavoir like setting the size, querying a string or a value, having parents, children or neighbours etc.
So if you are not interessted in the type of the tuiObject, just cast it to .tuiObject. Every tuiObject has a special NewType, if you need access to it's specialized data, like .tuiEngine, .tuiWindow, .tuiButton etc.
They are all linked among each others, so if we want to change a tuiObject, it knows by itself on which window to redraw at what position, and what other tuiObjects might be influenced.

Once we have the engine, we can start to create a window:
code:

If ntui_BeginWindow{*tuiEngine,"MyWindow",#TypeID}
   ...
  ntui_EndWindow{}
EndIf



Because we don't want tons of parameters, the most important information is cached while we build the window. This is why we have a "Begin" and "End".
Everything declared within belongs implicitly to this window.
Note that we also have a window title and a TypeID. This is an ID you can freely choose, that identifies the window's type. If you try to open a window with the same typeID twice, ntui_BeginWindow will return False and pop the existing window to front instead of creating a new one. Of course we can have more than one window of the same type, we will see later how this works.

Example:
code:

If ntui_BeginWindow{*tuiEngine,"MyWindow",#typeID}
  ntui_Button{"Click Me!",#notifyValue}
  ntui_EndWindow{}
EndIf


And here it is: a tuiButton. It has a text and a notification value.
The concept is easy:

Instead of telling you "Button #124345 on Window #62415 was pressed up/down!", the tuiEngine will interpret the IDCMP Events and tell you "Event xzy has happended!". The xzy is the notification value. This is because we are actually not interessted if the event comes from a button, a menu entry or somewhere else, and even less interessting is some internal ID of the button or position in the menu layout. What we want to know is what the meaning is to us, what we should do, e.g. close a window, open an ASL requester etc. And this is represented by the notification value that will be entirely defined by YOU.

And now we are already arrived at the message loop:

code:

quitme.l = False
While quitme=False
  Wait_ -1
  While ntui_MoreEvents{*tuiEngine}
    Select ntui_GetEventNotify{*tuiEngine}
      Case #NOTIFY_TEST  : message{"User hit the button!"}
      Case #NOTIFY_CLOSE : quitme=True
    End Select
  Wend
Wend

;/* free the tui engine */
ntui_FreeEngine{*tuiEngine}
End



The "quitme" variable is False as long as we want to run our application.
If the window is closed, we jump out of the loop and exit. ntui_FreeEngine will close all windows and cleanup the mess we left behind, like releasing pens, freeing images or closing fonts.

The function "ntui_MoreEvents" must be asked for events until it returns False.
With "ntui_GetEventNotify" we get the ID we have choosen for a special event.
We can ask further questions from which window and which button the event came from (ntui_GetEvent???), but often this is not really important.
If we receive the notification that we should quit our application, we don't need to know were it came from (and don't have the work to find that out).

And here is a small demo combining all what we have learned so far:
(Ooops, I forgot to introduce the tuiLabel, it's as you might guess a tuiObject that just displays some text).

code:

XINCLUDE "ntui.include.bb2"

#WINID_DEMO = 1  ;/* our demo window ID */
#NOTIFY_TEST = 1 ;/* our demo notify values */

WbToScreen 0 : *scr.Screen = Peek.l(Addr Screen(0)) ;/* get the workbench screen */

*tuiEngine.tuiEngine = ntui_CreateEngine{"Demo",*scr} ;/* create a new ntui engine */
If *tuiEngine=!_NULL Then error {"Unable to initialized Engine!"} : End ; Ooops!

If ntui_BeginWindow{*tuiEngine,"Demo Window",#WINID_DEMO} ;/* create the demo window */
  ntui_BeginHGroup{2,"Group"}
    ntui_Label   {"myLabel",#TUIF_RIGHT}
    ntui_Button  {"myButton",#NOTIFY_TEST,"click this button to see how notification works!"}
  ntui_EndGroup{}
  ntui_EndWindow{}
End If

ntui_ShowWindowByID{*tuiEngine,#WINID_DEMO} ;/* show the window */

quitme.l = False
While quitme=False  ;/* main message loop */
  Wait_ -1 ;/* wait until something happens... */
  While ntui_MoreEvents{*tuiEngine} ;/* go for all pending events...*/
    Select ntui_GetEventNotify{*tuiEngine} ;/* get the notify value we defined */
      Case #NOTIFY_TEST  : message{"User hit the button!"}
      Case #NOTIFY_CLOSE : quitme=True ;/* #NOTIFY_CLOSE is pre-defined */
    End Select
  Wend
Wend

ntui_FreeEngine{*tuiEngine} ;/* free the tui engine */

End ;/* that's it, we are done! */



The only new thing here is ntui_ShowWindowByID, it shows the window that is initially hidden while it is created.
You can show and hide windows without re-building them. You can also manipulate tuiObjects as if the window was open, when it is actually hidden.
To hide a window, use ntui_HideWindowByID.
Actually, we don't care if a window is hidden or shown. This makes iconification possible, without extra work, means your application can continue acting as if the GUI was open. (no thousands of "If gui_is_open Then ...")

So far the first lesson. If you implement the above, the result is a tiny, but full grown application that looks like this:

Download: http://hd-rec.de/Archive/ntui_lesson1.lha


__________________
Check out http://www.hd-rec.de !

Dieser Beitrag wurde von Der_Wanderer am 14.10.2008, 19:50 Uhr editiert.

14.10.2008, 12:45 Der_Wanderer ist offline   Profil von Der_Wanderer Füge Der_Wanderer deiner Freunde-Liste hinzu Email an Der_Wanderer senden Homepage von Der_Wanderer
Andi
Routinier



Dabei seit: Dezember 2007
Herkunft: Dresden/Sachsen
Beiträge: 255
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Andi suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Wanderer,
this is very impressive!

I hope you will never lose track of this project. I think it will take a very long time to fulfill all the goals and to develop a new GUI toolkit. And all this work only for 68k!?

Good luck and have fun!

Andi

14.10.2008, 12:51 Andi ist offline   Profil von Andi Füge Andi deiner Freunde-Liste hinzu Email an Andi senden
Honitos
König




Dabei seit: Mai 2002
Herkunft: Hambühren/Niedersachsen
Beiträge: 968
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Honitos suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

@Wanderer:
I can't wait to experience that thing !

I am going to convert all my software (including AB3 itself) to that engine. I'd like to assist you in creating a Designer similar to StormWizard !


__________________
On the web at http://www.programmed-excellence.de

14.10.2008, 14:17 Honitos ist offline   Profil von Honitos Füge Honitos deiner Freunde-Liste hinzu Email an Honitos senden
Andi
Routinier



Dabei seit: Dezember 2007
Herkunft: Dresden/Sachsen
Beiträge: 255
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Andi suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

@Wanderer:

What about a simplified localization feature (catalog support or such)?

14.10.2008, 16:54 Andi ist offline   Profil von Andi Füge Andi deiner Freunde-Liste hinzu Email an Andi senden
Gast
unregistrierter Benutzer



Dabei seit:
Herkunft:
Beiträge:
  Antwort mit Zitat Beitrag editieren/löschen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

@Der Wanderer

yes Sir !!!
thats very interessting at this Point, but, who is it to play with it ?

Localisation is a must by a new Toolkit

14.10.2008, 18:10  
Der_Wanderer
Foren Gott




Dabei seit: März 2006
Herkunft: Karlsruhe, Baden-Württemberg
Beiträge: 3564
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Der_Wanderer suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Yes, support for catalogs in an easy way (=no or minimum extra work for the developer) is  a good idea.
I will add this once it is powerful enough for the real world.

I also forgot to mention that it can be easily done to launch a gui from an .xml defined file. That would be the format the GUIBuilder would store GUIs.

e.g. our Tutorial Example:

code:

<window title="Demo Window">
  <hgroup title="Group">
    <label text="myLabel" align="right">
    <button text="myButton" notify="TEST" help="click me to see how notification works!">
  </hgroup>
</window>



Thats pretty much 1:1 what the API is doing.
Instead of creating a GUI directly, you would do then
ntui_CreateWindowFromXML{xmlfile.s}
.. or something like that.

Only thing that worries me is how to provide notification values.
Because we can not create constants on-the-fly.

One solution would be to use 4-Byte identifiers, e.g.

"TEST", "QUIT", "DATA", "ADDX", "REMX", "ASLR"

etc., that could work as notification values if interpretet as a long.


__________________
Check out http://www.hd-rec.de !

Dieser Beitrag wurde von Der_Wanderer am 14.10.2008, 18:27 Uhr editiert.

14.10.2008, 18:21 Der_Wanderer ist offline   Profil von Der_Wanderer Füge Der_Wanderer deiner Freunde-Liste hinzu Email an Der_Wanderer senden Homepage von Der_Wanderer
Andi
Routinier



Dabei seit: Dezember 2007
Herkunft: Dresden/Sachsen
Beiträge: 255
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Andi suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Zitat:
Original von Der Wanderer
Yes, support for catalogs in an easy way (=no or minimum extra work for the developer) is  a good idea.
I will add this once it is powerful enough for the real world.



Thanks. I would suggest to implement it as an optional parameter. So it could easily be added after the GUI creation step or for quick and simple written examples for instance. If this makes sence at all, I mean.

Dieser Beitrag wurde von Andi am 14.10.2008, 21:59 Uhr editiert.

14.10.2008, 21:56 Andi ist offline   Profil von Andi Füge Andi deiner Freunde-Liste hinzu Email an Andi senden
bernd_
Haudegen



Dabei seit: Oktober 2008
Herkunft:
Beiträge: 561
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von bernd_ suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

most important stuff for a gui system to make it user friendly and not only for experts is a GUI Editor.

If there is no GUI editor it is only for experts and users that have much patience usable.

so i think near nobody use today a basic that have no GUI designer.

if a window need test, a gui designer work in realtime, mui und tui need a recompile and a start od prgram.

this cost lots time, and non experts user dont know exact howthe gui look.they do try and error.

and because a try and error step cost somany time, many loose fun to code.

outside amiga world also in C most coders use GUI.

maybe you take a look at XUL.it need not compile the whole program again input can be xml or a gui editor(thing)

http://www.heise.de/ix/artikel/2005/07/124/

http://thing.sourceforge.net/screenshot.png

BTW:

I have now working gcc4.3.2.old gcc output asm source in old style that no amiga assembler can read.

new gcc use motorola syntax that amiblitz can read and convert.so its too possible to use C++ C code and add the assembler file to amiblitz

15.10.2008, 09:49 bernd_ ist offline   Profil von bernd_ Füge bernd_ deiner Freunde-Liste hinzu Email an bernd_ senden
Der_Wanderer
Foren Gott




Dabei seit: März 2006
Herkunft: Karlsruhe, Baden-Württemberg
Beiträge: 3564
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Der_Wanderer suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

@Bernd
Welcome!

If you read the initial post carefully, you will notice that I have planned a GUI Editor.

Thanks for the hint with XUL, this is very interessting and quite close to NTUI.
Actually, when I posted the XML code above, I got it as a GUI in the Webbrowser!!! I had to change the < to their HTML definitions, to avoid interpretation.

What I could do is to use the same attribute names like XUL uses, so you could watch NTUI Guis in a webbrowser that supports XUL (like googe chrome).

But there are a few differences and I dont want to support the full XUL, and I will have some special things that XUL doesnt support. So it wont be 1:1 XUL.

However, the concept of XUL is nearly identical to NTUI, and I can get some ideas from the XUL Tutorial.

Thanks for this hint.


I want to implement NTUI in Amiblitz, without any 68K dependencies. I still have to hope that we can compile for other targets one day. The sourcecode of NTUI is c-style, so it could be crosscompiled to C easily, if necessary. That would probably happen if NTUI becomes interesting for people outside the Amiblitz community.
NTUI is implemented to fullyfill Library constraints, so no problem to do a ntui.library.

... but now I got the idea how to solve the identifier problem. Instead of allowing 4 Byte string, I will use the CR32 hashcode (MD5 would be better, but too long and too expensive to calculate). Now, if you want to reference a tuiObject, just use a string as identifier, e.g. "the_button_that_opens_the_ASL_requester" (of course, this is far to long, but possible!)


__________________
Check out http://www.hd-rec.de !

Dieser Beitrag wurde von Der_Wanderer am 15.10.2008, 11:36 Uhr editiert.

15.10.2008, 11:00 Der_Wanderer ist offline   Profil von Der_Wanderer Füge Der_Wanderer deiner Freunde-Liste hinzu Email an Der_Wanderer senden Homepage von Der_Wanderer
Der_Wanderer
Foren Gott




Dabei seit: März 2006
Herkunft: Karlsruhe, Baden-Württemberg
Beiträge: 3564
  Antwort mit Zitat Beitrag editieren/löschen Nach weiteren Beiträgen von Der_Wanderer suchen Diesen Beitrag einem Moderator melden        IP Adresse Zum Anfang der Seite springen

Lesson #2: Setup an NTUI Environment
-----------------------------------------------------

Let's have a closer look at the tuiEngine object.
The first thing we need is always the tuiEngine, this is the main anker we always need to refer to.
Think of it like a base-pointer of a library. This object contains all the information about pens, fonts, message port, look and feel.

The tuiEngine needs to be created once before we start any activities regarding NTUI, and should be the last thing we free before our application ends. If creating fails, there is nothing better we can do than exiting our program, best if we do this using an error message.

code:

XINCLUDE "ntui.include.bb2"

;/* create a new tuiEngine */
*tuiEngine.tuiEngine = ntui_CreateEngine{"Demo"}
If *tuiEngine=!_NULL Then error {"Unable to initialize NTUI Environment!"} : End ; Ooops!
.
.
.
... here is our main loop ...
.
.
.
;/* free the tui engine */
ntui_FreeEngine{*tuiEngine}

;/* that's it, we are done! */
End


Note: !_NULL is a macro from the "useful.include" and equals to 0.
Note: error{} is a function from the "error.include" - you can do whatever you like here.
Note: Creating a new ntui environment only requires a name of the program. This is used to check eventually already running instances and creating a suitable message/AREXX port.

Now we can start creating other objects. Let's create a simple window:

code:

#WINID_DEMO  = 1
#NOTIFY_TEST = 1

;/* create the demo window */
If ntui_BeginWindow{*tuiEngine,"Demo Window",#WINID_DEMO}
    ntui_BeginHGroup{}
      ntui_Label  {"Push Button",#TUIF_RIGHT}
      ntui_Button {"Click Me!",#NOTIFY_TEST,"This is the online help!"}
    ntui_EndGroup{}
  ntui_EndWindow{}
End If


Note: HGroup, Label and Button are sub-objects of the tuiWindow (we will examine them later).
Note: Objects that contain other objects typically start with "ntui_Begin..." and close with "ntui_End...". This holds especially for Windows, Groups, Pages, Menus and Docks (we will examine them later).
Note: We needed 2 extra numeric constants:

#WINID_DEMO is a number that can freely be choosen. It will be used to identify the type window later. It can be any 32-bit number. It is recommended to create your set of window types using the naming scheme #WINID_... = . But things like @"TEST" are ok too (just not typo-proof).
The other constant is #NOTIFY_TEST, this is the value we would get in the main message loop if the button was pressed. Again, you can choose any, but positive value starting from 1, e.g. @"CLIC", but it is recommended to use the #NOTIFY_... scheme (typo-proof). The reason why it is restricted to positive numbers is, that there are some internal notification values that have negative values (like #NOTIFY_CLOSE). A value of 0 (=#NOTIFY_NOTHING) represents no notification at all.

What is #TUIF_RIGHT? you might ask. This is a pre-definded constant from NTUI. It is one of the Tui Flags, they all start with #TUIF_... The flags control the general behaviour or apearance of tuiObjects.

Here is a list of flags, that are allowed to be set or cleared by the user:
code:

;/* TUI Object Flags */
#TUIF_HIDDEN     ; object exists, but is hidden
#TUIF_ENABLED    ; complement of TUIF_DISABLED
#TUIF_DISABLED   ; object is in disabled state
#TUIF_TOP        ; vertical alignment
#TUIF_MIDDLE      
#TUIF_BOTTOM      
#TUIF_LEFT       ; horizontal alignment
#TUIF_CENTER      
#TUIF_RIGHT        
#TUIF_FIXWIDTH   ; fix or sizable
#TUIF_FIXHEIGHT  
#TUIF_FIXSIZE    = TUIF_FIXWIDTH|#TUIF_FIXHEIGHT
#TUIF_SAMEWIDTH  ; force objects to have the same size
#TUIF_SAMEHEIGHT  
#TUIF_SAMESIZE   = #TUIF_SAMEWIDTH|#TUIF_SAMEHEIGHT
#TUIF_IMMIDIATE  ; event on down or up?
#TUIF_SMALL      ; small version
#TUIF_NORMAL     ; normal
#TUIF_FIX        ; fix (font) version
#TUIF_TOGGLE     ; button toggle (default is push)
#TUIF_BOLD       ; bold text
#TUIF_ITALIC     ; italic
#TUIF_UNDERLINED ; underlined
#TUIF_GAPLESS    ; no gaps around the object
#TUIF_BORDER     ; add a border
#TUIF_BIG        ; big version  



Those flags are typically used during creation of an tuiObject.
E.g. if you want a tuiButton to have a bold text, set #TUIF_BOLD. If you want a tuiTextBox to have a fix font, use #TUIF_FIX. If you want a tuiLabel to be aligned to the right side, use #TUIF_RIGHT etc.
Not all objects support all flags, in those cases they do nothing. But mostly it is quite intuitive what they do to the tuiObject.
Execpt #TUIF_ENABLED/DISABLED, the flags are usually not changed during the lifetime of an object, even if you could do so.

Let's get back to our window. We defined the window, but it is not visible yet. But we can already use the window as if it was open.
To open the window on the screen, something is still missing ... the Screen! We must tell the tuiEngine the screen we are working on.
We can use any screen, it is not the business of NTUI where we get it from. To tell the tuiEngine the screen, we have the function
ntui_PopUp. The name of the function is choosen because if we had visible Windows already, they would immidiately pop up.
In order to clean up all dirt we did on a screen, we use the counterpart ntui_Iconify. This would close (note: not free!) all windows, release all pens and close all fonts that we have used. Our application doesn't need to know that. We can still act as if our windows were open.
Once we call ntui_PopUp again, the windows will re-open.

So let's do it:
code:

; /* borrow the WB Screen */
WbToScreen 0 : *scr.Screen = Peek.l(Addr Screen(0))

;/* pop up on the screen */
If ntui_PopUp{*tuiEngine,*scr}=False Then error{"Unable to pop up!"}:End ; what's wrong with the screen!?

; /* now we can actually open the window */
ntui_ShowWindowByID{*tuiEngine,#WINID_DEMO}



The last thing we need is the message loop. Typically, we use the OS function Wait_(sigFlags) to wait for signals from outside. This is the best way to save the CPU cycles for other things going on on your Amiga.
If you don't want to think about which signals you want to wait for, let's wait for any (= $FFFFFFFF or -1).
(If you want to know NTUI's signal, call ntui_GetSigFlag{})

code:

;/* main message loop */
quitme.l = False
While quitme=False
  Wait_ $FFFFFFFF ; wait for any signal
  While ntui_MoreEvents{*tuiEngine} ; check if there are events we are interessted in...
    Select ntui_GetEventNotify{*tuiEngine} ; go for the notification value we got...
      Case #NOTIFY_TEST  : ; now we could do something that makes sense...
      Case #NOTIFY_CLOSE : quitme=True
    End Select
  Wend
Wend



Note: There is one pre-defined value #NOTIFY_CLOSE. We receive this value if the user hits the close-gadget of the window. Of course, you could use the same notify value for a button called "Quit" or "Exit", that is supposed to do the same thing.

Let's put the pieces together to a running sourcecode:

code:

XINCLUDE "ntui.include.bb2"

#WINID_DEMO  = 1 ; define a window type
#NOTIFY_TEST = 1 ; define an own notification value

;/* create a new ntui engine */
*tuiEngine.tuiEngine = ntui_CreateEngine{"Demo"}
If *tuiEngine=!_NULL Then error {"Unable to initialized Engine!"} : End ; Ooops!

; /* borrow the WB Screen */
WbToScreen 0 : *scr.Screen = Peek.l(Addr Screen(0))

;/* pop up on the screen */
If ntui_PopUp{*tuiEngine,*scr}=False Then error{"Unable to pop up!"}:End ; what's wrong with the screen!?

;/* create the demo window */
If ntui_BeginWindow{*tuiEngine,"Demo Window",#WINID_DEMO}
    ntui_BeginHGroup{}
      ntui_Label  {"Push Button",#TUIF_RIGHT}
      ntui_Button {"Click Me!",#NOTIFY_TEST,"This is the online help!"}
    ntui_EndGroup{}
  ntui_EndWindow{}
End If

; /* now we can actually open the window */
ntui_ShowWindowByID{*tuiEngine,#WINID_DEMO}

;/* main message loop */
quitme.l = False
While quitme=False
  Wait_ $FFFFFFFF ; wait for any signal
  While ntui_MoreEvents{*tuiEngine} ; check if there are events we are interessted in...
    Select ntui_GetEventNotify{*tuiEngine} ; go for the notification value we got...
      Case #NOTIFY_TEST  : ; now we could do something that makes sense...
      Case #NOTIFY_CLOSE : quitme=True
    End Select
  Wend
Wend

;/* free the tui engine (and close all windows) */
ntui_FreeEngine{*tuiEngine}

;/* that's it, we are done! */
End


Note: ntui_BeginWindow{*tuiEngine,"Demo Window",#WINID_DEMO} would fail, if a window of the type #WINID_DEMO was already open. This is not a bug, this is a feature. The function would then bring the already-open window to front, instead of letting you open another one. This is pretty handy for windows you need one instance of, e.g. a preferences window, about box etc.
If you need more windows of the same type, you must specify a userID. Again, if the userID is also the same, the already-open window will pop in front, but if the userID is different, a new window will be opened. As a userID, you can use an internal index or basepointer to the object the window referres to. That way, you can quickly deside to which object an event belongs to. The userId would be the next, optional parameter of ntui_BeginWindow.


__________________
Check out http://www.hd-rec.de !

Dieser Beitrag wurde von Der_Wanderer am 25.11.2008, 16:12 Uhr editiert.

25.11.2008, 15:36 Der_Wanderer ist offline   Profil von Der_Wanderer Füge Der_Wanderer deiner Freunde-Liste hinzu Email an Der_Wanderer senden Homepage von Der_Wanderer
  « Vorheriges Thema | Nächstes Thema »
Neues Thema erstellen Antwort erstellen
Gehe zu: