You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebindings/qtruby/rubylib/examples/qt-examples/progress/progress.rb

276 lines
7.2 KiB

#!/usr/bin/env ruby -w
require 'Qt'
class AnimatedThingy < TQt::Label
attr_accessor :label, :step
attr_accessor :ox0, :oy0, :ox1, :oy1
attr_accessor :x0, :y0, :x1, :y1
attr_accessor :dx0, :dx1, :dy0, :dy1
NTQIX = 10
def initialize(*k)
super(*k)
@label = k[1] + "\n... and wasting CPU\nwith this animation!\n"
@step = 0
@ox0, @oy0, @ox1, @oy1 = *Array.new(4) { Array.new(10, 0) }
@x0 = @y0 = @x1 = @y1 = 0
@dx0 = rand(8)+2
@dy0 = rand(8)+2
@dx1 = rand(8)+2
@dy1 = rand(8)+2
end
def show
startTimer(100) unless isVisible
super
end
def hide
super
killTimers()
end
def sizeHint
TQt::Size.new(120,100)
end
def inc(x, dx, b)
x += dx
if x < 0
x = 0
dx = rand(8) + 2
elsif x >= b
x = b-1
dx = -(rand(8)+2)
end
yield x, dx
end
def timerEvent(e)
p = TQt::Painter.new(self)
pn = p.pen
pn.setWidth(2)
pn.setColor(backgroundColor)
p.setPen(pn)
@step = (@step + 1) % NTQIX
p.drawLine(@ox0[@step], @oy0[@step], @ox1[@step], @oy1[@step])
inc(@x0, @dx0, width) { |x,dx| @x0, @dx0 = x, dx }
inc(@y0, @dy0, height) { |y,dy| @y0, @dy0 = y, dy }
inc(@x1, @dx1, width) { |x,dx| @x1, @dx1 = x, dx }
inc(@y1, @dy1, height) { |y,dy| @y1, @dy1 = y, dy }
@ox0[@step] = @x0
@oy0[@step] = @y0
@ox1[@step] = @x1
@oy1[@step] = @y1
c = TQt::Color.new
c.setHsv( (@step*255)/NTQIX, 255, 255 ) # rainbow effect
pn.setColor(c)
pn.setWidth(2)
p.setPen(pn)
p.drawLine(@ox0[@step], @oy0[@step], @ox1[@step], @oy1[@step])
p.setPen(colorGroup().text())
p.drawText(rect(), AlignCenter, @label)
p.end()
end
def paintEvent(event)
p = TQt::Painter.new(self)
pn = p.pen()
pn.setWidth(2)
p.setPen(pn)
p.setClipRect(event.rect())
0.upto(NTQIX-1) do |i|
c = TQt::Color.new()
c.setHsv( (i*255)/NTQIX, 255, 255 ) # rainbow effect
pn.setColor(c)
p.setPen(pn)
p.drawLine(@ox0[i], @oy0[i], @ox1[i], @oy1[i])
end
p.setPen(colorGroup().text())
p.drawText(rect(), AlignCenter, @label)
p.end
end
end
class CPUWaster < TQt::Widget
attr_accessor :menubar, :file, :options, :rects, :pb
attr_accessor :td_id , :ld_id, :dl_id, :cl_id, :md_id
attr_accessor :got_stop, :timer_driven, :default_label
slots 'drawItemRects(int)', 'doMenuItem(int)', 'stopDrawing()', 'timerDriven()'
slots 'loopDriven()', 'defaultLabel()', 'customLabel()', 'toggleMinimumDuration()'
FIRST_DRAW_ITEM = 1000
LAST_DRAW_ITEM = 1006
def initialize(*k)
super(*k)
@menubar = TQt::MenuBar.new(self, "menu")
@pb = nil
@file = TQt::PopupMenu.new
@menubar.insertItem( "&File", file )
FIRST_DRAW_ITEM.upto(LAST_DRAW_ITEM) {
|i| file.insertItem( "#{drawItemRects(i)} Rectangles", i)
}
connect( menubar, TQ_SIGNAL('activated(int)'), self, TQ_SLOT('doMenuItem(int)') )
@file.insertSeparator
@file.insertItem("Quit", $qApp, TQ_SLOT('quit()'))
@options = TQt::PopupMenu.new
@menubar.insertItem("&Options", options)
@td_id = options.insertItem("Timer driven", self, TQ_SLOT('timerDriven()'))
@ld_id = options.insertItem("Loop driven", self, TQ_SLOT('loopDriven()'))
@options.insertSeparator
@dl_id = options.insertItem("Default label", self, TQ_SLOT('defaultLabel()'))
@cl_id = options.insertItem("Custom label", self, TQ_SLOT('customLabel()'))
@options.insertSeparator
@md_id = options.insertItem("No minimum duration", self, TQ_SLOT('toggleMinimumDuration()'))
@options.setCheckable true
loopDriven
defaultLabel
setFixedSize(400, 300)
setBackgroundColor(black)
end
def drawItemRects(id)
n = id - FIRST_DRAW_ITEM - 1
r = 100
n.downto(0) { |n|
r *= (n%3 != 0) ? 5 : 4
}
r
end
def doMenuItem(id)
draw drawItemRects(id) if id >= FIRST_DRAW_ITEM && id <= LAST_DRAW_ITEM
end
def stopDrawing
@got_stop = true
end
def timerDriven
@timer_driven = true
@options.setItemChecked(@td_id, true)
@options.setItemChecked(@ld_id, false)
end
def loopDriven
@timer_driven = false
@options.setItemChecked(@td_id, false)
@options.setItemChecked(@ld_id, true)
end
def defaultLabel
@default_label = true
@options.setItemChecked(@dl_id, true)
@options.setItemChecked(@cl_id, false)
end
def customLabel
@default_label = false
@options.setItemChecked(@dl_id, false)
@options.setItemChecked(@cl_id, true)
end
def toggleMinimumDuration
checked = @options.isItemChecked(@md_id)
@options.setItemChecked(@md_id, !checked)
end
def timerEvent(e)
@pb.setProgress( @pb.totalSteps - @rects ) if @rects % 100 == 0
@rects -= 1
painter = TQt::Painter.new(self)
ww = width
wh = height
if ww > 8 and wh > 8
c = TQt::Color.new(rand(255), rand(255), rand(255))
x = rand(ww - 8)
y = rand(wh - 8)
w = rand(ww - x)
h = rand(wh - y)
painter.fillRect(x, y, w, h, TQt::Brush.new(c))
end
painter.end()
if @rects == 0 || @got_stop
@pb.setProgress(@pb.totalSteps)
painter = TQt::Painter.new(self)
painter.fillRect(0, 0, width(), height(), TQt::Brush.new(backgroundColor))
painter.end()
enableDrawingItems(true)
killTimers()
@pb = nil
end
end
def newProgressDialog(label, steps, modal)
d = TQt::ProgressDialog.new(label, "Cancel", steps, self, "progress", modal)
d.setMinimumDuration(0) if @options.isItemChecked(@md_id)
d.setLabel( AnimatedThingy.new(d, label) ) unless @default_label
d.show
d
end
def enableDrawingItems(yes)
FIRST_DRAW_ITEM.upto(LAST_DRAW_ITEM) {
|i| menubar.setItemEnabled(i, yes)
}
end
def draw(n)
if timer_driven
unless @pb.nil?
warn("This cannot happen!")
return
end
@rects = n
@pb = newProgressDialog("Drawing rectangles.\nUsing timer event.", n, false)
@pb.setCaption("Please Wait")
connect(@pb, TQ_SIGNAL('cancelled()'), self, TQ_SLOT('stopDrawing()'))
enableDrawingItems(false)
startTimer(0)
@got_stop = false
else
lpb = newProgressDialog("Drawing rectangles.\nUsing loop.", n, true)
lpb.setCaption("Please Wait")
painter = TQt::Painter.new(self)
0.upto(n) { |i|
if (i % 100) == 0
lpb.setProgress(i)
break if lpb.wasCancelled
end
cw, ch = width, height
c = TQt::Color.new(rand(255), rand(255), rand(255))
x = rand(cw - 8)
y = rand(cw - 8)
w = rand(cw - x)
h = rand(cw - y)
painter.fillRect(x, y, w, h, TQt::Brush.new(c))
}
lpb.cancel
painter.fillRect(0, 0, width, height, TQt::Brush.new(backgroundColor))
painter.end()
end
end
end
a = TQt::Application.new(ARGV)
w = CPUWaster.new
w.show
a.setMainWidget(w)
a.exec