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: Yavor Doganov
Subject: Re: Аналог на GDK_INVERT при cairo/GTK 3
Date: Tue, 12 Nov 2019 11:56:04 +0200
User-agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (Gojō) APEL/10.8 EasyPG/1.0.0 Emacs/26 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)

Kaloian Doganov wrote:
> On Mon, 2019-11-11 at 01:40 +0200, Yavor Doganov wrote:
> > Проблемът е, че при движението на мишката правоъгълника се променя и
> > нещо трябва да „трие“ следите.

> Тази (или всяка аналогична на GDK_INVERT) техника, обаче, разчита на
> това, че в даден момент знаем дали на екрана има нарисувана селекция
> или не.  [...] Визуално, резултатът е грозен артефакт на екрана.
> Всичко това е демонстрирано в screenshot-ите по- долу.

Да, наистина.  Страхотна функция си използвал, много ми помогна да
вникна в нещата, сякаш задейства дремещи когнитивни способности :-).
Винаги съм се чудил защо учители и университетски преподаватели
избягват подобни нагледни примери.  А добрият пример е отлична
предпоставка за успешен учебен процес.

> Иронията е, че това разминаване нямаше да се случи ако освен всичко
> друго ::draw рисуваше и селекцията.

Така е, убедих се вече.

> > Да, това е типична практика при много програми, писани за GTK 2 (и
> > 1.2, BTW), работи си без проблем.
> 
> Ако това е типична практика, значи масово не са се спазвали правилата
> на GUI framework-а

Ами да.  Вече сигурно над 20 програми съм портнал, почти всяка
по-сложна от тях си позволява да рисува извън expose_event.  API-то го
позволява, дори и при GTK 3 с gdk_cairo_create и по-новите функции
като gdk_window_begin_draw_frame.

> > Дори и да се чертае само от ::draw, това няма как да промени нещата и
> > няма как да ме улесни по никакъв начин.
> 
> Ако рисуването на widget-а включва и рисуването на селекцията (ако има
> активна такава), и в същото време прерисуваш напълно widget-а при
> движение на мишката, това ще реши проблема ти.  Няма да има нужда да
> триеш от екрана старото състояние на селекцията, понеже то ще се
> забърсва при изрисуването на графиката.

Разбира се, това е толкоз просто и логично.

> Това, което ти предлагам, е да сложиш рисуването на активната селекция
> на последно място в ::draw.

Това направих.  Промених draw_selection и
gtk_plot_canvas_child_draw_selection да приемат аргумент cairo_t,
и включих в края на ::draw:

  switch (canvas->action) {
    case GTK_PLOT_CANVAS_ACTION_DRAG:
    case GTK_PLOT_CANVAS_ACTION_RESIZE:
      if (canvas->active_item)
        gtk_plot_canvas_child_draw_selection (cr, canvas, canvas->active_item,
                                              canvas->drag_area);
      break;
    case GTK_PLOT_CANVAS_ACTION_INACTIVE:
      if (canvas->active_item && canvas->state == GTK_STATE_SELECTED)
        gtk_plot_canvas_child_draw_selection (cr, canvas, canvas->active_item,
                                              canvas->active_item->drag_area);
      break;
    case GTK_PLOT_CANVAS_ACTION_SELECTION:
      draw_selection (cr, canvas, NULL, canvas->drag_area);
      break;
    default:
      break;
  }

Навсякъде в event handler-ите замених извикването на тези две функции
с gtk_widget_queue_draw (също и в gtk_plot_canvas_unselect).  В
draw_selection, преди действителното чертане, пльоснах

  cairo_set_source_rgb (cr, 0, 0, 0);

Това е абсолютно необходимо, за да се извършва действителното чертане,
защото в началото на имплементацията на ::draw имам:

  cairo_set_source_surface (cr, pixmap, 0, 0);

Притеснява ме малко gtk_plot_canvas_button_release, където не съм
сигурен дали едно от условията

 if (canvas->action != GTK_PLOT_CANVAS_ACTION_INACTIVE && veto)

ще пасне на логиката в ::draw.

> Не само, че не е много сложно, ами е по-просто от това, което
> GtkPlotCanvas прави в момента.

Да, съгласен съм.  Единственият недостатък е, че се прерисува всичко
доста пъти.  Но по-важното е, че работи.

> > Не, това е генерален проблем при GTK и cairo, който не съществува при
> > GDK 2.  Както е писал потребителя във връзката, която дадох.
> 
> Не съм съгласен с тази оценка. Поне от това, което виждам дотук, GTK 2
> е бил използван неправилно.

Да, не съм бил прав.  Благодаря за насоките.



reply via email to

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