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

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

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


From: Yavor Doganov
Subject: Аналог на GDK_INVERT при cairo/GTK 3
Date: Sat, 09 Nov 2019 22:08:28 +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)

Здравейте,

Тези дни съм се нагърбил с обновяването на Genius[1], което касае
няколко библиотеки:

  * GTK 2 -> 3
  * GtkSourceView 2 -> 4
  * Vte 0.28 -> 2.91
  * GtkExtra (вградена) от GTK 2 -> 3

Основната работа съм я свършил, програмата работи горе-долу добре
вече, но има някои неща за доизкусуряване.  (Кръпката е тлъста --
близо 400K, засега.)

При избор на "Plot" от лентата с инструменти (или Calculator->Plot...)
от менюто се появява диалогов прозорец, където могат да се въведат
математически функции, които след натискане на бутона "Plot" се
визуализират в графика.  Този изглед има опция за Zoom -- потребителят
може да избере регион от графиката с мишката, като при провлачване се
променя размера на пунктирания правоъгълник, който очертава региона.
След отпускане на левия бутон правоъгълника изчезва и графиката се
преначертава съобразно избрания регион и новия мащаб.

Ударих на камък с тоя пунктиран правоъгълник, който се променя чрез
движението на мишката.  При GTK 2 той се чертае чрез създаден GdkGC с
функцията GDK_INVERT [2].  Аз промених тази функция така (съкращавам я
нарочно, защото дъщерния обект canvas->active_item винаги е NULL):

{
  GdkDrawingContext *ctxt;
  GdkWindow *window;
  cairo_region_t *region;
  cairo_t *cr;
  const double dashes[] = { 5., 5. };

  window = gtk_widget_get_window (GTK_WIDGET (canvas));
  region = gdk_window_get_clip_region (window);
  ctxt = gdk_window_begin_draw_frame (window, region);
  cr = gdk_drawing_context_get_cairo_context (ctxt);

  cairo_set_dash (cr, dashes, 2, 0);
  cairo_set_line_width (cr, 1);
  cairo_rectangle (cr, area.x, area.y, area.width, area.height);
  cairo_stroke (cr);

  gdk_window_end_draw_frame (window, ctxt);
  cairo_region_destroy (region);

  gtk_widget_queue_draw (GTK_WIDGET (canvas));
}

Работи както се очаква, но правоъгълника примигва сериозно, защото
gtk_widget_queue_draw задейства основния сигнал ::draw [3], който
изчертава наново цялата графика, и това се случва много пъти, докато
се движи мишката.  При спиране на движението (но все още натиснат
бутон), пунктирания правоъгълник изчезва, отново заради ::draw.

Ако заменя gtk_widget_queue_draw с gtk_widget_queue_draw_area и
опреснявам само area, то примигване няма, но няма и опресняване, ако
правоъгълника се смалява.  При смаляване се изобразяват вложени
правоъгълници, което е недопустимо.  Ако пък премахна *_queue_draw
изцяло, съвсем очаквано вложените правоъгълници остават навсякъде при
движението на мишката, независимо дали маркирания регион се уголемява
или смалява.

Изглежда не съм първия, който се сблъсква с този проблем:

https://mail.gnome.org/archives/gtk-app-devel-list/2010-August/msg00050.html

В същата нишка друг човек е написал програма-демонстрация, която
решава този проблем.  Има и клон gtk3, който се компилира, след като
замених HUGE с FLT_MAX.  Програмата работи прекрасно, без видимо
забавяне при чертането.  Но ми изглежда доста сложен този подход и
поне на пръв поглед ми се струва трудно да го приложа в моя случай.
Освен всичко друго, не е прието да се ползва чужд код в подобен род
кръпки, особено за тривиален (при GDK 2!) случай.

Някакви идеи как да реша този проблем?  Хрумна ми да експериментирам с
различни cairo_operator_t (_XOR и _DIFFERENCE), но не се получава
нищо.  Не би трябвало нещо толкова просто да се решава по толкова
сложен начин.

Ако наистина няма друг начин, как мога да преработя gtkcanvasplot.c
така, че да ползвам кода на тоя юнак?

[1] https://www.jirka.org/genius.html
[2] 
https://sources.debian.org/src/genius/1.0.24-2/gtkextra/gtkplotcanvas.c/#L2120
[3] 
https://sources.debian.org/src/genius/1.0.24-2/gtkextra/gtkplotcanvas.c/#L2033
[4] http://github.com/dov/dovtk-lasso



reply via email to

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