Seite 1 von 1
Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 29.10.2013 23:43
von Kurzer
Hallo,
mein Problem scheint auf den ersten Blick
hier schon einmal behandelt worden zu sein, aber eine Lösung habe ich dort leider nicht gefunden.
Ich programmiere ein Customgadget unter Verwendung des Canvas Gadgets.
Das Erscheinungsbild des Gadgets (81 Sudoku-Felder mit Zahlen) wird mit mehr oder weniger vielen Zeichenoperationen erstellt. Nun wird das Canvasgadget aber leider nach jeder Zeichenoperation neu auf dem Window gezeichnet. Das Gadget besteht aus 9 x 9 Feldern, die aus programmtechnischen Gründen nacheinander mit jeweils einem StartDrawing / Stopdrawing Block gezeichnet werden (es gibt halt eine Prozedur die ein einzelnes Feld zeichnet und die wird 81 mal aufgerufen).
Leider sieht man den Aufbau des Gadgets bzw. der Grafik schon recht deutlich, da das Canvasgadget sich immer wieder aktualisiert. Besser wäre es, wenn ich erstmal alles fertig zeichnen könnte und sich dann das Gadget einmal auf dem Window neuzeichnet.
Gibt's da eine Möglichkeit bei der ich kein Callback für das ganze Fenster erstellen muss, um die Canvas-repaints zu unterdrücken? Es soll ein universell einsetzbares Customgadget werden, daher möchte ich kein Callback auf das Fenster setzen, auf dem sich das Gadget später befinden wird. Das wäre meiner Meinung nach dann kein transparentes Verhalten.
Man kann das mit HideGadget() erreichen, aber dann ist das Gadget in der Zeit des Neuzeichnens komplett verschwunden. Das kommt auch nicht in Frage, da das Gadget später auch "während des Betriebs" z.B. mit neuen Zahlenreihen befüllt werden kann.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 29.10.2013 23:48
von STARGÅTE
Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 00:03
von Kurzer
STARGÅTE hat geschrieben:Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
Weil ich die Zeichenoperationen als einzelne, unabhängige Prozeduren realisiert habe, die auch einzeln aufrufbar sind. DrawGrid(), DrawCell(), DrawDebugNumbers()... die haben alle Ihre einzelnen Start/Stop Aufrufe.
Wenn ich das ganze Gadget zeichne, dann sind das zwei verschachtelte For Schleifen (1-9) in denen DrawCell(x,y) usw. aufgerufen wird.
Aber ich sehe schon, dass ich das dann wohl doch so umbauen sollte, dass die Prozeduren sowohl mit ihrem eigenen StartDrawing-Block als auch mit einem externen StartDrawing-Block außerhalb der Prozedur umgehen können.
Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Falls es so etwas wie ein RepaintOff(#Gadget, 1/0) nicht gibt, dann schreib ich meine Zeichenprozeduren nochmal um.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 00:16
von STARGÅTE
Das CanvasGadget bietet ja sogar SetGadgetAttribute(#Gadget, #PB_Canvas_Image, ImageID(...)).
Und das halte ich für "ungegurkt"
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 00:22
von Bisonte
Wenn ich das recht verstanden habe hast du sowas gemacht ? :
Code: Alles auswählen
Procedure DrawCell()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
Procedure DrawCellHere()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
Procedure DrawCellThere()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
; ----
Procedure NeuZEichnen()
DrawCell()
DrawCellHere()
DrawCellThere()
EndProcedure
Wobei sowas sinnvoller wäre :
Code: Alles auswählen
Procedure DrawCell()
Box(....
EndProcedure
Procedure DrawCellHere()
Box(....
EndProcedure
Procedure DrawCellThere()
Box(....
EndProcedure
; ----
Procedure NeuZEichnen()
StartDrawing(Canv....
DrawCell()
DrawCellHere()
DrawCellThere()
StopDrawing()
EndProcedure
Meinst du das ? Wenn nicht hab ich völliges missverständnis meinerseits
Ansonsten muss man auch nicht das komplette Canvas neuzeichnen, wenn sich nur ein Teil davon ändert.
Man braucht "nur" den Teil neu zeichnen, der sich auch tatsächlich ändert...
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 09:43
von Thorium
Kurzer hat geschrieben:
Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Das ist kein gegurke, das ist ganz normales Double Buffering wie es jedes Spiel verwendet um eben solche Effekte zu verhindern.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 10:03
von Lord
Vielleicht (Windows only):
Code: Alles auswählen
SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#False,0)
...
...
...
SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#True,0)
Eventuell danach ein
Code: Alles auswählen
RedrawWindow_(WindowID(#Window),#Null,#Null,#RDW_INVALIDATE|#RDW_UPDATENOW|#RDW_ERASE)
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Verfasst: 30.10.2013 13:21
von Kurzer
Danke für Eure Hinweise.
Das mit dem "gegurkt" klang vermutlich dramatischer, als ich es eigentlich gemeint hatte. Sorry.
Ich wollte die Image-Idee damit nicht schlechtreden, nur kam es mir nicht richtig vor, weil das Canvasgadget lt. PB-Hilfe von sich aus schon double buffered gezeichnet wird. Das Problem ist einzig, dass ich nicht bedachte habe, dass das double buffering mit Startdrawing eingeleitet und mit StopDrawing beendet wird. Ich werde meine Routinen dahingehend anpassen und dann funktioniert vermutlich alles genau im Sinne des Erfinders.
@Bisonte: Ja, so in etwa ist das richtig, wie Du es aufgezeigt hast. Zusätzlich nutze ich DrawCell(x,y) aber auch noch einzeln, um die Zelle unter der Maus hervorzuheben. Daher muss das auch einzeln funktionieren.
Ich werde die Startdrawing/StopDrawing-Befehle jetzt außerhalb der Zeichnungsprozeduren platzieren.
@Thorium & Stargate: Wie gesagt, das war ein Verständnisproblem. Double buffering ist mir geläufig, ich hab's im Fall des Canvasgadgets halt nur nicht korrekt angewendet (mehrfache Start-/StopDrawings). Die Nutzung eines extenen Images löst die Problematik mit den mehrfachen Start-/StopDrawings, erhöht aber den Verwaltungsaufwand für das Gadegt, da man das flipping koordinieren muss.
Ich brauchte halt nur einen Wink, um in die richtige Richtung zu denken. Ist hiermit erfolgreich geschehen.

Besten Dank.