diff --git a/Userland/DevTools/Profiler/CMakeLists.txt b/Userland/DevTools/Profiler/CMakeLists.txt index c9f2dd8e53..d39fcd544d 100644 --- a/Userland/DevTools/Profiler/CMakeLists.txt +++ b/Userland/DevTools/Profiler/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES ProfileModel.cpp ProfileTimelineWidget.cpp SamplesModel.cpp + TimelineView.cpp ) serenity_app(Profiler ICON app-profiler) diff --git a/Userland/DevTools/Profiler/ProfileTimelineWidget.cpp b/Userland/DevTools/Profiler/ProfileTimelineWidget.cpp index 17dfb5ea45..4181d32e1d 100644 --- a/Userland/DevTools/Profiler/ProfileTimelineWidget.cpp +++ b/Userland/DevTools/Profiler/ProfileTimelineWidget.cpp @@ -6,14 +6,16 @@ #include "ProfileTimelineWidget.h" #include "Profile.h" +#include "TimelineView.h" #include #include #include namespace Profiler { -ProfileTimelineWidget::ProfileTimelineWidget(Profile& profile, Process const& process) - : m_profile(profile) +ProfileTimelineWidget::ProfileTimelineWidget(TimelineView& view, Profile& profile, Process const& process) + : m_view(view) + , m_profile(profile) , m_process(process) { set_fill_with_background_color(true); @@ -21,7 +23,6 @@ ProfileTimelineWidget::ProfileTimelineWidget(Profile& profile, Process const& pr set_fixed_height(40); set_fixed_width(m_profile.length_in_ms() / 10); set_frame_thickness(1); - m_hover_time = m_profile.first_timestamp(); } ProfileTimelineWidget::~ProfileTimelineWidget() @@ -64,9 +65,9 @@ void ProfileTimelineWidget::paint_event(GUI::PaintEvent& event) painter.draw_line({ x + i, frame_thickness() + column_height }, { x + i, height() - frame_thickness() * 2 }, color); } - u64 normalized_start_time = clamp_timestamp(min(m_select_start_time, m_select_end_time)); - u64 normalized_end_time = clamp_timestamp(max(m_select_start_time, m_select_end_time)); - u64 normalized_hover_time = clamp_timestamp(m_hover_time); + u64 normalized_start_time = clamp_timestamp(min(m_view.select_start_time(), m_view.select_end_time())); + u64 normalized_end_time = clamp_timestamp(max(m_view.select_start_time(), m_view.select_end_time())); + u64 normalized_hover_time = clamp_timestamp(m_view.hover_time()); int select_start_x = (int)((float)(normalized_start_time - start_of_trace) * column_width); int select_end_x = (int)((float)(normalized_end_time - start_of_trace) * column_width); @@ -108,20 +109,20 @@ void ProfileTimelineWidget::mousedown_event(GUI::MouseEvent& event) if (event.button() != GUI::MouseButton::Left) return; - m_selecting = true; - m_select_start_time = timestamp_at_x(event.x()); - m_select_end_time = m_select_start_time; - m_profile.set_timestamp_filter_range(m_select_start_time, m_select_end_time); + m_view.set_selecting({}, true); + m_view.set_select_start_time({}, timestamp_at_x(event.x())); + m_view.set_select_end_time({}, m_view.select_start_time()); + m_profile.set_timestamp_filter_range(m_view.select_start_time(), m_view.select_end_time()); update(); } void ProfileTimelineWidget::mousemove_event(GUI::MouseEvent& event) { - m_hover_time = timestamp_at_x(event.x()); + m_view.set_hover_time({}, timestamp_at_x(event.x())); - if (m_selecting) { - m_select_end_time = m_hover_time; - m_profile.set_timestamp_filter_range(m_select_start_time, m_select_end_time); + if (m_view.is_selecting()) { + m_view.set_select_end_time({}, m_view.hover_time()); + m_profile.set_timestamp_filter_range(m_view.select_start_time(), m_view.select_end_time()); } update(); @@ -132,8 +133,8 @@ void ProfileTimelineWidget::mouseup_event(GUI::MouseEvent& event) if (event.button() != GUI::MouseButton::Left) return; - m_selecting = false; - if (m_select_start_time == m_select_end_time) + m_view.set_selecting({}, false); + if (m_view.select_start_time() == m_view.select_end_time()) m_profile.clear_timestamp_filter_range(); } diff --git a/Userland/DevTools/Profiler/ProfileTimelineWidget.h b/Userland/DevTools/Profiler/ProfileTimelineWidget.h index 76624aa955..8bb8ab3a82 100644 --- a/Userland/DevTools/Profiler/ProfileTimelineWidget.h +++ b/Userland/DevTools/Profiler/ProfileTimelineWidget.h @@ -12,6 +12,7 @@ namespace Profiler { class Process; class Profile; +class TimelineView; class ProfileTimelineWidget final : public GUI::Frame { C_OBJECT(ProfileTimelineWidget) @@ -24,17 +25,13 @@ private: virtual void mousemove_event(GUI::MouseEvent&) override; virtual void mouseup_event(GUI::MouseEvent&) override; - explicit ProfileTimelineWidget(Profile&, Process const&); + explicit ProfileTimelineWidget(TimelineView&, Profile&, Process const&); u64 timestamp_at_x(int x) const; + TimelineView& m_view; Profile& m_profile; Process const& m_process; - - bool m_selecting { false }; - u64 m_select_start_time { 0 }; - u64 m_select_end_time { 0 }; - u64 m_hover_time { 0 }; }; } diff --git a/Userland/DevTools/Profiler/TimelineView.cpp b/Userland/DevTools/Profiler/TimelineView.cpp new file mode 100644 index 0000000000..ae71668cb9 --- /dev/null +++ b/Userland/DevTools/Profiler/TimelineView.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "TimelineView.h" +#include + +namespace Profiler { + +TimelineView::TimelineView() +{ + set_layout(); + set_shrink_to_fit(true); +} + +TimelineView::~TimelineView() +{ +} + +} diff --git a/Userland/DevTools/Profiler/TimelineView.h b/Userland/DevTools/Profiler/TimelineView.h new file mode 100644 index 0000000000..fd5da55594 --- /dev/null +++ b/Userland/DevTools/Profiler/TimelineView.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Profiler { + +class ProfileTimelineWidget; + +class TimelineView final : public GUI::Widget { + C_OBJECT(TimelineView); + +public: + virtual ~TimelineView() override; + + bool is_selecting() const { return m_selecting; } + u64 select_start_time() const { return m_select_start_time; } + u64 select_end_time() const { return m_select_end_time; } + u64 hover_time() const { return m_hover_time; } + + void set_selecting(Badge, bool value) + { + m_selecting = value; + update(); + } + void set_select_start_time(Badge, u64 value) + { + m_select_start_time = value; + update(); + } + void set_select_end_time(Badge, u64 value) + { + m_select_end_time = value; + update(); + } + void set_hover_time(Badge, u64 value) + { + m_hover_time = value; + update(); + } + +private: + TimelineView(); + + bool m_selecting { false }; + u64 m_select_start_time { 0 }; + u64 m_select_end_time { 0 }; + u64 m_hover_time { 0 }; +}; + +} diff --git a/Userland/DevTools/Profiler/main.cpp b/Userland/DevTools/Profiler/main.cpp index da2d39c124..c6d5f15ba1 100644 --- a/Userland/DevTools/Profiler/main.cpp +++ b/Userland/DevTools/Profiler/main.cpp @@ -8,6 +8,7 @@ #include "ProcessPickerWidget.h" #include "Profile.h" #include "ProfileTimelineWidget.h" +#include "TimelineView.h" #include #include #include @@ -89,10 +90,7 @@ int main(int argc, char** argv) main_widget.set_fill_with_background_color(true); main_widget.set_layout(); - auto timelines_widget = GUI::Widget::construct(); - timelines_widget->set_layout(); - timelines_widget->set_shrink_to_fit(true); - + auto timeline_view = TimelineView::construct(); for (auto& process : profile->processes()) { size_t event_count = 0; for (auto& event : profile->events()) { @@ -101,11 +99,11 @@ int main(int argc, char** argv) } if (!event_count) continue; - timelines_widget->add(*profile, process); + timeline_view->add(*timeline_view, *profile, process); } auto& scrollable_container = main_widget.add(); - scrollable_container.set_widget(timelines_widget.ptr()); + scrollable_container.set_widget(timeline_view.ptr()); main_widget.add(*profile);