module Roby::GUI::RelationsCanvasTask

Attributes

displayed_state[R]
last_event[RW]

Public Class Methods

to_svg(task, options = Hash.new) click to toggle source

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

@param [Roby::Task] task the Roby task @option options [String] :path a file path to which the SVG should

be saved

@option options [Float] :scale_x (PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_X) @option options [Float] :scale_y (PlanDotLayout::DOT_TO_QT_SCALE_FACTOR_Y)

@return [String,nil] if the file path is not set, the SVG content.

Otherwise, nil.
# File lib/roby/gui/relations_view/relations_canvas.rb, line 214
def self.to_svg(task, options = Hash.new)
    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 |ev|
        if ev.controlable?
            plan.called_generators << ev
        end
        plan.emitted_events << ev.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 << [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 << [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
    if !path
        buffer.data
    end
end

Public Instance Methods

display(display, graphics_item) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 198
def display(display, graphics_item)
    update_graphics(display, graphics_item)
    super
end
display_create(display) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 139
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) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 162
def display_name(display)
    ancestor_with_name = model.ancestors.find { |m| m.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" }
        if !owners.empty?
            name << "\n[#{owners.map(&:name).join(", ")}]"
        end
    end
    name
end
display_time_end(rect, pos) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 158
def display_time_end(rect, pos);   rect.right = pos end
display_time_start(rect, pos) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 157
def display_time_start(rect, pos); rect.left = pos end
layout_events(display) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 98
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) click to toggle source
# File lib/roby/gui/relations_view/relations_canvas.rb, line 180
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