Module: Roby::GUI::RelationsCanvasTask

Includes:
RelationsCanvasPlanObject
Included in:
RelationsCanvasTaskProxy, Task
Defined in:
lib/roby/gui/relations_view/relations_canvas.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RelationsCanvasPlanObject

#display_events, #display_parent

Instance Attribute Details

#displayed_stateObject (readonly)

Returns the value of attribute displayed_state.



207
208
209
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 207

def displayed_state
  @displayed_state
end

#last_eventObject

Returns the value of attribute last_event.



188
189
190
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 188

def last_event
  @last_event
end

Class Method Details

.to_svg(task, options = {}) ⇒ String?

Generates a SVG representation of a given task model, using the task as proxy for the model

Parameters:

  • task (Roby::Task)

    the Roby task

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :path (String)

    a file path to which the SVG should be saved

  • :scale_x (Float) — default: PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_X
  • :scale_y (Float) — default: PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_Y

Returns:

  • (String, nil)

    if the file path is not set, the SVG content. Otherwise, nil.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
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
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 243

def self.to_svg(task, options = {})
    options = Kernel.validate_options options,
                                      path: nil,
                                      scale_x: PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_X,
                                      scale_y: PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_Y

    task.extend RelationsCanvasTask
    plan = task.plan

    display = RelationsCanvas.new([plan])
    display.display_plan_bounding_boxes = false
    display.layout_options.merge!(options.slice(:scale_x, :scale_y))
    task.each_event do |generator|
        if generator.controlable?
            plan.called_generators << generator
        end
        plan.emitted_events << [Time.now, generator.new([], 0)]
    end
    task.model.all_forwardings.each do |source_name, targets|
        source = task.event(source_name)
        targets.each do |target_name|
            plan.propagated_events << [Time.at(0), true, [source.new([], 0)], task.event(target_name)]
        end
    end
    task.model.all_signals.each do |source_name, targets|
        source = task.event(source_name)
        targets.each do |target_name|
            plan.propagated_events << [Time.at(0), false, [source.new([], 0)], task.event(target_name)]
        end
    end
    display.update
    scene = display.scene

    svg = Qt::SvgGenerator.new
    if path = options[:path]
        svg.file_name = path
    else
        buffer = svg.output_device = Qt::Buffer.new
    end
    svg.size = Qt::Size.new(Integer(scene.width), Integer(scene.height))
    painter = Qt::Painter.new
    painter.begin(svg)
    scene.render(painter)
    painter.end
    unless path
        buffer.data
    end
end

Instance Method Details

#display(display, graphics_item) ⇒ Object



227
228
229
230
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 227

def display(display, graphics_item)
    update_graphics(display, graphics_item)
    super
end

#display_create(display) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 162

def display_create(display)
    scene = display.scene
    rect = scene.add_rect Qt::RectF.new(0, 0, 0, 0)
    text = scene.add_text display_name(display)
    rect.brush = Qt::Brush.new(TASK_BRUSH_COLORS[:pending])
    rect.pen   = Qt::Pen.new(TASK_PEN_COLORS[:pending])
    @displayed_state = :pending
    text.parent_item = rect
    rect.singleton_class.class_eval { attr_accessor :text }
    rect.text = text
    rect.z_value = TASK_LAYER

    @width, @height = nil

    rect.set_data(0, Qt::Variant.new(self.object_id.to_s))
    rect
end

#display_name(display) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 190

def display_name(display)
    ancestor_with_name = model.ancestors.find(&:name)
    if ancestor_with_name
        name = display.filter_prefixes(ancestor_with_name.name)
    else
        name = "<anonymous>"
    end
    if display.show_ownership
        owners = self.owners.dup
        owners.delete_if { |o| o.remote_name == "log_replay" }
        unless owners.empty?
            name << "\n[#{owners.map(&:name).join(', ')}]"
        end
    end
    name
end

#display_time_end(rect, pos) ⇒ Object



184
185
186
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 184

def display_time_end(rect, pos)
    rect.right = pos
end

#display_time_start(rect, pos) ⇒ Object



180
181
182
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 180

def display_time_start(rect, pos)
    rect.left = pos
end

#layout_events(display) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 120

def layout_events(display)
    graphics_item = display[self]

    width, height = 0, 0
    events = self.each_event.map do |e|
        next unless display.displayed?(e)
        next unless circle = display[e]

        br = (circle.bounding_rect | circle.children_bounding_rect)
        [e, circle, br]
    end
    events.compact!
    events = events.sort_by { |ev, _| RelationsCanvasEventGenerator.priorities[ev] }

    events.each do |_, circle, br|
        w, h = br.width, br.height
        height = h if h > height
        width += w
    end
    width  += TASK_EVENT_SPACING * (events.size + 1)
    height += TASK_EVENT_SPACING

    x = -width / 2 + TASK_EVENT_SPACING
    events.each do |e, circle, br|
        w = br.width
        circle.set_pos(x + w / 2, -br.height / 2 + EVENT_CIRCLE_RADIUS + TASK_EVENT_SPACING)
        x += w + TASK_EVENT_SPACING
    end

    width = DEFAULT_TASK_WIDTH unless width > DEFAULT_TASK_WIDTH
    height = DEFAULT_TASK_HEIGHT unless height > DEFAULT_TASK_HEIGHT

    if @width != width || @height != height
        @width, @height = width, height
        coords = Qt::RectF.new(-(width / 2), -(height / 2), width, height)
        graphics_item.rect = coords
    end

    text = graphics_item.text
    text.set_pos(- text.bounding_rect.width / 2, height / 2 + TASK_EVENT_SPACING)
end

#update_graphics(display, graphics_item) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 209

def update_graphics(display, graphics_item)
    new_state = GUI.task_state_at(self, display.current_time)
    finalized = finalization_time && finalization_time <= display.current_time
    if displayed_state != [new_state, finalized]
        if finalized
            pen = Qt::Pen.new(TASK_PEN_COLORS[:finalized])
            pen.width = 4
            graphics_item.pen   = pen
        else
            graphics_item.pen   = Qt::Pen.new(TASK_PEN_COLORS[new_state])
        end
        graphics_item.brush = Qt::Brush.new(TASK_BRUSH_COLORS[new_state])
        @displayed_state = [new_state, finalized]
    end

    graphics_item.text.plain_text = display_name(display).to_s
end