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 - ] |
12.07.2011, 21:00 Uhr Thore Posts: 2266 Nutzer |
> 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. Ah okay, ja dann ists AND. Dachte er will die Clips vergrößern. Jetzt machts auch wieder Sinn [ - Antworten - Zitieren - Direktlink - ] |
12.07.2011, 21:03 Uhr Der_Wanderer Posts: 1229 Nutzer |
Zitat:Ja sollte man. Und z.b. ist es schlecht, dem App Programmierer den Refresh auszubürden, weil er es in 90% der Fälle zu selten oder zu oft macht. Der GUI Toolkit Programmierer weis am besten, wann ein Refresh zu tun ist. Und man muss auch keine Return Code dafür missbrauchen, sondern kann einfach das Widget in die "Damage" List setzen, falls noch nicht geschehen. Der Return Code ist dafür zu wichtig. Bei Events z.b. wird der Return Code normalerweise dazu benutzt um anzuzeigen, ob das Event konsumiert worden ist oder anderen Widgets zur Verfügung steht. Zitat:Zumindest nicht, wenn man sich nicht auf eine Programmiersprache, für die man z.b. Headerdateien erzeugt, festlegen will.Zitat:Es gibt ja auch keine bessere. Und per Hand wollen wir ja im Jahre 2011 keine GUI mehr machen... Zitat:Ja auch eine gute Idee. Aber wie gesagt, "don't optimize". Die Strings sind wirklich das letzte, was Performance kostet. Da schlagen die Skin Grafiken um mehrere Zehnerpotenzen mehr zu buche. Und wenns doch ein Nadelöhr werden sollte, dann hast du ja gezeigt dass man es so effizient wie Integer machen kann. Zitat:Schon richtig. Aber: "don't optimize yet". Kann man alles später noch tun, wenn es zu langsam sein sollte. Aber mal ehrlich, wieviele Layer hat man denn schon? Normalerweise hat das Fenster einen soliden Hintergrund, alle weiteren Widgets (z.B. Gruppen) sind transparent bis dann irgendwann der Button kommt. Klar kann auch eine farbige Gruppe dazwischen kommen, aber wen interessieren schon zwei RectFill statt einem in so einem schon eher seltenen Fall. Erstmal sollte man sich drauf konzentrieren, dass alles "korrekt" implementiert ist. Sonst verbaut man sich schnell den Weg durch optimieren, z.b. hatte ich am Anfang auch das so gemacht, dass die Hintergrund Farbe ermittelt wird vom Button aus. Als dann aber Skins dazu kamen, hat das nicht mehr geklappt, denn die "Hintergrundfarbe" kann ist dann nicht mehr einfarbig und kann sich wegen Alphatransparenz aus allen Pixel "darunter" zusammensetzen, sodass man gar nicht anders kann als beim Root anzufangen. -- -- 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 21:08 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
12.07.2011, 21:06 Uhr Der_Wanderer Posts: 1229 Nutzer |
@AGSzabo: 1. Ja, aber die Funktion heisst trotzdem OrRectRegion, bildet aber die Schnittmenge. Da hat wohl jemand in der Informatikvorlesung geschlafen, als er die API designed hat. 2. Dein Konzept setzt dann aber vorraus, dass der App Programmierer 68k Assembler verwendet, oder nicht? Was mache ich, wenn ich C++, Amiblitz oder AREXX benutze? -- -- 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 21:06 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
12.07.2011, 21:16 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: Ist für und geht nur mit Assembler. Höchstens C, aber da müsste jemand die header files und so machen. -- 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, 21:37 Uhr Thore Posts: 2266 Nutzer |
> Ja, aber die Funktion heisst trotzdem OrRectRegion, bildet aber die Schnittmenge. Da hat wohl jemand in der Informatikvorlesung geschlafen, als er die API designed hat. Da muss ein Verständnisproblem vorliegen: Hier die Beschreibung: "If any portion of rectangle is not in the region then add that portion to the region." Mach mal ein Demo und zeig daß es falschrum ist Es wär garantiert schon anderen aufgefallen und korrigiert worden. [ - Antworten - Zitieren - Direktlink - ] |
12.07.2011, 22:11 Uhr Der_Wanderer Posts: 1229 Nutzer |
Hoppla, stimmt. Das OrRectRegion mache ich nur, wenn die Region vorher NULL war. Das ist so eine seltsame Ausnahme, weil NULL zwar kein Clipping macht, aber beim OR/AND sich wie "nichts" verhält. -- -- 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, 22:17 Uhr Thore Posts: 2266 Nutzer |
> Das ist so eine seltsame Ausnahme, weil NULL zwar kein Clipping macht, aber beim OR/AND sich wie "nichts" verhält. Für OR richtig. Für AND dürfte das Ergebnis ebenfalls leer sein. Das ist schon korrekt wie die das gemacht haben [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 01:03 Uhr Holger Posts: 8116 Nutzer |
Zitat:Jein. Das Toolkit, bzw. die Komponenten wissen am besten, wann sie einen Refresh nötig haben, aber wann die Anwendung alle Änderungen getätigt hat, die instantan sichtbar werden sollen, weiß nur die Anwendung. Ein Automatismus funktioniert dann am besten, wenn alle Aktionen, die einen Refresh nötig machen würden, in Call-Backs wie Event-Handlern ausgeführt werden. Dann kann das Toolkit nach Beendigung der Call-Back Ausführung entscheiden, ob es einen Refresh durchführt oder nicht. Mit dem klassischen AmigaOS geht das nicht so einfach. Zitat:Das kann man auch über ein Flag im Event machen. Zitat:Vor allem nicht, wenn man sich nicht auf Dauer von einer zentralen Autorität abhängig machen will, die den Range gültiger IDs und deren Bedeutung festlegen soll. Zitat:Zwei Gründe sprechen dafür, es doch zu tun: 1. Man kann es auch für diverse nicht-graphische Operationen verwenden. 2. Einige Programmierer tun sich damit schwer, Strings zu verwenden. Es erhöht somit die Akzeptanz, wenn man auf die Effizienz hinweisen kann, selbst wenn es nur gefühlte Performance ist. Zitat:Darum geht es dabei ja gar nicht. In dem Fall geht es um den Overhead, den kompletten Baum zu traversieren und alle Elemente gegen das ClipRect zu testen. Klar, ist meist nichts gegen einen Blit, aber das hängt von den jeweiligen Fähigkeit zur Grafikbeschleunigung ab. Beim Beispiel von Swing ging es ja noch um etwas anderes. Neben nicht-rechteckigen Formen, gibt es auch sich möglicherweise überlappende Elemente und halbtransparente Overlays. Und es ist mitunter sinnvoller, die Gruppen nicht als transparent anzusehen. Dann muss man nämlich nicht bis zum Root hochgehen, sondern kann u.U. den direkten Parent als Ausgangsbasis einer Zeichenoperation nehmen. Bei Abwandern des kompletten Baums überspringt man dagegen das Füllen mit der Hintergrundfarbe, wenn diese identisch mit der des Parents ist. Zitat:Grundsätzlich schon. Zitat:Das ist ein Zeichen dafür, dass der später angestrebte Anwendungsfall nicht beim ersten Design berücksichtigt wurde. Eine sorgfältige Planung kann auch Performancefragen von vornherein berücksichtigen, andernfalls muss man mitunter hinterher doch alles neu designen. -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 07:32 Uhr AGSzabo Posts: 1663 Nutzer |
Zitat:Was jetzt? IDs von Objekten oder von Attributen und Methoden?Zitat:Vor allem nicht, wenn man sich nicht auf Dauer von einer zentralen Autorität abhängig machen will, die den Range gültiger IDs und deren Bedeutung festlegen soll. Btw, was ist denn Notify oder bessergefragt, wie funktiniert das? Ich habe eine simple "connect" klasse gemacht, die an die broadcastliste eines ojbekts angehängt wird. Und wenn sie ein SetAttr() vom Objekt empfängt kann sie die AttributID in eine andere wandeln und den Attributwert damit an ein Targetobjekt weitersenden. Ich weiss nicht ob das schon Notifiy ist, ich glaube nicht... -- 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 13.07.2011 um 07:37 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 08:03 Uhr AGSzabo Posts: 1663 Nutzer |
@Holger: > Darum geht es dabei ja gar nicht. In dem Fall geht es um den Overhead, den kompletten Baum zu traversieren und alle Elemente gegen das ClipRect zu testen. Das tuts garnicht, es werden nur diejenigen elemente nach einem cliprect gefragt, die in der Klasse das CLIPPING-bit gesetzt haben. -- 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 - ] |
13.07.2011, 09:53 Uhr Der_Wanderer Posts: 1229 Nutzer |
@Holger Warum würde ein Programmierer einen Refresh erzwingen wollen, wenn das GUI Toolkit das für ihn tut? Bei modernen Toolkits wie Android gibt es eine solche Möglichkeit meines Wissens nach nicht, aber es fehlt auch nichts. Wenn z.b. ein einem zweiten Thread gezeichnet wird, dann möchte man sicher nicht dazwischenfunken durch einen direkten Draw Aufruf. Die "Anzeige" ist für die App eine Black Box. Man beschäftigt sich nur mit den Widget Paramtern/Daten. Wie und wann und wo sie gezeichnet werden, ist Aufgabe des Toolkits. Bei NTUI wird nie sofort gezeichnet, sondern erstmal das Dirty Flag gesetzt. Möglicherweise nehme ich ja viele Änderungen vor, die jedesmal ein Neuzeichnen erfordern würden. In der Regel gehen die Änderungen furchtbar schnell (z.b. eine Farbe ändern => Setzen eines Integers), während das Neuzeichnen im Vergleich furchtbar lange dauert. Erst wenn ich alles gesetzt habe und zurückkehre in den NTUI Code, wird dann neu gezeichnet was "dirty" ist. Die Responsivität leidet darunter nicht, im Gegenteil, wenn mehrfaches Refresh vom Prinzip her verhindert wird ist es immer schön flott. @AGSzabo Du braucht keine Clipping flags oder sowas. Jedes Widget kann geclippt werden. Ich glaube wir reden etwas aneinander vorbei. Des weiteren denke ich, dass der Aufwand den Tree abzusteigen überschätzt wird. Es ist ja gerade die Tree Struktur, durch die sich die betroffenen Widgets sehr schnell ermitteln lassen, egal ob Mausklick, Refresh etc. -- -- 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 13.07.2011 um 09:59 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 10:28 Uhr Holger Posts: 8116 Nutzer |
Zitat:Er will keinen Refresh erzwingen, sondern den automatischen Refresh bei Bedarf verzögern. Zitat:Ja, genau davon sprach ich. Wenn Deine Änderungen innerhalb eines Callbacks geschehen, es also einen Zeitpunkt gibt, zu dem der Code zum Toolkit „zurückkehrt“, dann kannst Du das problemlos machen. Dann ist es auch die beste mir bekannte Vorgehensweise. Beim klassischen AmigaOS-API sind Callbacks aber eher die Ausnahme. Deshalb funktioniert es dort nicht so. Zitat:Wenn es um simple Clip-Operationen geht, ja. Die Optimierung, die ich beschrieben habe, betreffen aber einen Zeichenvorgang. Dabei ist natürlich mindestens jeder Parent teilweise innerhalb des ClipRect und muss seine Zeichenroutinen durchlaufen, auch wenn diese durch das Clipping der einzelnen Operationen effektiv auf eine No-Op hinauslaufen. Aber das System muss hier davon ausgehen, dass jedes einzelne Element an dieser Stelle User-Code mit unbekannten Overhead aufrufen könnte. Wenn es also einen einfachen Algorithmus gibt, der das umgehen kann, spricht nichts dagegen, diesen zu verwenden. -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 10:30 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: > Ich glaube wir reden etwas aneinander vorbei. Daher fragte ich, ob du es mir genau erklären könntest. Also nur wenn du lust hast. -- 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 - ] |
13.07.2011, 16:26 Uhr AGSzabo Posts: 1663 Nutzer |
hier nochmal mein aktualisierter SuperRefresh. Er funktioniert, bis darauf, daß alle schwesterwidgets nach einem clippenden widget garnimmer gezeichnet werden. ich müsste irgednwie den clip des parents der schwestern reinstallieren. hat jemand vorschläge oder findet den 'bug' (ich weiss, es ist ein denkfehler drin).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 BITDEF sr,DRAWCHILDS,1 BITDEF sr,CLIPPING,2 BITDEF sr,STOP,3 pushm d2-d7/a2/a4/a5/a6 move.l oxO_drawinfo(a0),a4 btst #oxDIB_WINDOWOPEN,oxDI_flags(a4) beq .pop move.l oxDI_window(a4),a1 move.l oxDI_windowobject(a4),a0 ; store window object pointer for install_clip move.l a0,a2 ; 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) movem.w sr_left(a5),d4-d7 bsr .first_member lea sr_SIZEOF(a7),a7 ; remove any clips from layer bclr #oxDIB_CLIPPING,oxDI_flags(a4) bsr remove_clip .pop popm d2-d7/a2/a4/a5/a6 rts .first_member pushm a0/a5 lea -sr_SIZEOF(a7),a7 ; make all childs redrawn move.b sr_flags(a5),sr_flags(a7) bclr #srB_DRAWCHILDS,sr_flags(a5) beq .copy_rect bset #srB_DRAWING,sr_flags(a7) .copy_rect ; movem.w d4-d7,sr_left(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 bclr #srB_DRAWCHILDS,sr_flags(a5) btst #srB_DRAWING,sr_flags(a5) bne .draw btst #oxOB_REFRESH,oxO_flags(a0) beq .clip bset #srB_DRAWCHILDS,sr_flags(a5) .draw bclr #oxOB_REFRESH,oxO_flags(a0) moveq #OXM_DRAW,d1 moveq #0,d2 bsr _oxDoMethod tst.l d0 beq .clip bset #srB_STOP,sr_flags(a5) .clip ; apply clip for childs here ? move.l oxO_class(a0),a1 btst #oxCB_CLIPPING,oxC_flags(a1) beq .check_stop lea -ra_SIZEOF(a7),a7 move.l a7,a1 moveq #OXM_GETCLIP,d1 ; cannot fail bsr _oxDoMethod movem.w (a1),d0-d3 movem.w sr_left(a5),d4-d7 bsr shrink_clip ; for the childs make this as new cliprect movem.w d4-d7,sr_left(a5) movem.w d4-d7,oxDI_cliprect(a4) bset #srB_CLIPPING,sr_flags(a5) bset #oxDIB_CLIPPING,oxDI_flags(a4) pushm a0/a6 bsr install_clip popm a0/a6 lea ra_SIZEOF(a7),a7 .check_stop bclr #srB_STOP,sr_flags(a5) bne .parent_clip bsr .members .parent_clip ; reinstall clip after doing childs in subclip ;movem.w sr_left(a5),d4-d7 ;pushm a0/a6 ;bsr install_clip ;popm a0/a6 bra .next_member .return lea sr_SIZEOF(a7),a7 popm a0/a5 rts .members bsr .first_member moveq #OXM_GETCONTINUE,d1 bsr _oxDoMethod tst.l d0 beq .rts push a0 move.l d0,a0 bsr .first_member pop a0 .rts rts shrink_clip ; shrink box borders to smallest .left cmp.w d4,d0 ble .right move.w d0,d4 .right cmp.w d6,d2 bge .top move.w d2,d6 .top cmp.w d5,d1 ble .bottom move.w d1,d5 .bottom cmp.w d7,d3 bge .rts move.w d3,d7 .rts 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 [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 16:47 Uhr Der_Wanderer Posts: 1229 Nutzer |
Ich glaube nicht, dass sich jemand in den Source einlesen will, schon gar nicht bei Assembler. ;-) Ich verstehe nicht ganz warum du den Clip nicht restaurieren kannst. Wie gesagt, ich versuche das mal zu veranschaulichen, aber dafür brauch ich eine ruhige Minute. -- -- 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 - ] |
13.07.2011, 17:28 Uhr Der_Wanderer Posts: 1229 Nutzer |
Im Prinzip sieht die Zeichenfunktion für jedes Widget so aus: (Pseudo Code) code:METHOD Widget::Draw(Rect clip) { IF (this OUTSIDE clip) RETURN // wir sind ausserhalb des clips => und tschüss! myclip = clip AND this.boundary // verenge den Clip auf unsere Boundaries (Schnittmenge) oldclip = INSTALLCLIPREGION(myclip) // setze den Clip für die Zeichenfunktionen DRAW_BACKGROUND_FOR_THIS_WIDGET // male unser Widget, z.b. Group Frame oder einen Button FOR EACH this.child { // falls wir Kinder haben, dann male diese auch, mit dem verengten Clip this.child.Draw(myclip) } DRAW_FORGROUND_FOR_THIS_WIDGET // falls vorhanden, z.b. ein Glossy Effekt oder überlappende Elemente wie Slider Marker myclip = INSTALLCLIPREGION(oldclip) // alten Clip wieder herstellen FREECLIPREGION(myclip) // unseren frei geben RETURN // und wech! } Wenn man z.b. einen Button neu zeichnen will, dann ruft man root.Draw(Button.boundary) (wobei "root" normalerweise ein Fenster ist) auf, und alles sollte genau so laufen wie es soll... Für einen completten Refreh des Fensters würde man root.Draw(root.boundary) aufrufen, oder z.B. NULL als Boundary, um anzuzeigen dass man initial keinen Clip hat. -- -- 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 13.07.2011 um 17:31 Uhr geändert. ] [ Dieser Beitrag wurde von Der_Wanderer am 13.07.2011 um 17:34 Uhr geändert. ] [ Dieser Beitrag wurde von Der_Wanderer am 13.07.2011 um 17:36 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 19:17 Uhr Holger Posts: 8116 Nutzer |
Zitat:Sowohl als auch. Alles, was Bestandteil der öffentlichen Schnittstelle ist. Zitat:Wahrscheinlich doch. -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 19:24 Uhr Thore Posts: 2266 Nutzer |
Ein Notify ist eine Reaktion auf ein Event. Das was Du gemacht hast ebenso. [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 19:29 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: Gute Idee mit dem Foreground. So lassen sich zB Effekte wie "Ghosted" realisieren wenn der Ghost ein Muster sein soll, dass dem Gadget überlagert wird... bisher hatte ich das so gemacht, daß das gadget im Ghosted Fall seinen Inhalt auch wenn er aus Objekten besteht selbe rzu zeichnen in Auftrag gibt und dann gosted und durch den rückgabewert dem system refresh dann mitteilt dass der nicht selber weiter machen soll. -- 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 - ] |
13.07.2011, 21:08 Uhr Der_Wanderer Posts: 1229 Nutzer |
Den Foreground habe ich eigentlich noch nie benutzt. Wie auch immer, hast du das mit dem Draw "von oben" jetzt verstanden? Genau den gleichen Mechanismus benutzen bei mir eigentlich alle Widget Methoden, die da wären: CalculateMinSize(); Berechnet die Mindestgröße des Widgets. code:METHOD Widget::CalculateMinSize() { FOR EACH this.child { this.minsize += this.child.CalculateMinSize(); } this.minsize += ownminsize RETURN this.minsize } Layout(); Setzt die tatsächlichen Boundaries der Widgets. code:METHOD Widget::Layout(boundary) { this.boundary = boundary FOR EACH this.child { this.child.Layout(PART_OF(boundary)); } } Draw(); Zeichnet die Widgets. s.o. DispatchEvent(); Sendet Events (Mouseklick, Keyboard etc.) an die Widgets. code:METHOD Widget::DispatchEvent(event) { FOR EACH this.child { IF HASFOCUS(this.child) done = this.child.DispatchEvent(event); } IF NOT INTERESTED (event) THEN RETURN FALSE IF done=TRUE THEN RETURN TRUE DO SOMETHING WITH EVENT // z.b. Status updaten oder Notify generieren RETURN TRUE } Init() Initialisiert ein Widget. code:METHOD Widget::Init() { INITIALIZE this // wenn wir Kidner brauchen, z.b. Scroller oder Knöpfe: this.child = CREATE NEW WIDGET } Deinit() Gibt die Resourcen eines Widgets frei. code:METHOD Widget::Deinit() FOR EACH this.child { this.child.Deinit(); } FREE this } SetAttr() Setzt ein Attribut eines Widgets. SetAttr() Liesst ein Attribut eines Widgets. -- -- 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 13.07.2011 um 21:18 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
13.07.2011, 21:23 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: Vom Prinzip her verstanden ja, es hapert aber an meiner Umsetzung. Meine SuperRefresh Routine funktioniert nicht richtig, weil ich mit der paramterübergabe der rekursion nicht klar komme. ich schaffe es nicht, den parent clip so zu merken, dass er wieder eingebaut werden kann nachdem die childs gezeichnet worden sind. Initfunktionen habe ich drei: 1. SETDEF: füllt das objekt mit initialen default attributwerten. 2. dann kommen die SetAttrs aus der erzeugungstagliste rein. 3. CREATE: weist die Klasse an auf der Basis der jetzigen Attributwerte betimmte subelemente zu erzeugen, zB in einem Imagebutton den Text und das Image, wobei in schritt 2 zB der name des images empfangen wurde. 4. system sendet globale parameter an alle, zB zeiger auf den rastport, damit der text seine größe richtig berechnen kann 5. INIT: jetzt ist es ok alles im zusammenhang nochmal zu initialisieren. ps: layout passiert bei mir indem jedes widget eine infostruktur an seine kinder weiterreicht und diese dann ihre maße da rein schreibe. letztlich kommen die gesamtmindestmaße wieder zum fenster zurück. dann gibts noch setlayout, das änlich funktioniert. EDIT: ich habe die rekursion jetzt im grunde hinbekommen! es war auch ein registerrettungsfehler drin. braucht den source von mir nimmer zu debuggen, danke. -- 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 13.07.2011 um 21:26 Uhr geändert. ] [ Dieser Beitrag wurde von AGSzabo am 13.07.2011 um 22:56 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
14.07.2011, 17:52 Uhr AGSzabo Posts: 1663 Nutzer |
An Der Wanderer: Wie machst du es im Fall von Tabs-Gadgets, wo immer nur 1 Inhalt (subobjektebaum) an der front ist? soll ja nur einer der mehreren gezeichnet werden. ich mache es so, dass ich immer nur den aktuellen tab-inhalt in die childsliste einhänge. und wenn ein anderes tab geklickt wird, hänge ich das aktuelle raus und das neue rein. gehts besser oder einfacher? -- 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 - ] |
14.07.2011, 18:02 Uhr Holger Posts: 8116 Nutzer |
Zitat:Natürlich. Wenn der Parent an die Kinder delegiert und eben jener Parent Tabs enthält und natürlich das aktive kennt, muss er nichts weiter machen, als an das aktive Tab zu delegieren, statt an alle. Natürlich kann man genausogut ein visible-Flag für jede Komponente unterstützen und im Fall von Tabs alle außer einem invisible setzen. Die allgemeine Liste der Kinder zu manipulieren, ist nicht empfehlenswert, da dies nur für bestimmte Operationen sinnvoll ist und alle anderen, die sich auf die ursprüngliche Semantik verlassen, torpediert, bzw. spezielle Workaround benötigt. Wenn man z.B. ein Objekt löscht, löscht es üblicherweise alle Kindobjekte. Was ist dann mit den nicht sichtbaren Tabs? -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
14.07.2011, 18:22 Uhr AGSzabo Posts: 1663 Nutzer |
@Holger: Das Delegieren gestaltet sich bei mir ein wenig kompliziert. Man muß schon wissen, was zu delegeiren ist, wie und an wen. Wenn man neue features in das system einbaut muss die delegierde klasse auch um dieses features delegierend erweitert werden? Die Objekte der nicht sichtbaren tabs werden in der deinit() routine des tabs disposed. ps: ich habs jetzt so am ändern, dass das system schon weiss, wann es was delegieren muss. das entspricht dem VISIBLE bit. invisible objekte erhalten keinen user input und auch noch einige andere sachen nicht. -- 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 14.07.2011 um 20:25 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
14.07.2011, 22:17 Uhr Der_Wanderer Posts: 1229 Nutzer |
Höre auf Holger. Die Kinder Widgets der Tabs sollten alle immer existieren. Aus der "richtigen" Liste der Kinder herauszunehmen oder gar zu deiniten ist keine gute Idee. Evtl. kannst du das mit einem "Hidden" Flag lösen, das Rekursiv für alle Kinder gesetzt wird. Z.b. möchtest du ein Widget aktualisieren können, obwohl es gerade nicht sichtbar ist. Wenn man dann den Tab umschaltet, sollte es dann den aktuellen Stand zeigen. Bei NTUI kannst du sogar Widgets aktualisieren deren Fenster zu ist. Als App Programmierer sollte dich nicht interessieren (müssen), ob, wo und in welchem Fenster ein bestimmtes Widget sichtbar ist. Dir kommt es ja nur auf die Logik an, nicht auf die Darstellung. Dadurch hat das Toolkit dann mehr flexibilität, z.b. an/abocken von Toolbars ist möglich, oder pop-up Menues die wiederum beliebige Widgets enthalten. -- -- 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 - ] |
15.07.2011, 07:25 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: Ok, ich habe es jetzt so mit einem VISIBLE-bit. Aber was ist, wenn ich nachträglich, im laufenden Betrieb zB neue tabs anfügen möchte? die objekte in den neuen tabs haben noch keinen oxDrawInfo-pointer in sich (nicht verwechseln mit der amiga os drawinfo), da ist zB der RastPortzeiger drin. Jetzt habe ich es so, das beim späteren anhängen von objekten diese auch den drawinfo-zeiger zugesandt bekommen (und dann auch nochmal ein Init()), und zwar von der klasse an deren objekt angehängt wird. geht es auch eleganter? Wenn man den Rastport nur zum zeichnen benötigen würde, täte ich ihn mit der DRAW methode mitsenden, aber ich brauche ihn, und auch den windowzeiger auch anderswo als nur beim 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 15.07.2011 um 07:29 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
15.07.2011, 12:45 Uhr Der_Wanderer Posts: 1229 Nutzer |
RastPort Pointer würde ich auf keinen Fall permanent in einem Widget ablegen. Ein sehr wichtiger genereller Tip: code:(=>Vermeidung von Redundanz)///////////////////////////////////////////////////////// // // // Niemals EINE Information an ZWEI Orten speichern! // // // ///////////////////////////////////////////////////////// Denn das führt schnell zu enormen sog. Bookkeeping Aufwand und ist eine super Quelle für Bugs. Bookkeeping bedeutet, du musst Code schreiben der eigentlich nix macht ausser zu gucken, dass auch ja immer überall der richtige RastPort eingetragen ist, also purer Overhead Code. Deshalb: Speichere den RastPort nur an einem Ort. Wenn es ein Window ist, dann steht er in der Window Structur bereits drin, als mache KEINE Kopie davon. Wenn er gebraucht wird, dann sollte er sich vom Window besorgt werden. Ist ja kein Problem den bei Draw, MinSize oder Layout als Parameter zu übergeben. Das gleiche gilt für den AmigaOS-Window Pointer selbst. Bei mir steht er nur an einer Stelle, nämlich im Window Objekt, das den AmigaOS Window Pointer hält, falls das Window offen ist. Kann ja auch geschlossen sein, und das Window Objekt existiert trotzdem noch, z.b. beim Iconifizieren. Generell würde ich von der Denkweise abrücken, dass nur existiert was man auch sieht (wie es AmigaOS macht). In NTUI baue ich die GUI auf, und die Applikation kann mit ihr ganz normal arbeiten, egal in welchem Zustand sie ist. D.h. in Iconifiziertem zustand kann ich genauso Werte setzen oder auslesen, als wenn das Fenster offen ist oder auch geschlossen, ob das Widget nun auf einem nicht sichtbaren Tab ist oder nicht. D.h. die App selbst muss keine Kenntnis über das Aussehen der GUI haben. -- -- 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 15.07.2011 um 12:58 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
15.07.2011, 12:55 Uhr Der_Wanderer Posts: 1229 Nutzer |
Achja, und wichtig ist es gedanklich zwischen verschiedenen Formen von "Visible" zu unterscheiden. Das was du "Visible" nennst, nenne ich in NTUI "OnScreen" und bedeutet, dass das Widget tatsächlich auf dem Bildschirm sichtbar ist, also z.b. auf Refresh Anfragen reagiert oder verwirft. Dieses Flag darf ausschließlich die Layout Methode setzen oder löschen. Im Gegensatz dazu gibt es gibt es ein Visibility Feld in jedem Objekt, das anzeigt wie unser Objekt layouted werden soll. Diese Feld kann man mit Get/SetAttr ändern als User. Visiblity kann "Visible", "Hidden" oder "Gone" sein. "Visible" ist klar, d.h. das Widget wird ganz normal layouted und ist sichtbar, bekommt als ggf. das OnScreen Flag gesetzt. "Hidden" heißt, dass zwar der Platz im Layout berücksichtigt wird, es wird also layouted, aber es wird nicht gezeichnet (wird also auch niemals "OnScreen"). "Gone" bedeutet, das Objekt existiert war (und kann z.B. mit Get/SetAttr angesprochen werden), wird aber vom Layout komplett ignoriert als wäre es nicht da. -- -- 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 - ] |
15.07.2011, 13:18 Uhr AGSzabo Posts: 1663 Nutzer |
@Der_Wanderer: der rasport ist nicht an zwei orten. jedes objekt hat lediglich einen pointer auf die drawinfo und da ist dann der rastport auch drin. die drawinfo gehört zu window und gibts nur einmal. etwas vom window zu erfragen setz vorraus, daß das widget die windowaddresse kennt. da kann ich gleich nen zeiger auf ne ganze drawinfo an alle senden ... das wird intern gehandhabt, der dispatcher brauch das nicht zu machen (kann er aber wenn er will in einigen ausnahmefällen). so komfortabel mit dem visible brauche ich es garnicht ... ich hab nur ein flag und das zeigt ob das objekt on screen ist. das führt zu vielen vorteilen und wird vom system gesetzt so wie es das fenster und sie klassen wollen. ein unsichtbares objekt das zwar platz einnimmt ... wofür? übrigens, ich habe ein "pages" widget, das kann multiple inhalte an der selben stelle, von denen im layout der größte genommen wird und von denen nur einer an der front sein kann. die anderen werden dann der funktion SetVisible(false) übergeben. ps: was ist mit einem popup-menu? es ist nicht on screen und will trotzdem sichtbar sein und auch mausklicks erhalten und mehr. darf ein popup menu im objektebaum mit drin sein? wie geht das dann? pps: wenn du den rasport mit dem layout misenden willst, müsste das layout auch immer von ganz oben kommen. ein balance-widget kann es nicht selber nur an seine beiden childs senden ... oder? -- 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 15.07.2011 um 13:33 Uhr geändert. ] [ Dieser Beitrag wurde von AGSzabo am 15.07.2011 um 13:35 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
15.07.2011, 13:37 Uhr Holger Posts: 8116 Nutzer |
Zitat:Die gleiche Frage kannst Du auch umgekehrt, bei Deiner Vorgehensweise stellen: Wenn man neue Features in das System einbaut muss die Tab-Klasse auch um die Weiterleitung dieses Features an die echte, statt der falschen Kind-Liste erweitert werden? Zitat:Ich würde so etwas auf keinen Fall im Objekt speichern, das ist nicht nur Speicherverschwendung, sondern führt zu einer falschen Semantik. Klar brauchst Du solche Informationen auch für andere Operationen als das Zeichnen. Trotzdem sind das alle Operationen, die somit diese Informationen als Parameter übergeben bekommen können. Eine immer präsente Information verführt dazu, sie auch dann zu benutzen, wenn ihre Gültigkeit gar nicht sicher ist. Also außerhalb der Operationen, für die sie eigentlich gedacht ist. Zitat:Du hast diese Information trotzdem überall kopiert. Wenn man einen Teilbaum in einen anderen Baum verschiebt, muss man trotzdem diverse Klimmzüge für etwas machen, was anderswo mit der Änderung von einem, maximal zwei Pointern abgehakt wäre. Zitat:Damit sich nicht das gesamte Layout verändert, wenn es später eingeblendet wird. Tabs sind doch das einfachste Beispiel dafür. Wenn ein nicht sichtbarer Tab mehr Platz benötigt als der sichtbare, soll dann beim Umschalten des Tabs das gesamte Fenster inkl. aller Komponenten neu layoutet werden, oder reservierst Du von Anfang an so viel Platz für die Tabs, dass auch nicht sichtbare Tabs Platz hätten? Zitat:Hat dieses Flag denn etwas mit dem Layout zu tun? An sich ist doch ein Objekt on-screen, wenn es (und alle seine Parents) visible und der Root ein Fenster ist, dass tatsächlich geöffnet ist. Diese Eigenschaft ändert sich doch nicht durch layouten. -- Good coders do not comment. What was hard to write should be hard to read too. [ - 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-2024 by amiga-news.de - alle Rechte vorbehalten. |