mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:52:43 +00:00 
			
		
		
		
	 fc6d051dfd
			
		
	
	
		fc6d051dfd
		
	
	
	
	
		
			
			The LexicalPath instance methods dirname(), basename(), title() and extension() will be changed to return StringView const& in a further commit. Due to this, users creating temporary LexicalPath objects just to call one of those getters will recieve a StringView const& pointing to a possible freed buffer. To avoid this, static methods for those APIs have been added, which will return a String by value to avoid those problems. All cases where temporary LexicalPath objects have been used as described above haven been changed to use the static APIs.
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include "TimelineHeader.h"
 | |
| #include "Process.h"
 | |
| #include "Profile.h"
 | |
| #include <AK/LexicalPath.h>
 | |
| #include <LibGUI/FileIconProvider.h>
 | |
| #include <LibGUI/Icon.h>
 | |
| #include <LibGUI/Painter.h>
 | |
| #include <LibGfx/Font.h>
 | |
| #include <LibGfx/Palette.h>
 | |
| 
 | |
| namespace Profiler {
 | |
| 
 | |
| TimelineHeader::TimelineHeader(Profile& profile, Process const& process)
 | |
|     : m_profile(profile)
 | |
|     , m_process(process)
 | |
| {
 | |
|     set_frame_shape(Gfx::FrameShape::Panel);
 | |
|     set_frame_shadow(Gfx::FrameShadow::Raised);
 | |
|     set_fixed_size(200, 40);
 | |
|     update_selection();
 | |
| 
 | |
|     m_icon = GUI::FileIconProvider::icon_for_executable(m_process.executable).bitmap_for_size(32);
 | |
|     m_text = String::formatted("{} ({})", LexicalPath::basename(m_process.executable), m_process.pid);
 | |
| }
 | |
| 
 | |
| TimelineHeader::~TimelineHeader()
 | |
| {
 | |
| }
 | |
| 
 | |
| void TimelineHeader::paint_event(GUI::PaintEvent& event)
 | |
| {
 | |
|     GUI::Frame::paint_event(event);
 | |
|     GUI::Painter painter(*this);
 | |
|     painter.add_clip_rect(event.rect());
 | |
| 
 | |
|     painter.fill_rect(frame_inner_rect(), m_selected ? palette().selection() : palette().button());
 | |
| 
 | |
|     Gfx::IntRect icon_rect { frame_thickness() + 2, 0, 32, 32 };
 | |
|     icon_rect.center_vertically_within(frame_inner_rect());
 | |
| 
 | |
|     if (m_icon)
 | |
|         painter.blit(icon_rect.location(), *m_icon, m_icon->rect());
 | |
| 
 | |
|     Gfx::IntRect text_rect {
 | |
|         icon_rect.right() + 6,
 | |
|         icon_rect.y(),
 | |
|         width() - 32,
 | |
|         32
 | |
|     };
 | |
|     text_rect.center_vertically_within(frame_inner_rect());
 | |
| 
 | |
|     auto& font = m_selected ? painter.font().bold_variant() : painter.font();
 | |
|     auto color = m_selected ? palette().selection_text() : palette().button_text();
 | |
|     painter.draw_text(text_rect, m_text, font, Gfx::TextAlignment::CenterLeft, color);
 | |
| }
 | |
| 
 | |
| void TimelineHeader::update_selection()
 | |
| {
 | |
|     m_selected = m_profile.has_process_filter() && m_profile.process_filter_contains(m_process.pid, m_process.start_valid);
 | |
|     update();
 | |
| }
 | |
| 
 | |
| void TimelineHeader::mousedown_event(GUI::MouseEvent& event)
 | |
| {
 | |
|     if (event.button() != GUI::MouseButton::Left)
 | |
|         return;
 | |
|     m_selected = !m_selected;
 | |
|     on_selection_change(m_selected);
 | |
| }
 | |
| 
 | |
| }
 |