gug-bg-herd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Аналог на GDK_INVERT при cairo/GTK 3


From: Kaloian Doganov
Subject: Re: Аналог на GDK_INVERT при cairo/GTK 3
Date: Sun, 10 Nov 2019 21:27:09 +0200
User-agent: Evolution 3.30.5-1.1

On Sun, 2019-11-10 at 13:44 +0200, Kaloian Doganov wrote:
> 
> При всички положения, обаче, ми се струва добра идея да се закачиш за
> ::draw и да рисуваш селекцията веднага след "стандартния" ::draw на
> графиката (по възможност синхронно, в същия пас на main queue-
> то).  По
> този начин, ако нещо друго в системата тригерира ::draw, ти ще си там
> за да си нарисуваш селекцията отгоре.

Едва сега попрегледах кода в gtkplotcanvas.c и, честно казано, ми се
струва, че логиката около рисуването на widget-а поначало е некоректна.
Авторът има имплементация на draw, която не рисува пълният state на
widget-а.  Вместо това изглежда, че draw рисува базовата графика, а
после авторът рисува допълнително в резултат от някакви събития (напр.
движение на мишката).  Това е доста кофти, защото ако draw бъде извикан
по друг повод, нарисуваното на екрана ще излезе от синхрон с
потребителския state.

Ето един пример, който е малко измислен, но е първото което се сетих
докато преглеждах кода: Ако натиснем левия бутон на мишката върху
графиката, преместим курсора за да се появи селекция, и -- без да
пускаме левия бутон -- натиснем клавишната комбинация за Maximize на
текущия прозорец, селекцията се одрисква.

Този ефект е пряко следствие от липсата на читав draw, който да
отразява текущия модел върху екрана. Изображението на екрана се
получава от основния draw, плюс още нафлякани неща върху него които се
рисуват не по време на draw -- при движение на мишката се трие старата
селекция, рисува се нова, т.н.  Това работи общо взето, но ако
събитията дойдат в неочакван за автора ред, илюзията рухва.  А нищо в
системата не гарантира, че събитията ще дойдат в желания от автора ред.

Най-простият начин да се организират тези неща е събитията да водят до
смяна на някакъв невидим state в widget-а (т.нар. модел), а draw да
рисува на базата на този невидим state.  Напр. event handler-а за
движение на мишката трябва само да сменя някакви числови координати в
модела на текущата селекция и да тригерира draw (независимо дали
синхронно с draw или асинхронно с queue_draw), който да ги нарисува. 
Това е най-простият начин да се осигури кохерентност.

Вярно е, че понякога тригерирането на пълен redraw при всяко събитие
може да води до големи разходи на ресурси.  Тогава може да е допустимо
да се правят врътки, да се "patch"-ва вече нарисуваното от draw
изображение, и какво ли още не.  Това, обаче, са оптимизации, които
никога не бива да бъдат за сметка на способността на draw да нарисува
целия widget когато се наложи.  Една GUI система винаги може да
инвалидира widget-а ни, и ние трябва винаги да сме способни да го
нарисуваме в неговата пълнота.  Ако няколко user event-а са единствения
начин за рисуване на селекцията, значи draw не може да нарисува целия
widget в неговото актуално състояние.

Струва ми се, че проблемите които срещаш с портването на селекцията са
следствие от това, че авторът поначало е организирал рисуването
нехигиенично.


Между другото, gtk_plot_canvas_child_draw е декларирана два пъти, но
това е бял кахър.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]