Class: Roby::GUI::ChronicleWidget
- Defined in:
- lib/roby/gui/chronicle_widget.rb
Overview
Widget to display tasks on a chronicle (i.e. timelines)
Use ChronicleView when using a PlanRebuilderWidget
The following interactions are available:
* CTRL + wheel: change time scale
* ALT + wheel: horizontal scroll
* wheel: vertical scroll
* double-click: task info view
Defined Under Namespace
Classes: TaskLayout
Constant Summary collapse
- SCALES =
[1, 2, 5, 10, 20, 30, 60, 90, 120, 300, 600, 1200, 1800, 3600]
- TIMELINE_GRAY_PEN =
Qt::Pen.new(Qt::Color.new('gray'))
- TIMELINE_BLACK_PEN =
Qt::Pen.new(Qt::Color.new('black'))
Instance Attribute Summary collapse
-
#all_job_info ⇒ Object
Job information about all known tasks.
-
#all_tasks ⇒ Object
All known tasks.
-
#base_time ⇒ Object
The startup time.
-
#current_tasks ⇒ Object
readonly
The set of tasks that should currently be managed by the view.
-
#current_time ⇒ Object
The system’s current time.
-
#display_point ⇒ Object
The point (in pixels) where the current display time should be located on the display.
-
#display_time ⇒ Object
The time that is currently at the middle of the view.
-
#displayed_time_range ⇒ (Time,Time)?
readonly
The range, in absolute time, currently visible in the view.
-
#filter ⇒ Object
Inclusion filter on task names.
-
#filter_out ⇒ Object
Exclusion filter on task names.
-
#layout_cache ⇒ Hash<Task,TaskLayout>
readonly
Per-task visual layout information.
-
#live_update_margin ⇒ Object
readonly
How many pixels should there be between the ‘now’ line and the right side, in pixels.
-
#messages_per_task ⇒ Object
readonly
Per-task messages to be displayed.
-
#pixel_to_time ⇒ Object
readonly
Scale factor to convert seconds to pixels.
-
#position_to_task ⇒ Object
readonly
An ordered set of [y, task], where
yis the position in Y of the bottom of a task line andtaskthe corresponding task object. -
#scheduler_state ⇒ Schedulers::State
Scheduler information.
-
#show_mode ⇒ Object
High-level filter on the list of shown tasks.
-
#sort_mode ⇒ Object
The current sorting mode.
-
#start_line ⇒ Object
The index of the task that is currently at the top of the view.
-
#task_height ⇒ Object
The base height of a task line.
-
#task_layout ⇒ Object
readonly
The task layout as computed in the last call to #paintEvent.
-
#task_separation ⇒ Object
The separation, in pixels, between tasks.
-
#time_scale ⇒ Object
Internal representation of the desired time scale.
-
#time_to_pixel ⇒ Object
readonly
Scale factor to convert seconds to pixels.
Instance Method Summary collapse
-
#add_tasks_info(tasks, job_info) ⇒ Object
Add information to the chronicle for the next display update.
- #clear ⇒ Object
- #clear_tasks_info ⇒ Object
- #contents_height ⇒ Object
- #current_tasks_dirty? ⇒ Boolean
-
#initialize(parent = nil) ⇒ ChronicleWidget
constructor
A new instance of ChronicleWidget.
- #invalidate_current_tasks ⇒ Object
-
#invalidate_layout_cache ⇒ Object
private
Clears #layout_cache because parameters changed that require to recompute the task layouts.
- #lay_out_task(fm, task) ⇒ Object
- #live=(flag) ⇒ Object
- #massage_slot_time_argument(time, default) ⇒ Object
- #mouseDoubleClickEvent(event) ⇒ Object
- #paint_tasks(painter, fm, layout, top_y) ⇒ Object
- #paint_timeline(painter, fm) ⇒ Object
- #paintEvent(event) ⇒ Object
- #remove_tasks(tasks) ⇒ Object
- #resizeEvent(event) ⇒ Object
-
#restrict_to_jobs=(set) ⇒ Object
Sets whether only the toplevel job tasks should be shown.
-
#restrict_to_jobs? ⇒ Boolean
True if only the action’s toplevel tasks are shown.
-
#reverse_sort=(flag) ⇒ Object
Whether the order defined by #sort_mode should be inverted.
-
#reverse_sort? ⇒ Boolean
Whether the order defined by #sort_mode should be inverted.
- #setCurrentTime(time = nil) ⇒ Object
- #setDisplayTime(time = nil) ⇒ Object
- #task_timeline_title(task) ⇒ Object
- #timeline_height ⇒ Object
-
#update_base_time(time) ⇒ Object
private
Update the time at the start of the chronicle.
- #update_current_tasks(force: false) ⇒ Object
-
#update_current_time(time) ⇒ Object
private
Update the time at the end of the chronicle.
- #update_display_point ⇒ Object
-
#update_display_time(time) ⇒ Object
private
Update the currently displayed time.
- #update_displayed_time_range ⇒ Object
- #update_scroll_ranges ⇒ Object
-
#update_time_range(start_time, current_time) ⇒ Object
private
Updates the start and current time.
-
#wheelEvent(event) ⇒ Object
Event handler for wheel event.
Constructor Details
#initialize(parent = nil) ⇒ ChronicleWidget
Returns a new instance of ChronicleWidget.
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 262 263 264 265 266 267 268 |
# File 'lib/roby/gui/chronicle_widget.rb', line 214 def initialize(parent = nil) super(parent) @layout_cache = Hash.new = Hash.new { |h, k| h[k] = Array.new } @current_tasks = Array.new @current_tasks_dirty = true self.time_scale = 10 @task_height = 10 @task_separation = 10 @live_update_margin = 10 @start_line = 0 @all_tasks = Set.new @all_job_info = Hash.new @scheduler_state = Schedulers::State.new @task_layout = Array.new @sort_mode = :start_time @reverse_sort = false @show_mode = :all @show_future_events = true @live = true @track_current_time = true = false @display_point = .size.width - live_update_margin = Qt::Widget.new pal = Qt::Palette.new(.palette) pal.setColor(Qt::Palette::Background, Qt::Color.new('white')) .setAutoFillBackground(true); .setPalette(pal) self. = .connect(SIGNAL('sliderMoved(int)')) do value = .value self.track_current_time = live? && (value == .maximum) time = base_time + Float(value) * pixel_to_time update_display_time(time) emit timeChanged(time - base_time) end .connect(SIGNAL('sliderPressed()')) do self. = true end .connect(SIGNAL('sliderReleased()')) do self.track_current_time = live? && (.value == .maximum) self. = false update_scroll_ranges end .connect(SIGNAL('valueChanged(int)')) do value = .value if value < current_tasks.size self.start_line = value update end end end |
Instance Attribute Details
#all_job_info ⇒ Object
Job information about all known tasks
92 93 94 |
# File 'lib/roby/gui/chronicle_widget.rb', line 92 def all_job_info @all_job_info end |
#all_tasks ⇒ Object
All known tasks
88 89 90 |
# File 'lib/roby/gui/chronicle_widget.rb', line 88 def all_tasks @all_tasks end |
#base_time ⇒ Object
The startup time
77 78 79 |
# File 'lib/roby/gui/chronicle_widget.rb', line 77 def base_time @base_time end |
#current_tasks ⇒ Object (readonly)
The set of tasks that should currently be managed by the view.
It is updated in #update(), i.e. when the view gets something to display
103 104 105 |
# File 'lib/roby/gui/chronicle_widget.rb', line 103 def current_tasks @current_tasks end |
#current_time ⇒ Object
The system’s current time
75 76 77 |
# File 'lib/roby/gui/chronicle_widget.rb', line 75 def current_time @current_time end |
#display_point ⇒ Object
The point (in pixels) where the current display time should be located on the display
71 72 73 |
# File 'lib/roby/gui/chronicle_widget.rb', line 71 def display_point @display_point end |
#display_time ⇒ Object
The time that is currently at the middle of the view
73 74 75 |
# File 'lib/roby/gui/chronicle_widget.rb', line 73 def display_time @display_time end |
#displayed_time_range ⇒ (Time,Time)? (readonly)
The range, in absolute time, currently visible in the view
459 460 461 |
# File 'lib/roby/gui/chronicle_widget.rb', line 459 def displayed_time_range @displayed_time_range end |
#filter ⇒ Object
Inclusion filter on task names
If it contains a regular expression, only the task names that match the expression will be displayed
187 188 189 |
# File 'lib/roby/gui/chronicle_widget.rb', line 187 def filter @filter end |
#filter_out ⇒ Object
Exclusion filter on task names
If it contains a regular expression, the task names that match the expression will not be displayed
200 201 202 |
# File 'lib/roby/gui/chronicle_widget.rb', line 200 def filter_out @filter_out end |
#layout_cache ⇒ Hash<Task,TaskLayout> (readonly)
Per-task visual layout information
151 152 153 |
# File 'lib/roby/gui/chronicle_widget.rb', line 151 def layout_cache @layout_cache end |
#live_update_margin ⇒ Object (readonly)
How many pixels should there be between the ‘now’ line and the right side, in pixels
68 69 70 |
# File 'lib/roby/gui/chronicle_widget.rb', line 68 def live_update_margin @live_update_margin end |
#messages_per_task ⇒ Object (readonly)
Per-task messages to be displayed
154 155 156 |
# File 'lib/roby/gui/chronicle_widget.rb', line 154 def end |
#pixel_to_time ⇒ Object (readonly)
Scale factor to convert seconds to pixels
pixel = time_to_pixel * time
64 65 66 |
# File 'lib/roby/gui/chronicle_widget.rb', line 64 def pixel_to_time @pixel_to_time end |
#position_to_task ⇒ Object (readonly)
An ordered set of [y, task], where y is the position in Y of the bottom of a task line and task the corresponding task object
It is updated on display
108 109 110 |
# File 'lib/roby/gui/chronicle_widget.rb', line 108 def position_to_task @position_to_task end |
#scheduler_state ⇒ Schedulers::State
Scheduler information
96 97 98 |
# File 'lib/roby/gui/chronicle_widget.rb', line 96 def scheduler_state @scheduler_state end |
#show_mode ⇒ Object
High-level filter on the list of shown tasks. Can either be :all, :running, :current. Defaults to :all
In :all mode, all tasks that are included in a plan in a certain point in time are displayed.
In :running mode, only the tasks that are running within the display time window are shown.
In :current mode, only the tasks that have emitted events within the display time window are shown
In :in_range mode, only the tasks that would display something within the display time window are shown
146 147 148 |
# File 'lib/roby/gui/chronicle_widget.rb', line 146 def show_mode @show_mode end |
#sort_mode ⇒ Object
The current sorting mode. Can be :start_time or :last_event. Defaults to :start_time
In :start mode, the tasks are sorted by the time at which they started. In :last_event, by the time of the last event emitted before the current displayed time: it shows the last active tasks first)
116 117 118 |
# File 'lib/roby/gui/chronicle_widget.rb', line 116 def sort_mode @sort_mode end |
#start_line ⇒ Object
The index of the task that is currently at the top of the view. It is an index in #current_tasks
84 85 86 |
# File 'lib/roby/gui/chronicle_widget.rb', line 84 def start_line @start_line end |
#task_height ⇒ Object
The base height of a task line
79 80 81 |
# File 'lib/roby/gui/chronicle_widget.rb', line 79 def task_height @task_height end |
#task_layout ⇒ Object (readonly)
The task layout as computed in the last call to #paintEvent
98 99 100 |
# File 'lib/roby/gui/chronicle_widget.rb', line 98 def task_layout @task_layout end |
#task_separation ⇒ Object
The separation, in pixels, between tasks
81 82 83 |
# File 'lib/roby/gui/chronicle_widget.rb', line 81 def task_separation @task_separation end |
#time_scale ⇒ Object
Internal representation of the desired time scale. Don’t use it directly, but use #time_to_pixel or #pixel_to_time
34 35 36 |
# File 'lib/roby/gui/chronicle_widget.rb', line 34 def time_scale @time_scale end |
#time_to_pixel ⇒ Object (readonly)
Scale factor to convert seconds to pixels
pixels = time_to_pixel * time
59 60 61 |
# File 'lib/roby/gui/chronicle_widget.rb', line 59 def time_to_pixel @time_to_pixel end |
Instance Method Details
#add_tasks_info(tasks, job_info) ⇒ Object
Add information to the chronicle for the next display update
339 340 341 342 343 344 345 346 347 348 |
# File 'lib/roby/gui/chronicle_widget.rb', line 339 def add_tasks_info(tasks, job_info) tasks.each do |t| if base_time && t.addition_time < base_time update_base_time(t.addition_time) end end all_tasks.merge(tasks) all_job_info.merge!(job_info) end |
#clear ⇒ Object
888 889 890 891 |
# File 'lib/roby/gui/chronicle_widget.rb', line 888 def clear all_tasks.clear all_job_info.clear end |
#clear_tasks_info ⇒ Object
305 306 307 308 309 |
# File 'lib/roby/gui/chronicle_widget.rb', line 305 def clear_tasks_info all_tasks.clear all_job_info.clear self.scheduler_state = Schedulers::State.new end |
#contents_height ⇒ Object
357 358 359 360 361 362 363 364 365 366 |
# File 'lib/roby/gui/chronicle_widget.rb', line 357 def contents_height update_current_tasks display_start, display_end = displayed_time_range fm = Qt::FontMetrics.new(font) height = current_tasks.inject(0) do |h, t| h + lay_out_task(fm, t).height(display_start, display_end) end height + current_tasks.size * task_separation + timeline_height end |
#current_tasks_dirty? ⇒ Boolean
465 466 467 |
# File 'lib/roby/gui/chronicle_widget.rb', line 465 def current_tasks_dirty? @current_tasks_dirty end |
#invalidate_current_tasks ⇒ Object
461 462 463 |
# File 'lib/roby/gui/chronicle_widget.rb', line 461 def invalidate_current_tasks @current_tasks_dirty = true end |
#invalidate_layout_cache ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Clears #layout_cache because parameters changed that require to recompute the task layouts
160 161 162 |
# File 'lib/roby/gui/chronicle_widget.rb', line 160 def invalidate_layout_cache layout_cache.clear end |
#lay_out_task(fm, task) ⇒ Object
746 747 748 749 750 751 |
# File 'lib/roby/gui/chronicle_widget.rb', line 746 def lay_out_task(fm, task) layout = layout_cache[task] ||= TaskLayout.new(task, base_time, time_to_pixel, fm) layout. = .fetch(task, Array.new) layout.update layout end |
#live=(flag) ⇒ Object
24 25 26 27 |
# File 'lib/roby/gui/chronicle_widget.rb', line 24 def live=(flag) @live = flag self.track_current_time = live? && (value == .maximum) end |
#massage_slot_time_argument(time, default) ⇒ Object
543 544 545 546 547 548 549 550 551 |
# File 'lib/roby/gui/chronicle_widget.rb', line 543 def massage_slot_time_argument(time, default) # Convert from QDateTime to allow update() to be a slot if time.kind_of?(Qt::DateTime) return Time.at(Float(time.toMSecsSinceEpoch) / 1000) elsif !time return default else time end end |
#mouseDoubleClickEvent(event) ⇒ Object
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 |
# File 'lib/roby/gui/chronicle_widget.rb', line 893 def mouseDoubleClickEvent(event) click_y = event.pos.y layout = task_layout.find { |layout| layout.top_y < click_y && layout.top_y + layout.height > click_y } if layout if !@info_view @info_view = ObjectInfoView.new Qt::Object.connect(@info_view, SIGNAL('selectedTime(QDateTime)'), self, SIGNAL('selectedTime(QDateTime)')) end if @info_view.display(layout.task) @info_view.activate end end event.accept end |
#paint_tasks(painter, fm, layout, top_y) ⇒ Object
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 |
# File 'lib/roby/gui/chronicle_widget.rb', line 753 def paint_tasks(painter, fm, layout, top_y) current_point = Integer((current_time - base_time) * time_to_pixel) display_offset = Integer(display_point - (display_time - base_time) * time_to_pixel) display_start_time, display_end_time = displayed_time_range view_height = .size.height fm = Qt::FontMetrics.new(font) text_height = fm.height text_ascent = fm.ascent text_descent = fm.descent update_current_tasks current_tasks[start_line..-1].each do |task| break if top_y > view_height task_layout = lay_out_task(fm, task) add_point, start_point, end_point, finalization_point = task_layout.add_point, task_layout.start_point, task_layout.end_point, task_layout.finalization_point state = task_layout.state task = task_layout.task event_height = task_layout.event_height task_line_height = event_height if events = task_layout.events_in_range(display_start_time, display_end_time) task_line_height += events.max_by { |_, _, y, _| y }[2] end if task_height > task_line_height task_line_height = task_height end # Paint the pending stage, i.e. before the task started top_task_line = top_y painter.brush = TASK_BRUSHES[:pending] painter.pen = TASK_PENS[:pending] painter.drawRect( add_point + display_offset, top_task_line, (start_point || finalization_point || current_point) - add_point, task_line_height) if start_point painter.brush = TASK_BRUSHES[:running] painter.pen = TASK_PENS[:running] painter.drawRect( start_point + display_offset, top_task_line, (end_point || current_point) - start_point, task_line_height) if state && state != :running # Final state is shown by "eating" a few pixels at the task painter.brush = TASK_BRUSHES[state] painter.pen = TASK_PENS[state] painter.drawRect( end_point - 2 + display_offset, top_task_line, 4, task_height) end end # Display the emitted events event_baseline = top_task_line + event_height / 2 if events events.each do |_, x, y, text| x += display_offset y += event_baseline painter.brush, painter.pen = EVENT_STYLES[EVENT_CONTROLABLE | EVENT_EMITTED] painter.drawEllipse(Qt::Point.new(x, y), EVENT_CIRCLE_RADIUS, EVENT_CIRCLE_RADIUS) painter.pen = EVENT_NAME_PEN painter.drawText(Qt::Point.new(x + 2 * EVENT_CIRCLE_RADIUS, y), text) end end # Add the title painter.pen = TASK_NAME_PEN title_baseline = top_task_line + task_line_height + text_ascent task_layout.title ||= task_timeline_title(task) painter.drawText(Qt::Point.new(0, title_baseline), task_layout.title) # And finally display associated messages = title_baseline + text_height painter.pen = TASK_MESSAGE_PEN task_layout..each_with_index do |msg| += text_height painter.drawText(Qt::Point.new(TASK_MESSAGE_MARGIN, ), msg) end top_y = + text_descent end end |
#paint_timeline(painter, fm) ⇒ Object
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
# File 'lib/roby/gui/chronicle_widget.rb', line 575 def paint_timeline(painter, fm) text_height = fm.height window_size = .size # Display the current cycle time central_label = Roby.format_time(display_time) central_label_width = fm.width(central_label) central_time_max = display_point + central_label_width / 2 if central_time_max + 3 > window_size.width central_time_max = window_size.width - 3 end central_time_min = central_time_max - central_label_width if central_time_min < 3 central_time_min = 3 central_time_max = central_time_min + central_label_width end painter.pen = TIMELINE_GRAY_PEN painter.drawText(central_time_min, text_height, central_label) painter.drawRect(central_time_min - 2, 0, central_label_width + 4, text_height + 2) # First, decide on the scale. We compute a "normal" text width # for the time labels, and check what would be a round time-step min_step_size = pixel_to_time * 1.5 * central_label_width step_size = SCALES.find do |scale| scale > min_step_size end step_size ||= SCALES.last # Now display the timeline itself. If a normal ruler collides # with the current time, just ignore it start_time, end_time = displayed_time_range painter.pen = TIMELINE_BLACK_PEN ruler_base_time = (start_time.to_f / step_size).floor * step_size ruler_base_x = (ruler_base_time - start_time.to_f) * time_to_pixel step_count = ((end_time.to_f - ruler_base_time) / step_size).ceil step_count.times do |i| time = step_size * i + ruler_base_time pos = step_size * i * time_to_pixel + ruler_base_x time_as_text = Roby.format_time(Time.at(time)) time_as_text_width = fm.width(time_as_text) min_x = pos - time_as_text_width / 2 max_x = pos + time_as_text_width / 2 if central_time_min > max_x || central_time_max < min_x painter.drawText(min_x, text_height, time_as_text) end painter.drawLine(pos, text_height + fm.descent, pos, text_height + fm.descent + TIMELINE_RULER_LINE_LENGTH) end end |
#paintEvent(event) ⇒ Object
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
# File 'lib/roby/gui/chronicle_widget.rb', line 848 def paintEvent(event) return if !display_time painter = Qt::Painter.new() font = painter.font font.point_size = 8 painter.font = font fm = Qt::FontMetrics.new(font) update_current_tasks paint_timeline(painter, fm) paint_tasks(painter, fm, task_layout, timeline_height) # Draw the "zero" line painter.pen = TIMELINE_GRAY_PEN painter.drawLine(display_point, fm.height + 2, display_point, size.height) ensure if painter painter.end end end |
#remove_tasks(tasks) ⇒ Object
350 351 352 353 354 355 |
# File 'lib/roby/gui/chronicle_widget.rb', line 350 def remove_tasks(tasks) tasks.each do |t| all_tasks.delete(t) all_job_info.delete(t) end end |
#resizeEvent(event) ⇒ Object
434 435 436 437 438 439 440 441 442 443 |
# File 'lib/roby/gui/chronicle_widget.rb', line 434 def resizeEvent(event) if track_current_time? @display_point = event.size.width - live_update_margin elsif display_time && current_time update_display_point end update_displayed_time_range invalidate_current_tasks event.accept end |
#restrict_to_jobs=(set) ⇒ Object
Sets whether only the toplevel job tasks should be shown
177 178 179 180 181 |
# File 'lib/roby/gui/chronicle_widget.rb', line 177 def restrict_to_jobs=(set) @restrict_to_jobs = set setDisplayTime update end |
#restrict_to_jobs? ⇒ Boolean
Returns true if only the action’s toplevel tasks are shown.
174 |
# File 'lib/roby/gui/chronicle_widget.rb', line 174 attr_predicate :restrict_to_jobs? |
#reverse_sort=(flag) ⇒ Object
Whether the order defined by #sort_mode should be inverted
129 130 131 |
# File 'lib/roby/gui/chronicle_widget.rb', line 129 def reverse_sort=(flag) @reverse_sort = flag end |
#reverse_sort? ⇒ Boolean
Whether the order defined by #sort_mode should be inverted
125 126 127 |
# File 'lib/roby/gui/chronicle_widget.rb', line 125 def reverse_sort? !!@reverse_sort end |
#setCurrentTime(time = nil) ⇒ Object
564 565 566 567 568 569 570 571 |
# File 'lib/roby/gui/chronicle_widget.rb', line 564 def setCurrentTime(time = nil) time = massage_slot_time_argument(time, current_time) return if !time update_base_time(time) if !base_time update_current_time(time) update end |
#setDisplayTime(time = nil) ⇒ Object
553 554 555 556 557 558 559 560 561 |
# File 'lib/roby/gui/chronicle_widget.rb', line 553 def setDisplayTime(time = nil) time = massage_slot_time_argument(time, display_time) return if !time update_base_time(time) if !base_time update_current_time(time) if !current_time update_display_time(time) update end |
#task_timeline_title(task) ⇒ Object
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
# File 'lib/roby/gui/chronicle_widget.rb', line 871 def task_timeline_title(task) text = task.to_s if job_task = all_job_info[task] job_text = ["[#{job_task.job_id}]"] if job_task.action_model job_text << job_task.action_model.name.to_s end if job_task.action_arguments job_text << "(" + job_task.action_arguments.map do |k,v| "#{k} => #{v}" end.join(", ") + ")" end text = "#{job_text.join(" ")} / #{text}" end text end |
#timeline_height ⇒ Object
843 844 845 846 |
# File 'lib/roby/gui/chronicle_widget.rb', line 843 def timeline_height fm = Qt::FontMetrics.new(font) fm.height + fm.descent + TIMELINE_RULER_LINE_LENGTH end |
#update_base_time(time) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Update the time at the start of the chronicle
382 383 384 385 386 |
# File 'lib/roby/gui/chronicle_widget.rb', line 382 def update_base_time(time) @base_time = time invalidate_current_tasks invalidate_layout_cache end |
#update_current_tasks(force: false) ⇒ Object
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
# File 'lib/roby/gui/chronicle_widget.rb', line 469 def update_current_tasks(force: false) return if !force && !current_tasks_dirty? current_tasks = all_tasks.dup if restrict_to_jobs? current_tasks = all_job_info.keys.to_set end if filter current_tasks = current_tasks.find_all { |t| t.to_s =~ filter } end if filter_out current_tasks.delete_if { |t| t.to_s =~ filter_out } end started_tasks, pending_tasks = current_tasks.partition { |t| t.start_time } if sort_mode == :last_event not_yet_started, started_tasks = started_tasks.partition { |t| t.start_time > display_time } current_tasks = started_tasks.sort_by do |t| last_event = nil t.history.each do |ev| if ev.time < display_time last_event = ev else break end end last_event.time end current_tasks = current_tasks.reverse current_tasks.concat(not_yet_started.sort_by { |t| t.start_time }) if show_mode == :all current_tasks. concat(pending_tasks.sort_by { |t| t.addition_time }) end else current_tasks = (started_tasks + pending_tasks).sort_by { |t| t.start_time || t.addition_time } end start_time, end_time = displayed_time_range if start_time && (show_mode == :running || show_mode == :current) current_tasks = current_tasks.find_all do |t| (t.start_time && t.start_time < end_time) && (!t.end_time || t.end_time > start_time) end if show_mode == :current current_tasks = current_tasks.find_all do |t| t.history.any? { |ev| ev.time > start_time && ev.time < end_time } end end end tasks_in_range, tasks_outside_range = current_tasks.partition do |t| (t.addition_time <= end_time) && (!t.finalization_time || t.finalization_time >= start_time) end if reverse_sort? tasks_in_range = tasks_in_range.reverse tasks_outside_range = tasks_outside_range.reverse end @current_tasks_dirty = false if show_mode == :in_range @current_tasks = tasks_in_range else @current_tasks = tasks_in_range + tasks_outside_range end .setRange(0, current_tasks.size) end |
#update_current_time(time) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Update the time at the end of the chronicle
390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/roby/gui/chronicle_widget.rb', line 390 def update_current_time(time) @current_time = time if !base_time update_base_time(time) end if !display_time || track_current_time? update_display_time(time) else update_scroll_ranges invalidate_current_tasks end end |
#update_display_point ⇒ Object
422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/roby/gui/chronicle_widget.rb', line 422 def update_display_point display_point = .size.width - live_update_margin - (current_time - display_time) * time_to_pixel display_point_min = .size.width / 2 if display_point < display_point_min display_point = display_point_min end @display_point = Integer(display_point) update_displayed_time_range invalidate_current_tasks end |
#update_display_time(time) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Update the currently displayed time
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
# File 'lib/roby/gui/chronicle_widget.rb', line 405 def update_display_time(time) @display_time = time if !base_time update_base_time(time) end _, end_time = displayed_time_range update_display_point if ! update_scroll_ranges .value = time_to_pixel * (display_time - base_time) end invalidate_current_tasks end |
#update_displayed_time_range ⇒ Object
445 446 447 448 449 450 451 452 453 |
# File 'lib/roby/gui/chronicle_widget.rb', line 445 def update_displayed_time_range if display_time display_point = self.display_point window_width = .size.width start_time = display_time - display_point * pixel_to_time end_time = start_time + window_width * pixel_to_time @displayed_time_range = [start_time, end_time] end end |
#update_scroll_ranges ⇒ Object
912 913 914 915 916 917 918 919 920 921 |
# File 'lib/roby/gui/chronicle_widget.rb', line 912 def update_scroll_ranges .setRange(0, current_tasks.size - 1) return if if base_time && current_time && display_time .value = time_to_pixel * (display_time - base_time) .setRange(0, time_to_pixel * (current_time - base_time)) .setPageStep(size.width / 4) end end |
#update_time_range(start_time, current_time) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Updates the start and current time
371 372 373 374 375 376 377 378 |
# File 'lib/roby/gui/chronicle_widget.rb', line 371 def update_time_range(start_time, current_time) if start_time update_base_time(start_time) end if current_time update_current_time(current_time) end end |
#wheelEvent(event) ⇒ Object
Event handler for wheel event
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/roby/gui/chronicle_widget.rb', line 275 def wheelEvent(event) if event.modifiers != Qt::ControlModifier # Don't let the user scroll with the mouse if vertical # scrolling is off if == Qt::ScrollBarAlwaysOff event.ignore return else return super end end # See documentation of wheelEvent degrees = event.delta / 8.0 num_steps = degrees / 15 old = self.time_scale new = old + num_steps if new == 0 if old > 0 self.time_scale = -1 else self.time_scale = 1 end else self.time_scale = new end event.accept end |