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.



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

def displayed_state
  @displayed_state
end

#last_eventObject

Returns the value of attribute last_event.



160
161
162
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 160

def last_event
  @last_event
end

Class Method Details

.to_svg(task, options = Hash.new) ⇒ 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: Hash.new)

    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.



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# 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

Instance Method Details

#display(display, graphics_item) ⇒ Object



198
199
200
201
# 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) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# 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) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# 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) ⇒ Object



158
# 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) ⇒ Object



157
# File 'lib/roby/gui/relations_view/relations_canvas.rb', line 157

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

#layout_events(display) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
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
134
135
136
137
# 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) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# 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