Как нарисовать на виджете DrawingArea с помощью Cairo? - PullRequest
0 голосов
/ 05 мая 2018

У меня есть маленький проект, в котором я пытаюсь использовать gi-gtk для рисования на окне.

https://github.com/bigos/cairo-example/blob/b9480dc63d6fff3bc195d35c7422f193fc8ae7d4/src/Main.hs

Я понял, как заставить gi-gtk работать с Каиром.

https://github.com/haskell-gi/haskell-gi/wiki/Using-Cairo-with-haskell-gi-generated-bindings

Но у меня проблема с получением контекста в Каире. В следующем коде у меня есть два события. Первое мероприятие работает отлично. Но я не могу понять, как получить контекст cairo, необходимый для рисования на канвах, когда я слушаю нажатия клавиш на объекте окна.

  win <- Gtk.windowNew WindowTypeToplevel
  canvas <- Gtk.drawingAreaNew
  Gtk.containerAdd win canvas

  _ <- Gtk.onWidgetDraw canvas $ \context ->
    renderWithContext context (updateCanvas canvas) >> pure True

  _ <- Gtk.onWidgetKeyPressEvent win $ \x -> do
    vvv <- Gdk.getEventKeyKeyval x
    -- How do I draw on canvas here?
    (putStrLn ("You have pressed key code " ++  (show vvv))) >> pure True

1 Ответ

0 голосов
/ 06 мая 2018

Проще говоря, вы не можете. У вас не будет доступа к контексту рисования за пределами обратного вызова onWidgetDraw.

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

  • В обратном вызове onWidgetKeyPressEvent установите значение в вашем глобальном состоянии, когда пользователь нажимает выбранную клавишу
  • В обратном вызове onWidgetDraw используйте это значение, чтобы определить, нужно ли рисовать текст или нет.

    В идеале, вы должны попытаться вписать свое состояние в монаду штата или что-то подобное - однако, в этом конкретном случае, Gtk не позволяет вводить монадическое состояние само по себе, так что это невозможно напрямую. Вы должны прибегнуть к IORef s, TVar s или любому другому эквиваленту.

    Удачи! :)
...