Class: Gui

Inherits:
Qt::Widget
  • Object
show all
Defined in:
lib/mamba.rb

Overview

oky, this will become a visualizer for large data sequences

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width, height, parent = nil) ⇒ Gui

Returns a new instance of Gui.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/mamba.rb', line 14

def initialize(width,height,parent = nil)
  super()
  @width,@height = width,height
  resize(@width,@height)
  @lfw = 16 # legend font width
  @tfw = 15 # timestamp font width
  @pfw = 11 # predicate font width
  #text will not be filled
  #@brush = Qt::NoBrush
  #text will be filled
  @brush = Qt::Brush.new Qt::Color.new 0, 0, 0
  @current_color = 0
  #generate these deltas
  deltas = []
  #display these predicates
  @predicates = [:boh, :pd, :wp, :we]
  #graph with the data we want to visualize
  #@graph = Graph.new "V06",deltas,@height/12
  @graph = Graph.new "",deltas,@height/12,true #will build graph from table 'TrackerTest'
  #max movement speed
  @speedlimit = 20
  #setup the rest
  setup
  #method doing the x scrolling for us
  dlog "Initialized, starting active scroll loop."
  reactive_scroll
end

Instance Attribute Details

#heightObject

Returns the value of attribute height.



11
12
13
# File 'lib/mamba.rb', line 11

def height
  @height
end

#mousexObject

Returns the value of attribute mousex.



12
13
14
# File 'lib/mamba.rb', line 12

def mousex
  @mousex
end

#mouseyObject

Returns the value of attribute mousey.



12
13
14
# File 'lib/mamba.rb', line 12

def mousey
  @mousey
end

#widthObject

Returns the value of attribute width.



11
12
13
# File 'lib/mamba.rb', line 11

def width
  @width
end

#x_deltaObject

Returns the value of attribute x_delta.



12
13
14
# File 'lib/mamba.rb', line 12

def x_delta
  @x_delta
end

Instance Method Details

#build_blackout_path(hand) ⇒ Object

build painter path for blackout graph



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/mamba.rb', line 136

def build_blackout_path hand
  name = "blackout_#{hand}".to_sym
  color = Qt::Color.new(0, 0, 64) if hand.eql? :left
  color = Qt::Color.new(64, 0, 0) if hand.eql? :right
  #y-translation of the graph, we only need y
  ty = 10*@height/12+@lfw/2
  ty -= @lfw if hand.eql? :left
  ty += @lfw if hand.eql? :right
  path = Qt::PainterPath.new
  path.moveTo 0,0
  #now we construct the path
  @graph.points.each do |ts,v|
    unless v[hand][:blackout]        
     path.moveTo v[hand][:x],0
    else
     path.lineTo v[hand][:x],0
    end   
  end
  #and return the values
  return { :y => ty, :name => name, :path => path, :color => color, :width => 2.5 }
end

#build_delta_path(hand, delta) ⇒ Object

build painter path for delta graph



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/mamba.rb', line 177

def build_delta_path hand,delta   
  name = "#{delta}_#{hand}".to_sym
  color = Qt::Color.new(64, 0, @current_color%255) if hand.eql? :left
  color = Qt::Color.new(@current_color%255, 0, 64) if hand.eql? :right
  #change color for next delta
  @current_color += 16
  ty = 7*@height/12
  path = Qt::PainterPath.new
  path.moveTo 0,0
  #now we construct the path
  @graph.points.each do |ts,v|
    path.lineTo v[hand][:deltas][delta][:point]
  end
  #and return the values
  return { :y => ty, :name => name, :path => path, :color => color }
end

#build_euler_path(hand, angle) ⇒ Object

build painter path for euler graph



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/mamba.rb', line 159

def build_euler_path hand,angle  
  name = "#{angle}_#{hand}".to_sym
  color = Qt::Color.new(255, 0, 0) if angle.eql? :alpha
  color = Qt::Color.new(0, 255, 0) if angle.eql? :gamma
  color = Qt::Color.new(0, 0, 255) if angle.eql? :beta
  #y-translation of the graph, we only need y
  ty = @height/6
  path = Qt::PainterPath.new
  path.moveTo 0,0
  #now we construct the path
  @graph.points.each do |ts,v|
    path.lineTo v[hand][:euler][angle][:point]
  end
  #and return the values
  return { :y => ty, :name => name, :path => path, :color => color }
end

#build_legend_pathObject

build painter path for the legend



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mamba.rb', line 62

def build_legend_path
  p = Qt::PainterPath.new
  p.moveTo 0,0
  font = Qt::Font.new "Arial", @lfw
  p.addText @lfw,1.5*@lfw, font, "LEFT: euler angles"
  p.addText @lfw,2*@height/12, font, "RIGHT: euler angles"
  p.addText @lfw,5*@height/12, font, "LEFT: data"
  p.addText @lfw,7*@height/12, font, "RIGHT: data"
  p.addText @lfw,10*@height/12-@lfw, font, "LEFT: blackout"
  p.addText @lfw,10*@height/12+@lfw, font, "RIGHT: blackout"
  p.addText @lfw,11*@height/12-@lfw/2, font, "timestamps"
  dlog "Finished legend path setup."
  return p
end

#build_text_pathObject

build painter path for the text data



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/mamba.rb', line 78

def build_text_path
  #y to timestamps
  ty = 11*@height/12
  #back to left hand data
  ypl = -5*@height/12-2*@lfw
  #and back to right hand data
  ypr = -3*@height/12-2*@lfw
  tfont = Qt::Font.new "Arial", @tfw
  pfont = Qt::Font.new "Arial", @pfw
  every = 25 #display text every ... frames
  current = 0
  p = Qt::PainterPath.new
  p.moveTo 0,0
  @graph.points.each do |ts,hands|
    if current >= every
      p.addText hands[:left][:x],@lfw, tfont, "#{ts}"
      #display the predicates
      @predicates.each_index do |i|
        p.addText hands[:left][:x], ypl+i*@lfw, pfont, "#{hands[:left][@predicates[i]]}"
        p.addText hands[:right][:x], ypr+i*@lfw, pfont, "#{hands[:right][@predicates[i]]}"
      end
      current = 0
    else
      current += 1
    end
  end
  dlog "Finished subtitles path setup."
  return { :y => ty, :path => p }
end

#mouseMoveEvent(event) ⇒ Object

a mouse move event



259
260
261
# File 'lib/mamba.rb', line 259

def mouseMoveEvent event
  @mousex,@mousey = event.x,event.y
end

#mousePressEvent(event) ⇒ Object

mouse press event



251
252
253
254
255
256
# File 'lib/mamba.rb', line 251

def mousePressEvent event
  if event.buttons == Qt::RightButton
  elsif event.buttons == Qt::LeftButton
    #update
  end
end

#paint_graphsObject

outsourced graph painting



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/mamba.rb', line 202

def paint_graphs
  p = Qt::Painter.new(self)
  p.setRenderHint(Qt::Painter::HighQualityAntialiasing)
  p.setBrush Qt::NoBrush
  @graphs.each do |name,path|
    p.resetMatrix
    p.translate((@width/2)-@xdelta,path[:y])
    pen = Qt::Pen.new(Qt::SolidLine)
    pen.setColor path[:color]
    if path.has_key? :width
      pen.setWidth path[:width]
    else
      pen.setWidth 1.5
    end
    p.setPen(pen)
    p.drawPath path[:path]
  end
  p.end()
end

#paint_legendObject

outsourced legend painting



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/mamba.rb', line 237

def paint_legend
  p = Qt::Painter.new(self)
  p.setRenderHint(Qt::Painter::HighQualityAntialiasing)
  p.resetMatrix
  p.translate(0,0)
  p.setBrush @brush
  pen = Qt::Pen.new(Qt::SolidLine)
  pen.setWidth 1
  p.setPen(pen)
  p.drawPath @legend
  p.end()
end

#paint_textObject

outsourced text painting



223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/mamba.rb', line 223

def paint_text
  p = Qt::Painter.new(self)
  p.setRenderHint(Qt::Painter::HighQualityAntialiasing)
  p.setBrush Qt::NoBrush
  p.resetMatrix
  p.translate((@width/2)-@xdelta,@text[:y])
  pen = Qt::Pen.new(Qt::SolidLine)
  pen.setWidth 2
  p.setPen(pen)
  p.drawPath @text[:path]
  p.end()
end

#paintEvent(event) ⇒ Object

gets called when a repaint is necessary



195
196
197
198
199
# File 'lib/mamba.rb', line 195

def paintEvent(event)
  paint_graphs
  paint_text
  paint_legend
end

#reactive_scrollObject

ruby thread test



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/mamba.rb', line 264

def reactive_scroll
  fps = 60.0 #frames per second we attempt to compute
  tts = 0.0 #time to sleep
  last_time = Time.now
  Thread.new do
    loop do 
      tts = 1.0/fps - (Time.now-last_time) 
      sleep tts if tts > 0
      unless @mousex.nil?
        scroll_x 
        smooth_delta
        if @xspeed.abs > 1 
          #are we speeding?
          if @xspeed < -1.0*@speedlimit
            @xspeed = -1.0*@speedlimit
            @xgoal = @xdelta
          end
          if @xspeed > @speedlimit
            @xspeed = @speedlimit 
            @xgoal = @xdelta
          end
          #new delta
          @xdelta = (@xdelta + @xspeed).to_i
          update
        end
      end
      last_time = Time.now
    end
  end
end

#scroll_xObject

scroll on the x_axis if necessary



296
297
298
299
300
301
302
303
304
305
# File 'lib/mamba.rb', line 296

def scroll_x
  damper = 10
  #need some kind of zone that triggers scrolling: 1/4 width left and right
  if @mousex < @width/4
    @xgoal += (@mousex - @width/4)/damper  
  end
  if @mousex > 3*@width/4
    @xgoal += (@mousex - 3*@width/4)/damper
  end
end

#setupObject

setup all the stuff we need to display



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mamba.rb', line 43

def setup
  #legend painter path
  @legend = build_legend_path
  #text painter path
  @text = build_text_path
  #graph painter paths
  @graphs = setup_graph_paths
  #now some gui specific stuff
  setPalette(Qt::Palette.new(Qt::Color.new(250, 250, 250)))
  setAutoFillBackground(true)
  #cursor settings
  @cur1 = self.cursor
  @cur2 = Qt::Cursor.new(Qt::PointingHandCursor)
  self.mouseTracking = true
  #used for scrolling objects to the left and right
  @xdelta,@xgoal,@xspeed = 0.0,0.0,0.0
end

#setup_graph_pathsObject

setup the graph paths we want to paint



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/mamba.rb', line 109

def setup_graph_paths
  dlog "Starting graph path setup."
  graph_paths = {}
  #build following graphs for both hands
  [:left,:right].each do |hand| 
    #build painter paths for blackout graph
    blackout = build_blackout_path(hand)
    graph_paths[blackout[:name]] = blackout
    dlog "Finished blackout path setup. Y: #{blackout[:y]}"
    #build painter paths for euler angles
    [:alpha,:beta,:gamma].each do |angle|
      euler = build_euler_path(hand,angle)
      graph_paths[euler[:name]] = euler
      dlog "Finished #{euler[:name]} path setup. Y: #{euler[:y]}"
    end
    #build painter paths for deltas
    @graph.deltas.each do |d|
      delta = build_delta_path(hand,d)
      graph_paths[delta[:name]] = delta
      dlog "Finished #{delta[:name]} path setup. Y: #{delta[:y]}"
    end        
  end    
  dlog "Finished graph path setup."
  return graph_paths
end

#smooth_deltaObject

method that smoothes the scroll deltas over time



308
309
310
# File 'lib/mamba.rb', line 308

def smooth_delta
  @xspeed = (@xgoal-@xdelta)*0.05
end