amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > OOP-GUI Systeme und Content-Clipping [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 3 4 [ - Beitrag schreiben - ]

09.07.2011, 15:01 Uhr

AGSzabo
Posts: 1663
Nutzer
Hallo,

ich möchte evtl eine 'virtual' Klasse schreiben, die den IFrames in HTML entspricht, also geclippte boxen in geclippten boxen und so weiter. Als konzept habe ich mir überlegt, dass jedes objekt im objektebaum einen parent-zeiger hat und wenn sich ein objekt zeichnet, sucht es nach oben das kleinste cliprect. Das kann natürlich das guisystem selbst übernehmen, so dass sich nicht jede klasse eigens darum kümmern muss. aber evtl ist es ein overhead wenn bei jedem zeichnen der ganze höhere baum durchsucht wird? hat jemand eine bessere idee?

Andreas
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 13:13 Uhr

Holger
Posts: 8093
Nutzer
Ich weiß ja nicht, wie Du das bisher gemacht hast, aber normalerweise werden GUI-Systeme doch immer so implementiert, dass der Zeichenvorgang bei der Wurzel beginnt und den Baum abwandert, d.h. die Parents rufen die Zeichenmethode ihrer Kinder selbst auf und haben somit die Möglichkeit, ein weiteres Clipping zu dem Grafikcontext, den sie ihrerseits von ihrem Parent übergeben bekommen haben, hinzuzufügen (und nach Beendigung wieder zu entfernen).
Genau so wird es doch auch mit dem Koordinatensystem gemacht, das immer relativ zum direkten Parent verwendet wird. Bzw. mit jeder anderen visuellen Eigenschaft (Font, Vorder- und Hintergrundfarbe).

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 13:47 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

Richtig, es wandert auch bei mir von oben (vom fenster aus) den baum ab, wenn _alles_ gezeichnet wird.

Das Problem besteht darin, wenn ich nur ein einzelnes gadget refreshen will, das in einem von oben geclippten bereicht sich befindet, dann weis dieses gadget erstmal nichts vom clip, müste also evtl nach oben aufsteigend durchfragen ob jemand einen clip hat.
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 16:08 Uhr

thomas
Posts: 7680
Nutzer
@AGSzabo:

Bei ReAction ist das so gelöst, dass man statt der normalen Refresh-Funktion eine spezielle Funktion der Gruppenklasse aufruft, der man das Object, das man refreshen möchte und das Gruppenobjekt übergibt und das Gruppenobjekt entscheidet dann anhand der Sichtbarkeit des zu refreshenden Objekts, ob es dessen Zeichen-Methode aufruft oder nicht. Es bleibt also beim Refresh "von oben".

Wenn sich der Programmierer nicht daran hält, dann gibt es Grafikmüll, weil das Objekt sich dann zeichnet, obwohl es eigentlich nicht oder nur teilweise sichtbar wäre.

Siehe Autodocs über virtual.gadget/RefreshVirtualGadget oder page.gadget/RefreshPageGadget.


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 17:24 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Bei NTUI ist das so gelöst, dass man (der Nutzer der API) grundsätzlich nur "von oben", also dem Root (normalerweise ein Fenster) zeichnen kann.

Allerdings kann man jedem Refresh eine Clip-Region mitgeben, die Objekte "nach unten" hin auch weiter verengen können.

Objekte testen dann erstmal, ob sie überhaupt drin liegen, wenn nicht, springt es sofort wieder zurück.
Der Overhead, "von oben" zu beginnen, ist zu vernachlässigen, im Vergleich zu dem Zeichnen des eigentlichen Objekts. (Tiefe des Baums ist ja nur O(log n), n = Anzahl der GUI Elemente.

Will ich also ein einzelnes Objekt refreshen (dafür gibts natürlich ein Convenient-Stubb), dann nimmt sie den Root und setzt die ClipRegion auf die Boundaries des zu refreshenden Objekts, und führt dann ein ganz normales, globales Refresh durch.

Vorteil: Es gibt nur eine einzige Funktion zum Zeichen, egal welches Objekt, egal ob beim initialen Zeichen oder partiellen Refresh (Simple Refresh Windows), bei Data/Status-Updates von Objekten etc.

Ein weiterer Vorteil ist, dass man nicht sofort neu zeichnen muss, sondern kann die betroffenen Objekte erstmal als "damaged" markieren, und zeichnet erst neu, wenn der User der GUI Engine wieder den Focus gibt. Vorteil: Setze ich 1000x den Wert eines Objekts neu, wird es trotzdem nur 1x gezeichnet => keine lästigen Refresh Orgien z.b. beim Befüllen eines Lisviews oder beim Solid-Resizing.

Die eigentliche Zeichenfunktion eines bestimmten Objekts darf man nicht von aussen aufrufen, sondern muss immer durch diesen Mechanismus hindurch.
(bei NTUI ruft der API User eigenlich nie die Zeichenfunktionen auf, da NTUI das alles bereits regelt, es sei den er möchte in einen eigenen RastPort zeichnen, z.b. für einen GUI Builder oder Skin Vorschau).


P.S: Mit "virtual" hat das nichts zu tun. So ein ScrollView ist ein ganz normales Widget wie alle anderen auch.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ Dieser Beitrag wurde von Der_Wanderer am 11.07.2011 um 17:59 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 17:28 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Sowas hier meinst du vermutlich:

Bild: http://www.hd-rec.de/pics/ntui_status25.png

Das ist übrigends eines der mächtigsten Widgets überhaupt. Ich habe es "ScrollView" genannt. z.b. brauchst du für Listviews, Textboxen, ChatLogs, Bilder, Fließtext etc. alles gar keine eigenen Scroller implementieren, du packst sie einfach in einen ScrollView und lässt sie so groß werden wie sie sein wollen.
Der ScrollView erledigt das scrollen für dich.

Hint: Das erste Element unterhalb eines Windows kann auch ein (borderless,auto-scroller) ScrollView sein, in dem sich der Rest des Fensters befindet. Somit fängt das Fenster automatisch zu scrollen an, wenn es nicht auf den Bildschirm passen sollte, z.b. wenn jemand auf 320x256 springen würde. Sehr elegant, so ein ScrollView.


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 11.07.2011 um 18:02 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 18:28 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

Bei mir heisst das einfach nur view, weil das element mit den scrollern dazu diese view benutz. es sind zwei getrennte klassen, von denen die eine die andere benutzt. die scroller selbts sind auch extra klassen, die vom "scrollview" benutzt werden.

Ich habe nicht ganz verstanden, bei dir können views in views sein usw? Es wird immer der ganze baum abgewandert beim zeichnen?

Wenn ein objekt nur einen teil von sich neu zeichen möchte, zb nur den rahmen eines buttons im geklickten also inversen zustand? was macht ntui dann? Button hier ist nur ein beispiel, es könnten ja komplexere objekte sein, bei denen es sich evtl rentiert nicht alles neu zu zeichnen.

--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux


[ Dieser Beitrag wurde von AGSzabo am 11.07.2011 um 18:36 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 18:35 Uhr

Holger
Posts: 8093
Nutzer
Bei Java/Swing ist es so, dass wenn eine einzelne Komponente direkt gezeichnet werden soll, was i.A. nur beim Ziehen mit der Maus oder ähnlichem angewendet wird, diese Komponente nach oben wandert und überprüft, ob eine andere Komponente sie überlappt. Der Zeichenvorgang startet dann bei der ersten nicht überlappten Komponente, sinnigerweise natürlich auch mit gesetztem Clipping auf dem Graphics Kontext.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 18:43 Uhr

Holger
Posts: 8093
Nutzer
Zitat:
Original von AGSzabo:
Wenn ein objekt nur einen teil von sich neu zeichen möchte, zb nur den rahmen eines buttons im geklickten also inversen zustand?

Selbst bei so primitiven Gadgets wie bei Gadtools ändert sich beim Anklicken standardmäßig die Hintergrundfarbe und erzwingt somit ein komplettes Neuzeichnen der Buttons.

Ansonsten kann man natürlich durch die Wahl der Clipping-Bereiche auch nur Teile eines Gadgets aktualisieren.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 18:46 Uhr

AGSzabo
Posts: 1663
Nutzer
Wie 'geht' eigentlich das klippen im system? Ich meine immer, dass es zu lange dauern würde, alle koordinatenm auch von schrägen linien oder kreisen auf die maße der clips zu beschneiden. gibt es eine andere methode?

Ich mache ja double-buffering und jede zeichenvorgänge, die nicht in der standard DRAW methode einer klasse erledigt werden, sondern zB in der methode die auf einen click reagiert, jede solche müssen in BeginRefresh() und EndRefresh gekapselt werden (nicht zu verwechseln mit solchen systemfuntkionen). BeginRefresh() schaltet den rastport um und endrefresh kopiert den block des gadgets ins fenster. system sind heute aber so schnell, man könnte immer das ganze fenster kopieren ...

... nun, da ich diese kapselung habe, könnte ich evtl das einschaltet der clips in BeginRefresh() packen ...

--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ Dieser Beitrag wurde von AGSzabo am 11.07.2011 um 18:52 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 19:06 Uhr

Holger
Posts: 8093
Nutzer
Zitat:
Original von AGSzabo:
Wie 'geht' eigentlich das klippen im system? Ich meine immer, dass es zu lange dauern würde, alle koordinatenm auch von schrägen linien oder kreisen auf die maße der clips zu beschneiden. gibt es eine andere methode?

Es gibt natürlich immer verschiedene Methoden.
Im AmigaOS (Classic) basiert alles auf Rechtecken. Um eine Linie, ob schräg oder nicht, auf ein Rechteck zu beschneiden, muss man nicht viel tun. Und im Falle eines ClipRects, das genau ein Gadget von vielen umfasst, wird ja eh alles noch viel einfacher, weil die meisten Objekte komplett außerhalb des Bereichs, einige komplett innerhalb und (fast) gar keine teilweise innerhalb des Bereichs liegen.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 21:27 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Zitat:
Original von AGSzabo:
@Der_Wanderer:

Bei mir heisst das einfach nur view, weil das element mit den scrollern dazu diese view benutz. es sind zwei getrennte klassen, von denen die eine die andere benutzt. die scroller selbts sind auch extra klassen, die vom "scrollview" benutzt werden.

Bei mir ist es so, dass der ScrollView eine Content-Area hat und, falls nötig, Scroller initialisiert und diese zeichnet als Sub-Objekte. Er hat also 3 Subobjekte, und zwar den Inhalt (was auch immer das ist) und zwei Scroller. Die Scroller sind immer da, nur "Gone", falls man sie nicht benötigt, d.h. der Inhalt kleiner oder gleich dem ScrollView (minus Border, falls vorhanden) ist.

Zitat:
Ich habe nicht ganz verstanden, bei dir können views in views sein usw? Es wird immer der ganze baum abgewandert beim zeichnen?
Die können beliebig geschachtelt sein, ja. So wie TabViews etc.
Alles kann man beliebig verschachteln, weil ja alles rekursiv aufgebaut ist. Wenn eine Verschaltelung funktioniert, dann automatisch auch N Verschachtelungen.

Zitat:
Wenn ein objekt nur einen teil von sich neu zeichen möchte, zb nur den rahmen eines buttons im geklickten also inversen zustand?
Ja, bei einigen Widgets ergibt sich daraus tatsächlich etwas Kopfzerbrechen.
Aber bei den allermeisten Widget ist das so, dass sie sich Brute Force neu zeichnen. Zu optimieren ist das hier zu viel Geraffel was nichts bringt. Bedenke, dass bei NTUI z.b. auch Skins unterstützt werden, bei denen das komplette Hintergrundbild eines Buttons ausgetauscht wird, da kann man also sowieso nicht anders als alles neu zeichnen.
Man muss nur aufpassen, dass man das neu Zeichnen nicht sieht. Bei Skins geht das nur durch Double-Buffering, korrekter gesagt "Offscreen Bitmaps", bei den prozeduralen Looks habe ich das so geschickt gemacht, dass kein Pixel mehrmals bemalt wird, und somit flackert auch nichts.

Zitat:
was macht ntui dann? Button hier ist nur ein beispiel, es könnten ja komplexere Objekte sein, bei denen es sich evtl rentiert nicht alles neu zu zeichnen.
Ja, z.b. ein TabView, das beliebig komplexen Inhalt haben kann.
Wenn das den Focus verliert ändert sich nur der Rahmen.
In diesem Fall überlädt der TabView die Funktionen in denen nur der Rahmen sich ändert (z.b. "OnFocus"), und zeichnet nur den Rahmen neu.
Die Eltern-Implementation der Funktionen ist normalerweise ein simples Redraw, was ja immer funktioniert, nur manchmal etwas unoptimiert ist.

Aber wie Michael Jackson schon sagte:

"The First and Second Rules of Program Optimisation:
1. Don’t do it.
2. (For experts only!): Don’t do it yet."

Die meisten Bugs und Programmier-Sünden werden im Namen der Optimierung begangen.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 11.07.2011 um 21:43 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 21:41 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

Man könnte einfach auch in den userevent methoden die clips einbauen (systemseitig), dann kann darin ein gadget ein paar linien zeichnen und es wird trotzdem richtig geclippt. Von mir aus auch in SET, dann können attribute gleich richtig refresht werden...

> Die meisten Bugs und Programmier-Sünden werden im Namen der Optimierung begangen.

das ist allerdings wahr. :-)

--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ Dieser Beitrag wurde von AGSzabo am 11.07.2011 um 21:43 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 22:19 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Ich würde möglichst viel dem Widget Code selbst überlassen, denn es weis am besten wie es klippen muss. Ein SetAttr() macht bei mir ein Widget "damaged" (bzw. in NTUI heisst das "dirty"). Erst nachdem der Focus zur Engine zurückkehrt, wird es dann neu gezeichnet. So vermeidet man multiple Refreshs beim setzen vieler Attribute, wie oben schon erwähnt.

Generell kann ich tatäschlich von zu viel Optimierung abraten. Besser man denkt sich gute Datenstrukturen und Algorithmen aus, und implementiert das sauber. Am Ende kann man sich dann anschauen, wenns fertig ist, an welchen Ecken und Enden es zu langsam ist. Nur dann sollte man optimieren, denn optimieren bedeuted immer spezialisieren und dadurch einschränken. Oft liegt das Nadelöhr auch ganz wo anders, als man am Anfang des Projekts vermuten würde.


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 22:21 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

Was ist das mit dem "Focus", was bedeutet "zur engine zurück kehrt"?
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 23:06 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Dein Program "schläft" ja normalerweise in der GUI Engine, in soetwas wie "WaitEvent()". Wenn ein Event kommt, wird der "Focus" an die Applikation übergeben indem diese Funktion zurückkehrt. Dort kann dann die Applikation nach Lust und Laune an den Widgets rumschrauben, diese werden jedoch nicht sofort gezeichnet, sondern nur "dreckig" gemacht.
Die Applikation gibt dann den Focus möglichst schnell wieder zurück, indem es in WaitEvent() wieder zurückkehrt.
Dann werden erstmal alle dreckigen Widgets neu gezeichnet, und dann wieder nach Events gelauscht.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

11.07.2011, 23:23 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

Hmmm, bei mir ist die waitschleife im application objekt, wenn ein envent kommt, sendet es mit Broadcast() eine message den ganzen baum runter (das ist ein DoMethod() auf jedes objekt, der hirarchie nach). die widgets haben dann hooks in denen die funktionen der applikation ausgeführt werden. diese funktionen können mit SetAttr() an den gadgets rumschrauben. wenn dann das broadcast() zur applikation klasse zurück kommt, könnte es statt DRAW ein REFRESH runter senden, da würde dann geschaut werden welche objekte verändert wurden ... auf diese und ihre childs würde dann DRAW gebroadcastet, wobei dann das refresh ab einem veränderten objekt nimmer weiter ab steigen würde, denn das draw hat dann selbst schon alle unterobjekte erreicht. ... so etwa?

problem: ein hook, der zum beispiel einen virusscan-task startet, der task soll den progressbar auffrischen. da brauchts dann doch ein direktes refresh ... wie könnte das gehen? dem setattr vom scantask aus ein refresh hinterhersenden?
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 09:29 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Achso, du willst das Callback basierend machen. Habe ich mir auch überlegt.

Man kann ja zwei Ansätze verfolgen.

1. Man macht einen Message Loop, d.h. es gibt eine Funktion wie "WaitEvent()", die die Applikation aufruft und darin schläft. Die Funktion gibt dann Events zurück, die der Applikationsprogrammierer vorher gesetzt hat, und kann dann darauf reagieren.
Nicht zu verwechseln mit IDCMP Events, die sollte der App Programmierer niemals zu Gesicht bekommen, schon aus Portabilitätsgründen nicht.
Die App bekommt nur "logische" Events, die eine bestimmte Aktion representieren, nicht ein bestimmtes IDCMP Event eines Eingabegerätes.

Die ID so eines logischen Events ist in NTUI ein String, den ich Notify nenne. Es ist deshalb ein String, weil ich die GUI komplett in XML definierbar machen möchte.

code:
<Button id="MyButton" onClick="button_wurde_geklickt">

...
while (!quit) {
  event = WaitEvent();

  switch(event.notify) {
    case "button_wurde_geklickt":
      <etwas tun wenn der Button gedrückt wurde>
  }
}

return; // end of program


2. Der Message Loop wird versteckt. Die App besteht eigentlich nur aus der Definiton von Callback Funktionen, die auf bestimmte logische Events gesetzt werden. Das ist eigentlich der modernere Approach, aber setzt mehr Erfahrung vom Programmierer vorraus, vor allem wenn es dann Mutltithreaded wird, da eine Callback ja nicht wirklich lange brauchen sollte. Für einen Virenscanner z.b. bräuchte man dann auf jedenfall 2 Threads. D.h. der Programmierer muss das konzept von Threads und vor allem Threadsafe verstanden haben. Je nach Programmiersprache wird das auch schwer zu verwenden, z.b. Basic.

code:
<Button id="MyButton">
...

SetAttr("MyButton",ATTR_ONCLICK,?button_wurde_geklickt);

void button_wurde_geklickt(object *eventobject) {
  <etwas tun wenn der Button gedrückt wurde>
}

EnterEventLoop();

return; // end of program


Ich denke mal, dass NTUI beides unterstützen wird. Momentan wird aber nur Event Loop unterstützt.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 12.07.2011 um 09:36 Uhr geändert. ]

[ Dieser Beitrag wurde von Der_Wanderer am 12.07.2011 um 09:38 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 09:39 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

> Die ID so eines logischen Events ist in NTUI ein String, den ich Notify nenne. Es ist deshalb ein String, weil ich die GUI komplett in XML definierbar machen möchte.

id="1" geht doch auch?

Mein schönes clipping funktioniert leider nicht mehr, sobald zwei oder mehr clips verschachtelt sind ... hurz ...
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 09:39 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 10:36 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Nunja, wenn es ein String ist, dann geht wohl auch "1" ;-)

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 12:07 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

Nee, ich meine die "1" wird vom compiler in eine wertvariable umgewandelt und die wird einem attribut zugewiesen.

Mein Clipping funktioniert nicht. Könntest du bitte mal schauen ob du mir das noch besser erklären kannst, wie es zB geht? Wenn ich von oben anfange, dann nutzt es mir nix den bereich nur zu verengen, denn wenn dann ein benachbartes view gezeichnet werden soll und der clip schon verengt ist, fällt das benachbarte gadget raus.

Und wie macht man es, wenn man zusätzlich zu den system clips temporär einen kleinen userclip installieren will, der zb in einer liste den titel abschneidet, wenn er nicht in die spalte passt? Müsste man da nicht hinterher wieder oben anfangen mit dem verengen der clips?

--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 12:08 Uhr geändert. ]

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 12:25 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 17:27 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Zitat:
Original von AGSzabo:
@Der_Wanderer:

Nee, ich meine die "1" wird vom compiler in eine wertvariable umgewandelt und die wird einem attribut zugewiesen.

Nein. Die GUI wird ja bei mir nicht (notwendigerweise) fest reinkompiliert. Sonst müsste z.B. der GUI Builder die Zielprogrammiersprache kennen.

Alle IDs und Notifys sind bei mir Strings. Da habe ich lange drüber nachgedacht, bin aber auf keine bessere Lösung gekommen. Zumindest nicht, wenn man eine Amiga Shared Library draus machen will die von allen erdenklichen Programmiersprachen genutzt werden kann.

Zitat:
Mein Clipping funktioniert nicht. Könntest du bitte mal schauen ob du mir das noch besser erklären kannst, wie es zB geht?
Ich versuche das mal zu veranschaulichen, später.

Zitat:
Wenn ich von oben anfange, dann nutzt es mir nix den bereich nur zu verengen, denn wenn dann ein benachbartes view gezeichnet werden soll und der clip schon verengt ist, fällt das benachbarte gadget raus.
Das benachbarte Widget ist aber in der Hirarchie nicht drunter, sondern nebendran.

Zitat:
Und wie macht man es, wenn man zusätzlich zu den system clips temporär einen kleinen userclip installieren will, der zb in einer liste den titel abschneidet, wenn er nicht in die spalte passt? Müsste man da nicht hinterher wieder oben anfangen mit dem verengen der clips?
Bei "InstallClipRegion()" bekommst du ja die alte Clipregion als Rückgabe Wert. Bevor eine Funktion zurückkehrt, sollte sie natürlich die alte wieder herstellen. Durch die Rekursion ist so sichergestellt, dass es immer genau stimmt.
Evtl. liegt dein Problem in dem Verständnis der Rekursion?



--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 17:37 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

> Bei "InstallClipRegion()" bekommst du ja die alte Clipregion als Rückgabe Wert. Bevor eine Funktion zurückkehrt, sollte sie natürlich die alte wieder herstellen.

Der clip des tabellentitels muß aber die anderen clips zb von views mit berücksichtigen!


> Evtl. liegt dein Problem in dem Verständnis der Rekursion?

Ich weis nicht ... müsste man das rectangle auf jeder ebene merken, um nebenan trotzdem zeichnen zu können?


> Ich versuche das mal zu veranschaulichen, später.

Danke, das wäre großartig.
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 18:07 Uhr

Der_Wanderer
Posts: 1229
Nutzer
> Der clip des tabellentitels muß aber die anderen clips zb von views mit berücksichtigen!
Ja sicher, deshalb wird er ja auch draufge-OR-ed (benutze OrRectRegion() allerdings entspricht das meinem Verständnis von AND, aber egal), also verengt.
Wenn die Rekursion eine Stufe nach oben zurückkehrt, ist ja aber die alte Region wieder hergestellt. Dann geht man "nebendran", oder wieder eins höher, so löst sich die Verengung wieder auf bis man wieder beim Root angekommen ist.

Falls du vorhast, transparente Widgets zu haben (z.b. Buttons mit runden Ecken), dann musst du sowieso beim Root anfangen zu zeichnen, da ja der Hintergrund auch neu gezeichnet werden muss, den dein runder Button aber an den Ecken gar nicht kennt.


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 18:42 Uhr

Thore
Posts: 2266
Nutzer
> draufge-OR-ed (benutze OrRectRegion() allerdings entspricht das meinem Verständnis von AND, aber egal)

OR ist schon richtig, ist kein AND, beim AND wäre es sowas wie die Schnittmenge, bei OR die Gesamtmenge (Vereinigung)

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 20:01 Uhr

AGSzabo
Posts: 1663
Nutzer
Das ist mein erster implementationsversuch des "SuperRefresh" von oben. Leider werden jetzt auch alle nachfolgenden benachbarten gadgets neu gezeichnet. Ich weis auch warum, sehe aber noch nicht die Lösung. Ich habe ein problem mit der rekursion. Kann jemand helfen?

Die Routine soll das geänderte Objekt und nach ihm automatisch alle darunter liegenden objekte neu zeichnen.
asm code:
_oxSuperRefresh	; walk down the full tree and draw everything that was changed anew,
		; while doing this, do a graphical clipping as the classes prefer

		; a0 pointer to calling object, or windowobject

 STRUCTURE sr,0
	UWORD	sr_left
	UWORD	sr_top
	UWORD	sr_right
	UWORD	sr_bottom
	UBYTE	sr_flags
	UBYTE	sr_
	LABEL	sr_SIZEOF

	BITDEF	sr,DRAWING,0

		pushm	d7/a4/a5

		move.l	oxO_drawinfo(a0),a0
		btst	#oxDIB_WINDOWOPEN,oxDI_flags(a0)
		beq	.pop

		move.l	oxDI_window(a0),a1
		move.l	oxDI_windowobject(a0),a0

		; store window object pointer
		move.l	a0,a4

		; init and clear inital drawing and clipping info structure
		lea	-sr_SIZEOF(a7),a7
		move.l	a7,a5
		clr.l	sr_left(a5)
		move.l	wd_GZZWidth(a1),sr_right(a5)
		clr.b	sr_flags(a5)

		bsr	.first_member

		lea	sr_SIZEOF(a7),a7

.pop		popm	d7/a4/a5
		rts

.first_member	pushm	a0/a5
		lea	-sr_SIZEOF(a7),a7

		move.b	sr_flags(a5),sr_flags(a7)
		move.l	sr_left(a5),sr_left(a7)
		move.l	sr_right(a5),sr_right(a7)
		move.l	a7,a5

		lea	oxO_list(a0),a0
.next_member	move.l	(a0),a0
		tst.l	(a0)
		beq.b	.return

		btst	#srB_DRAWING,sr_flags(a5)
		bne	.draw

		btst	#oxOB_REFRESH,oxO_flags(a0)
		beq	.members

		bset	#srB_DRAWING,sr_flags(a5)

.draw		bclr	#oxOB_REFRESH,oxO_flags(a0)
		moveq	#OXM_DRAW,d1
		moveq	#0,d2
		bsr	_oxDoMethod
		tst.l	d0
		bne	.next_member

		; apply clip for childs here ?


.members	bsr	.first_member

		moveq	#OXM_GETCONTINUE,d1
		bsr	_oxDoMethod

		tst.l	d0
		beq	.next_member

		push	a0
		move.l	d0,a0
		bsr	.first_member
		pop	a0

		bra	.next_member

.return		lea	sr_SIZEOF(a7),a7
		popm	a0/a5
		rts

--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 20:09 Uhr geändert. ]

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 20:11 Uhr geändert. ]

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 20:39 Uhr geändert. ]

[ Dieser Beitrag wurde von AGSzabo am 12.07.2011 um 20:41 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 20:48 Uhr

Holger
Posts: 8093
Nutzer
Zitat:
Original von AGSzabo:
Man könnte einfach auch in den userevent methoden die clips einbauen (systemseitig), ...

Events und Clipping haben nichts miteinander zu tun.
Zitat:
problem: ein hook, der zum beispiel einen virusscan-task startet, der task soll den progressbar auffrischen. da brauchts dann doch ein direktes refresh ... wie könnte das gehen? dem setattr vom scantask aus ein refresh hinterhersenden?
Ja, so macht es Intuition. Ruft man SetAttrs[A] oder SetGadgetAttrs[A] auf, teilt der Rückgabewert mit, ob die Änderung ein visuelles Update erforderlich macht oder nicht. Es bleibt trotzdem dem Aufrufer vorbehalten, die Refresh-Funktion aufzurufen, d.h. er kann auch erst einmal ein Dutzend Änderungen durchführen, bevor er einen visuellen Refresh durchführt.

Sagte ich nicht schon einmal, dass es sich lohnt, die existierenden Lösungen zu studieren, bevor man seine eigene zu machen versucht? ;)

Zitat:
Original von Der_Wanderer:
Alle IDs und Notifys sind bei mir Strings. Da habe ich lange drüber nachgedacht, bin aber auf keine bessere Lösung gekommen.

Es gibt ja auch keine bessere.
Wenn es um Effizienz geht, lässt man das Toolkit eine eigene Hashmap aufbauen, die für jeden String einen kanonischen Eintrag besitzt, durch den jeder String bei der Initialisierung eines Clients (oder dem Laden einer XML-Datei) ersetzt wird.
Dann muss man keine String-Vergleiche anstellen, sondern lediglich die Adressen der Strings vergleichen, da dann ja gleiche Strings immer auf dieselbe kanonische Instanz zeigen.
Ist also exakt genauso effizient wie Integer-Werte.
Zitat:
Falls du vorhast, transparente Widgets zu haben (z.b. Buttons mit runden Ecken), dann musst du sowieso beim Root anfangen zu zeichnen, da ja der Hintergrund auch neu gezeichnet werden muss, den dein runder Button aber an den Ecken gar nicht kennt.
Nein, es muss beim ersten nicht-transparenten Parent gestarten werden. Der Root wäre nur der worst-case. Ich hatte ja dazu schon oben etwas geschrieben, wie Swing es macht.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 20:51 Uhr

Der_Wanderer
Posts: 1229
Nutzer
@Thore:

> OR ist schon richtig, ist kein AND, beim AND wäre es sowas wie die
> Schnittmenge, bei OR die Gesamtmenge (Vereinigung)
Wir wollen aber die Schnittmenge, nicht die Vereinigung. Trotzdem heisst der Befehl OrRectRegion.

Wenn Azabo einen Text clippt, damit er nicht aus dem Widget herausgeht, will er die Schnittmenge des bestehenden Clips (der möglicherweise "enger" ist) und dem Text bilden, nicht die Vereinigung, das wäre ja sinnlos.


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 20:55 Uhr

AGSzabo
Posts: 1663
Nutzer
@Holger:

> Dann muss man keine String-Vergleiche anstellen, sondern lediglich die Adressen der Strings vergleichen, da dann ja gleiche Strings immer auf dieselbe kanonische Instanz zeigen.

Mein OXML compiler macht das so ... erzeugt aber eben hardcode. :)
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]

12.07.2011, 20:56 Uhr

AGSzabo
Posts: 1663
Nutzer
@Der_Wanderer:

> die Schnittmenge

das geht mit AND
--
Sam mini os4.1 upd. 2 / e-uae 39bb2 / A4000D 3.0 & 3.9 2mbchip 8mbfast Ariadne_II ide DVD und HD / A500 3.1 (mkick) adide 50mb / Athlon ii X2 Ubuntu Linux

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 3 4 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > OOP-GUI Systeme und Content-Clipping [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2022 by amiga-news.de - alle Rechte vorbehalten.
.