diff --git a/src/GtkReactive.jl b/src/GtkReactive.jl index ac70162..80261f8 100644 --- a/src/GtkReactive.jl +++ b/src/GtkReactive.jl @@ -23,7 +23,7 @@ export set_coordinates, BoundingBox, SHIFT, CONTROL, MOD1, UP, DOWN, LEFT, RIGHT BUTTON_PRESS, DOUBLE_BUTTON_PRESS, destroy ## Exports -export slider, button, checkbox, togglebutton, dropdown, textbox, textarea, spinbutton, cyclicspinbutton +export slider, button, checkbox, togglebutton, dropdown, textbox, textarea, spinbutton, cyclicspinbutton, progressbar export label export canvas, DeviceUnit, UserUnit, XY, MouseButton, MouseScroll, MouseHandler export player, timewidget, datetimewidget diff --git a/src/widgets.jl b/src/widgets.jl index a5fa83f..882383f 100644 --- a/src/widgets.jl +++ b/src/widgets.jl @@ -946,3 +946,79 @@ function cyclicspinbutton{T}(range::Range{T}, carry_up::Signal{Bool}; CyclicSpinButton(signal, widget, id, preserved) end + +######################## ProgressBar ######################### + +immutable ProgressBar{T <: Number} <: Widget + signal::Signal{T} + widget::GtkProgressBarLeaf + preserved::Vector{Any} + + function (::Type{ProgressBar{T}}){T}(signal::Signal{T}, widget, preserved) + obj = new{T}(signal, widget, preserved) + gc_preserve(widget, obj) + obj + end +end +ProgressBar{T}(signal::Signal{T}, widget::GtkProgressBarLeaf, preserved) = + ProgressBar{T}(signal, widget, preserved) + +# convert a member of the interval into a decimal +interval2fraction(x::AbstractInterval, i) = (i - minimum(x))/IntervalSets.width(x) + +""" + progressbar(interval::AbstractInterval; widget=nothing, signal=nothing) + +Create a progressbar displaying the current state in the given interval; new iterations may be +displayed by pushing to the widget. Optionally specify + - the GtkProgressBar `widget` (by default, creates a new one) + - the (Reactive.jl) `signal` coupled to this progressbar (by default, creates a new signal) + +# Examples + +```julia-repl +julia> using GtkReactive + +julia> using IntervalSets + +julia> n = 10 + +julia> pb = progressbar(1..n) +Gtk.GtkProgressBarLeaf with 1: "input" = 1 Int64 + +julia> for i = 1:n + # do something + push!(pb, i) + end + +``` +""" +function progressbar(interval::AbstractInterval{T}; + widget=nothing, + signal=nothing, + syncsig=true, + own=nothing) where T<:Number + value = minimum(interval) + signalin = signal + signal, value = init_wsigval(T, signal, value) + if own == nothing + own = signal != signalin + end + if widget == nothing + widget = GtkProgressBar() + else + setproperty!(widget, :fraction, interval2fraction(interval, value)) + end + preserved = [] + if syncsig + push!(preserved, map(signal) do val + setproperty!(widget, :fraction, interval2fraction(interval, val)) + end) + end + if own + ondestroy(widget, preserved) + end + ProgressBar(signal, widget, preserved) +end + +progressbar(range::Range; args...) = progressbar(ClosedInterval(range), args...) diff --git a/test/runtests.jl b/test/runtests.jl index 07c3c9a..4a575f3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -204,6 +204,7 @@ include("tools.jl") @test G_.orientation(Orientable(widget(s))) == Gtk.GConstants.GtkOrientation.VERTICAL destroy(s) + # timewidget t = Dates.Time(1,1,1) s = Signal(t) tw = timewidget(t, signal=s) @@ -218,6 +219,7 @@ include("tools.jl") run_till_empty() @test value(tw) == value(s) == t + # datetimewidget t = DateTime(1,1,1,1,1,1) s = Signal(t) tw = datetimewidget(t, signal=s) @@ -231,6 +233,16 @@ include("tools.jl") push!(s, t) run_till_empty() @test value(tw) == value(s) == t + + # progressbar + pb = progressbar(1..10) + @test value(pb) == 1 + push!(pb, 5) + run_till_empty() + @test value(pb) == 5 + pb = progressbar(2:8) + @test value(pb) == 2 + end ## button