LINUX.ORG.RU

Как в этом вашем GTK+ принято делать?

 , , , ,


0

2

Понадобилось написать простое графическое приложение, ну я тут же взял OpenGL и начал что-то клепать. Быстро надоело.
Решил заюзать что-то убердесктопное, выбор пал на Cairo.
Взял java-gnome, попытался собрать экзампл. Пример использует некий EventExpose, которого нет ни в библиотеке, ни в документации к ней.
Бегло пробежав по документации, я быстро переписал этот пример таким образом:

 /*
  * java-gnome, a UI library for writing GTK and GNOME programs from Java!
  *
  * Copyright © 2007-2010 Operational Dynamics Consulting, Pty Ltd and Others
  *
  * The code in this file, and the program it is a part of, is made available
  * to you by its authors as open source software: you can redistribute it
  * and/or modify it under the terms of the GNU General Public License version
  * 2 ("GPL") as published by the Free Software Foundation.
  *
  * This program is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GPL for more details.
  *
  * You should have received a copy of the GPL along with this program. If not,
  * see http://www.gnu.org/licenses/. The authors of this program may be
  * contacted through http://java-gnome.sourceforge.net/.
  */ 
 package cairo;
 
 import org.freedesktop.cairo.Context;
 import org.freedesktop.cairo.LinearPattern;
 import org.freedesktop.cairo.Pattern;
 import org.freedesktop.cairo.RadialPattern;
 import org.gnome.gdk.Event;
 import org.gnome.gtk.DrawingArea;
 import org.gnome.gtk.Gtk;
 import org.gnome.gtk.Widget;
 import org.gnome.gtk.Window;
 
 /**
  * Exercise drawing with the Cairo API. If you are rendering a custom Widget
  * or otherwise drawing stuff with Cairo that is to be presented by GTK, you
  * are expected to do this in the Widget.ExposeEvent handler for that Widget.
  * 
  * @author Andrew Cowie
  * @author Carl Worth
  * @author Dmitry Golovin
  */
 public class ExampleDrawing
 {
     public static void main(String[] args) {
         final Window w;
         final DrawingArea d;
 
         Gtk.init(args);
 
         w = new Window();
         w.setTitle("Drawing");
         w.setDefaultSize(150, 150);
 
         d = new DrawingArea();
         w.add(d);
         w.showAll();
 
         d.connect(new Widget.Draw() {
             public boolean onDraw(Widget source, Context cr) {
                 final Pattern linear, radial;
 
                 /*
                  * Now, finally do some drawing:
                  */
 
                 cr.setSource(1.0, 0.1, 0.0, 1.0);
                 cr.moveTo(10, 40);
                 cr.lineTo(120, 145);
                 cr.stroke();
 
                 /*
                  * If youre used to using RGB triplets, just normalize them to
                  * the 0.0 to 1.0 range by dividing by 255. It's all the same
                  * to Cairo, really.
                  */
 
                 cr.setSource(225 / 255.0, 148 / 255.0, 11 / 255.0, 1.0);
                 cr.rectangle(70, 70, 20, 40);
                 cr.fill();
 
                 /*
                  * Now a much more complicated example of drawing: a linear
                  * colour gradiant with a radial alpha mask.
                  */
 
                 linear = new LinearPattern(0, 0, 150, 150);
                 linear.addColorStopRGB(0.0, 0.0, 0.3, 0.8);
                 linear.addColorStopRGB(1.0, 0.0, 0.8, 0.3);
 
                 radial = new RadialPattern(75, 75, 15, 75, 75, 60);
                 radial.addColorStopRGBA(0, 0.0, 0.0, 0.0, 0.0);
                 radial.addColorStopRGBA(1, 0.0, 0.0, 0.0, 1.0);
 
                 cr.setSource(linear);
                 cr.mask(radial);
 
                 return true;
             }
         });
 
         /*
          * And that's it. Conclude with connecting the usual tear-down
          * handler, and then fire up the main loop.
          */
 
         w.connect(new Window.DeleteEvent() {
             public boolean onDeleteEvent(Widget source, Event event) {
                 Gtk.mainQuit();
                 return false;
             }
         });
 
         Gtk.main();
     }
 }
Может, я сделал не по канонам? Как делать правильно?

★★★★★

И что, работает?

Expose — gtk-шный сигнал. Думаю без него твоё нарисованное накернится при необходимости перерисовать окно, например, при изменении размера.

frob ★★★★★ ()
Ответ на: комментарий от frob

Работает, но хочется узнать у gtk-экспертов, всё ли я делаю так.

CYB3R ★★★★★ ()
Ответ на: комментарий от frob

Фиг знает как оно в жабу проброшено, судя по мануалу в виджете экспоса нет, вместо него дро. ТС, ты попробуй поресайзить, если все ок, то ок. Если нет, то нет. Как-то так :)

arturpub ★★ ()
Ответ на: комментарий от arturpub

Рисуется хорошо, только края (скрытые ранее части) немного мерцают. Так и должно быть?

CYB3R ★★★★★ ()
Ответ на: комментарий от CYB3R

Нет, но в гтк+каиро сложно отделить мерцание из-за непопадания в даблбуфер vs непопадания в рейт ресайза из-за тормозов. Попробуй рядом кинуть другой виджет / картинку и сравни. Если у тебя мерцает явнее, значит... я не помню что тогда делать, сорри, очень давно было.

В любом случае твой мануал по GtkWidget не упоминает Expose, а нестандартный Draw описан так, как и должен быть описан Expose. Думаю ты все правильно сделал.

arturpub ★★ ()

OpenGL

Java

Gtk

написать простое графическое приложение

Дамы и господа, поприветствуем нового мирового рекордсмена в делении на ноль!

buddhist ★★★★★ ()
Ответ на: комментарий от buddhist

Не, ну начал я на C и OpenGL, потом решил, что лучше для задачи подходит GTK+, начал курить доки, решил переписать на Java. Сначала перенёс на Java с OpenGL, но теперь решил освоить GTK+ на Java.

CYB3R ★★★★★ ()
Ответ на: комментарий от arturpub

Хммм... Этот Draw оказывается происходит только при изменении размера окна. А как мне самостоятельно его вызвать?
И есть ли какое-то событие, происходящее при передвижении курсора по виджету? При клике?

CYB3R ★★★★★ ()
Ответ на: комментарий от CYB3R

Вероятно не только при изменении размера.
А как ты в жабе заставишь объект класса исполнить один из его методов? Вот так и вызвать.

При передвижении: ищи как в гтк-шной жабе называется «motion notify», при клике «button-press»/«button-release».
Если ты собираешься таскать мышью что-то на своей картинке, то поищи как в жабе называются
gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK

Без учёта последнего при резких движениях добра по засиженному деталями экрану будет наблюдаться «езда на резиночке» — события будут скапливаться в очереди и ожидать отрисовки, таскаемая деталь будет ползать по экрану, с задержкой повторяя траекторию курсора.

frob ★★★★★ ()
Ответ на: комментарий от CYB3R

Уже нашёл MotionNotify, но перерисовывать по запросу по прежнему не умею.

CYB3R ★★★★★ ()

expose это gtk2, draw это gtk3.

waker ★★★★★ ()
Ответ на: комментарий от CYB3R

Не надо его самостоятельно вызывать, сделай виджету queue_draw() или как это в жабобиндинге называется. Ты вообще мануал-то по гтк-виджету пролистай хотя бы, прежде чем нас заставлять ходить по твоей же ссылке каждый раз. Там Widget.ButtonPressEvent первой строчкой идет.

http://java-gnome.sourceforge.net/doc/api/4.1/org/gnome/gtk/Widget.html

arturpub ★★ ()
Ответ на: комментарий от CYB3R

Этот Draw оказывается происходит только при изменении размера окна. А как мне самостоятельно его вызвать?

gtk_widget_queue_draw (widget);

waker ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.