Okay, what works for me using your suggestion (except for me [with a 1 day 
old Julia and package] it's 'draw' and not 'redraw'), I have:

function update(canvas, scene::Scene)
  # update scene
  # ...
  
  # redraw
  draw(canvas)
end

function init(canvas, scene::Scene)
  update_timer = Timer(timer -> update(canvas, scene))
  start_timer(update_timer, 1, 0.5)
  return update_timer
end

function draw_scene(canvas, scene::Scene)
  ctx = getgc(canvas)
  h = height(canvas)
  w = width(canvas)

  rectangle(ctx, 0, 0, w, h)
  set_source_rgb(ctx, 1, 1, 1)
  fill(ctx)

  # use scene to draw other elements
  # ...
end

scene = Scene(...)
update_timer = init(canvas, scene)
draw(canvas -> draw_scene(canvas, scene), canvas)

if !isinteractive()
  cond = Condition()
  signal_connect(win, :destroy) do widget
    notify(cond)
  end

  wait(cond)
end

stop_timer(update_timer)


I wasn't sure if the way I bound the scene to the redraw is the nicest 
approach to take. If the function took additional parameters, that seems 
like it might be the most straight forward. E.g.:

draw(canvas, scene) do widget
   # ...
end

# here 'myscene' would be passed as the second parameter to the other draw
draw(canvas, myscene)


A

On Tuesday, June 17, 2014 1:16:11 PM UTC-4, Jameson wrote:
>
> Yes. Although I think the draw...do function is actually redraw...do 
> (this is actually a shared interface with Tk.jl, although I recommend Gtk :)
>
> Sent from my phone. 
>
> On Tuesday, June 17, 2014, Abe Schneider <abe.sc...@gmail.com 
> <javascript:>> wrote:
>
>> @Tim: Awesome, exactly what I was looking for. Thank you.
>>
>> @Jameson: Just to check, do you mean something like:
>>
>> function redraw_canvas(canvas)
>>   draw(canvas)
>> end
>>
>> draw(canvas) do widget
>>   # ...
>> end
>>
>> If so, I'll re-post my code with the update. It may be useful to someone 
>> else to see the entire code as an example.
>>
>> Thanks!
>> A
>>
>>
>> On Tuesday, June 17, 2014 10:44:16 AM UTC-4, Jameson wrote:
>>>
>>> This code is not valid, since getgc does not always have a valid drawing 
>>> context to return. Instead you need to provide Canvas with a callback 
>>> function via a call to redraw in which you do all the work, then just call 
>>> draw(canvas) in your timer callback to force an update to the view. 
>>> double-buffering is enabled by default.
>>>
>>> wait(Condition()) is the same wait(), and means sleep until this task is 
>>> signaled, and thereby prevents the program from exiting early
>>>
>>>
>>> On Tue, Jun 17, 2014 at 7:46 AM, Abe Schneider <abe.sc...@gmail.com> 
>>> wrote:
>>>
>>>> Thank you everyone for the fast replies!
>>>>
>>>> After looking at ImageView and the sources, here's the solution I came 
>>>> up with:
>>>>
>>>> w = Gtk.@Window() |>
>>>> (body=Gtk.@Box(:v) |>
>>>>   (canvas=Gtk.@Canvas(600, 600)) |>
>>>> showall
>>>>
>>>> function redraw_canvas(canvas)
>>>>   ctx = getgc(canvas)
>>>>   h = height(canvas)
>>>>   w = width(canvas)
>>>>
>>>>   # draw background
>>>>   rectangle(ctx, 0, 0, w, h)
>>>>   set_source_rgb(ctx, 1, 1, 1)
>>>>   fill(ctx)
>>>>
>>>>   # draw objects
>>>>   # ...
>>>>
>>>>   # tell Gtk+ to redisplay
>>>>   draw(canvas)
>>>> end
>>>>
>>>> function init(canvas, delay::Float64, interval::Float64)
>>>>   update_timer = Timer(timer -> redraw_canvas(canvas))
>>>>   start_timer(update_timer, delay, interval)
>>>> end
>>>>
>>>> update_timer = init(canvas, 2, 1)
>>>> if !isinteractive()
>>>>   wait(Condition())
>>>> end
>>>>
>>>> stop_timer(update_timer)
>>>>
>>>> I haven't looked yet into what is required to do double-buffering (or 
>>>> if it's enabled by default). I also copied the 'wait(Condition())' from 
>>>> the 
>>>> docs, though it's not clear to me what the condition is (if I close the 
>>>> window, the program is still running -- I'm assuming that means I need to 
>>>> connect the signal for window destruction to said condition).
>>>>
>>>> A
>>>>
>>>>
>>>> On Monday, June 16, 2014 9:33:42 PM UTC-4, Jameson wrote:
>>>>
>>>>> I would definately use Julia's timers. See `Gtk.jl/src/cairo.jl` for 
>>>>> an example interface to the Cairo backing to a Gtk window (used in 
>>>>> `Winston.jl/src/gtk.jl`). If you are using this wrapper, call `draw(w)` 
>>>>> to 
>>>>> force a redraw immediately, or `draw(w,false)` to queue a redraw request 
>>>>> for when Gtk is idle.
>>>>>
>>>>>
>>>>> On Mon, Jun 16, 2014 at 9:12 PM, Tim Holy <tim....@gmail.com> wrote:
>>>>>
>>>>>> ImageView's navigation.jl contains an example. The default branch is 
>>>>>> Tk
>>>>>> (because  as far as binary distribution goes, Tk is "solved" and Gtk 
>>>>>> isn't
>>>>>> yet), but it has a gtk branch you can look at.
>>>>>>
>>>>>> --Tim
>>>>>>
>>>>>> On Monday, June 16, 2014 04:01:46 PM Abe Schneider wrote:
>>>>>> > I was looking for a way to display a simulation in Julia. 
>>>>>> Originally I was
>>>>>> > going to just use PyPlot, but it occurred to me it would be better 
>>>>>> to just
>>>>>> > use Gtk+ + Cairo to do the drawing rather than something whose main 
>>>>>> purpose
>>>>>> > is drawing graphs.
>>>>>> >
>>>>>> > So far, following the examples on the Github page, I have no problem
>>>>>> > creating a window with a Cairo canvas. I can also display content 
>>>>>> on the
>>>>>> > canvas fairly easily (which speaks volumes on the awesomeness of 
>>>>>> Julia and
>>>>>> > the Gtk+ library). However, after looking through the code and 
>>>>>> samples,
>>>>>> > it's not obvious to me how to redraw the canvas every fraction of a 
>>>>>> second
>>>>>> > to display new content.
>>>>>> >
>>>>>> > I did find an example of animating with Cairo and Gtk+ in C
>>>>>> > (http://cairographics.org/threaded_animation_with_cairo/). 
>>>>>> However, I
>>>>>> > assume one would want to use Julia's timers instead of of GLibs? 
>>>>>> Secondly,
>>>>>> > there in their function 'timer_exe', call is made directly to Gtk+ 
>>>>>> to send
>>>>>> > a redraw queue to the window. Is there a cleaner way to do it with 
>>>>>> the Gtk+
>>>>>> > library?
>>>>>> >
>>>>>> > Thanks!
>>>>>> > A
>>>>>>
>>>>>>
>>>>>
>>>  

Reply via email to