mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-25 23:40:51 +08:00
Big bunch of changes:
* update copyright * fix css parsing * fix block name search * add matching text highlighing for find results * add calculation of block statistics for selected area * new action: right-click on a block on "Diagram" selects region using left and right bounds of this block * other optimizations
This commit is contained in:
parent
d4b414eb73
commit
92a5ca4a75
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright (c) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright (c) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright (c) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of profiling blocks
|
||||
* :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -16,7 +16,7 @@
|
||||
* : * 2016/09/17 Victor Zarubkin: added log messages printing.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : This file contains auxiliary profiler macros for different compiler support.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -298,6 +298,7 @@ namespace profiler {
|
||||
using blocks_t = profiler::BlocksTree::blocks_t;
|
||||
using thread_blocks_tree_t = std::unordered_map<profiler::thread_id_t, profiler::BlocksTreeRoot, ::estd::hash<profiler::thread_id_t> >;
|
||||
using block_getter_fn = std::function<const profiler::BlocksTree&(profiler::block_index_t)>;
|
||||
using stats_map_t = std::unordered_map<profiler::block_id_t, profiler::BlockStatistics*, estd::hash<profiler::block_id_t> >;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of Profile manager and implement access c-function
|
||||
* :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of Profile manager and implement access c-function
|
||||
* :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : which reads profiler file and fill profiler blocks tree.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -231,7 +231,6 @@ namespace profiler {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using StatsMap = std::unordered_map<profiler::block_id_t, profiler::BlockStatistics*, estd::hash<profiler::block_id_t> >;
|
||||
using IdMap = std::unordered_map<profiler::hashed_stdstring, profiler::block_id_t>;
|
||||
using CsStatsMap = std::unordered_map<profiler::string_with_hash, profiler::BlockStatistics*>;
|
||||
|
||||
@ -249,8 +248,14 @@ using CsStatsMap = std::unordered_map<profiler::string_with_hash, profiler::Bloc
|
||||
automatically receive statistics update.
|
||||
|
||||
*/
|
||||
static profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const profiler::BlocksTree& _current, profiler::block_index_t _current_index, profiler::block_index_t _parent_index, const profiler::blocks_t& _blocks, bool _calculate_children = true)
|
||||
{
|
||||
static profiler::BlockStatistics* update_statistics(
|
||||
profiler::stats_map_t& _stats_map,
|
||||
const profiler::BlocksTree& _current,
|
||||
profiler::block_index_t _current_index,
|
||||
profiler::block_index_t _parent_index,
|
||||
const profiler::blocks_t& _blocks,
|
||||
bool _calculate_children = true
|
||||
) {
|
||||
auto duration = _current.node->duration();
|
||||
//StatsMap::key_type key(_current.node->name());
|
||||
//auto it = _stats_map.find(key);
|
||||
@ -359,7 +364,7 @@ static profiler::BlockStatistics* update_statistics(CsStatsMap& _stats_map, cons
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void update_statistics_recursive(StatsMap& _stats_map, profiler::BlocksTree& _current, profiler::block_index_t _current_index, profiler::block_index_t _parent_index, profiler::blocks_t& _blocks)
|
||||
static void update_statistics_recursive(profiler::stats_map_t& _stats_map, profiler::BlocksTree& _current, profiler::block_index_t _current_index, profiler::block_index_t _parent_index, profiler::blocks_t& _blocks)
|
||||
{
|
||||
_current.per_frame_stats = update_statistics(_stats_map, _current, _current_index, _parent_index, _blocks, false);
|
||||
for (auto i : _current.children)
|
||||
@ -696,7 +701,7 @@ extern "C" PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<
|
||||
}
|
||||
}
|
||||
|
||||
using PerThreadStats = std::unordered_map<profiler::thread_id_t, StatsMap, estd::hash<profiler::thread_id_t> >;
|
||||
using PerThreadStats = std::unordered_map<profiler::thread_id_t, profiler::stats_map_t, estd::hash<profiler::thread_id_t> >;
|
||||
PerThreadStats parent_statistics, frame_statistics;
|
||||
IdMap identification_table;
|
||||
|
||||
@ -808,7 +813,7 @@ extern "C" PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<
|
||||
if (inStream.eof())
|
||||
break;
|
||||
|
||||
StatsMap per_thread_statistics;
|
||||
profiler::stats_map_t per_thread_statistics;
|
||||
|
||||
blocks_number_in_thread = 0;
|
||||
read(inStream, blocks_number_in_thread);
|
||||
|
@ -16,7 +16,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "EasySolutions"
|
||||
VALUE "FileDescription", "Lightweight profiler library for C++"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2016-2018 Victor Zarubkin, Sergey Yagovtsev"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2016-2019 Victor Zarubkin, Sergey Yagovtsev"
|
||||
VALUE "LegalTrademarks1", "All Rights Reserved"
|
||||
VALUE "LegalTrademarks2", "All Rights Reserved"
|
||||
VALUE "ProductName", "easy_profiler lib"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : which reads profiler file and fill profiler blocks tree.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -49,6 +49,8 @@ if (Qt5Widgets_FOUND)
|
||||
main_window.cpp
|
||||
round_progress_widget.h
|
||||
round_progress_widget.cpp
|
||||
text_highlighter.h
|
||||
text_highlighter.cpp
|
||||
timer.h
|
||||
timer.cpp
|
||||
thread_pool.h
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -1121,7 +1121,7 @@ void ArbitraryValuesChartItem::updateRegularImageAsync(QRectF _boundingRect, qre
|
||||
{
|
||||
auto color = profiler_gui::darken(c.color, 0.65f);
|
||||
if (profiler_gui::alpha(color) < 0xc0)
|
||||
p.setPen(QColor::fromRgba(profiler::colors::modify_alpha32(0xc0000000, color)));
|
||||
p.setPen(QColor::fromRgba(profiler::colors::modify_alpha32(color, 0xc0000000)));
|
||||
else
|
||||
p.setPen(QColor::fromRgba(color));
|
||||
p.setBrush(QColor::fromRgba(0xc8ffffff));
|
||||
@ -1456,7 +1456,7 @@ void ArbitraryValuesChartItem::updateComplexityImageAsync(QRectF _boundingRect,
|
||||
|
||||
auto color = profiler_gui::darken(c.color, 0.65f);
|
||||
if (profiler_gui::alpha(color) < 0xc0)
|
||||
p.setPen(QColor::fromRgba(profiler::colors::modify_alpha32(0xc0000000, color)));
|
||||
p.setPen(QColor::fromRgba(profiler::colors::modify_alpha32(color, 0xc0000000)));
|
||||
else
|
||||
p.setPen(QColor::fromRgba(color));
|
||||
p.setBrush(QColor::fromRgba(0xc8ffffff));
|
||||
@ -1546,12 +1546,14 @@ void ArbitraryValuesChartItem::clear()
|
||||
m_collections.clear();
|
||||
m_minValue = m_maxValue = 0;
|
||||
m_minDuration = m_maxDuration = 0;
|
||||
setEmpty(true);
|
||||
}
|
||||
|
||||
void ArbitraryValuesChartItem::update(Collections _collections)
|
||||
{
|
||||
cancelImageUpdate();
|
||||
m_collections = std::move(_collections);
|
||||
setEmpty(m_collections.empty());
|
||||
updateImage();
|
||||
}
|
||||
|
||||
@ -1866,6 +1868,7 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(bool _isMainWidget, profiler::threa
|
||||
, m_threadId(_threadId)
|
||||
, m_blockIndex(_blockIndex)
|
||||
, m_blockId(_blockId)
|
||||
, m_bInitialized(false)
|
||||
, m_bMainWidget(_isMainWidget)
|
||||
{
|
||||
m_collectionsTimer.setInterval(100);
|
||||
@ -1903,12 +1906,12 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(bool _isMainWidget, profiler::threa
|
||||
auto actionGroup = new QActionGroup(this);
|
||||
actionGroup->setExclusive(true);
|
||||
|
||||
auto actionRegulatChart = new QAction(QIcon(imagePath("yx-chart")), tr("Regular chart"), actionGroup);
|
||||
auto actionRegulatChart = new QAction(QIcon(imagePath("yx-chart")), tr("Regular chart [ v(t) ]"), actionGroup);
|
||||
actionRegulatChart->setCheckable(true);
|
||||
actionRegulatChart->setChecked(true);
|
||||
tb->addAction(actionRegulatChart);
|
||||
|
||||
auto actionComplexityChart = new QAction(QIcon(imagePath("big-o-chart")), tr("Complexity chart"), actionGroup);
|
||||
auto actionComplexityChart = new QAction(QIcon(imagePath("big-o-chart")), tr("Complexity chart [ t(v) ]"), actionGroup);
|
||||
actionComplexityChart->setCheckable(true);
|
||||
tb->addAction(actionComplexityChart);
|
||||
|
||||
@ -1950,6 +1953,8 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(bool _isMainWidget, profiler::threa
|
||||
connect(globalEvents, &GlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
|
||||
connect(globalEvents, &GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||
|
||||
connect(m_treeWidget->header(), &QHeaderView::sectionResized, this, &This::onHeaderSectionResized);
|
||||
|
||||
if (_isMainWidget)
|
||||
{
|
||||
connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked);
|
||||
@ -1989,6 +1994,69 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||
m_exportToCsvAction->setEnabled(false);
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
Parent::showEvent(event);
|
||||
|
||||
if (!m_bInitialized)
|
||||
{
|
||||
m_columnsMinimumWidth.resize(static_cast<size_t>(ArbitraryColumns::Count), 0);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
const auto padding = px(9);
|
||||
#else
|
||||
const auto padding = px(6);
|
||||
#endif
|
||||
|
||||
auto header = m_treeWidget->header();
|
||||
auto headerItem = m_treeWidget->headerItem();
|
||||
|
||||
auto f = header->font();
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
f.setBold(true);
|
||||
#endif
|
||||
QFontMetrics fm(f);
|
||||
|
||||
const auto indicatorSize = header->isSortIndicatorShown() ? px(11) : 0;
|
||||
for (int i = 0; i < static_cast<int>(m_columnsMinimumWidth.size()); ++i)
|
||||
{
|
||||
auto minSize = static_cast<int>(fm.width(headerItem->text(i)) * profiler_gui::FONT_METRICS_FACTOR + padding);
|
||||
m_columnsMinimumWidth[i] = minSize;
|
||||
|
||||
if (header->isSortIndicatorShown() && header->sortIndicatorSection() == i)
|
||||
{
|
||||
minSize += indicatorSize;
|
||||
}
|
||||
|
||||
if (header->sectionSize(i) < minSize)
|
||||
{
|
||||
header->resizeSection(i, minSize);
|
||||
}
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::onHeaderSectionResized(int logicalIndex, int /*oldSize*/, int newSize)
|
||||
{
|
||||
if (logicalIndex >= m_columnsMinimumWidth.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto header = m_treeWidget->header();
|
||||
const auto indicatorSize = header->isSortIndicatorShown() && header->sortIndicatorSection() == logicalIndex ? px(11) : 0;
|
||||
const auto minSize = m_columnsMinimumWidth[logicalIndex] + indicatorSize;
|
||||
|
||||
if (!m_bInitialized || newSize >= minSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
header->resizeSection(logicalIndex, minSize);
|
||||
}
|
||||
|
||||
ArbitraryTreeWidgetItem* findSimilarItem(QTreeWidgetItem* _parentItem, ArbitraryTreeWidgetItem* _item)
|
||||
{
|
||||
const auto index = _item->getSelfIndexInArray();
|
||||
@ -2583,12 +2651,7 @@ void ArbitraryValuesWidget::onOpenInNewWindowClicked(bool)
|
||||
|
||||
auto viewer = new ArbitraryValuesWidget(m_checkedItems, m_treeWidget->currentItem(), m_threadId, m_blockIndex, m_blockId);
|
||||
|
||||
#ifdef WIN32
|
||||
const WindowHeader::Buttons buttons = WindowHeader::AllButtons;
|
||||
#else
|
||||
const WindowHeader::Buttons buttons {WindowHeader::MaximizeButton | WindowHeader::CloseButton};
|
||||
#endif
|
||||
auto dialog = new Dialog(nullptr, "EasyProfiler", viewer, buttons, QMessageBox::NoButton);
|
||||
auto dialog = new Dialog(nullptr, "EasyProfiler", viewer, WindowHeader::AllButtons, QMessageBox::NoButton);
|
||||
dialog->setProperty("stayVisible", true);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::allDataGoingToBeDeleted, dialog, &QDialog::reject);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -341,6 +341,7 @@ class ArbitraryValuesWidget : public QWidget
|
||||
|
||||
QTimer m_collectionsTimer;
|
||||
QList<ArbitraryTreeWidgetItem*> m_checkedItems;
|
||||
std::vector<int> m_columnsMinimumWidth;
|
||||
class QSplitter* m_splitter;
|
||||
QTreeWidget* m_treeWidget;
|
||||
GraphicsChart* m_chart;
|
||||
@ -353,6 +354,7 @@ class ArbitraryValuesWidget : public QWidget
|
||||
profiler::thread_id_t m_threadId;
|
||||
profiler::block_index_t m_blockIndex;
|
||||
profiler::block_id_t m_blockId;
|
||||
bool m_bInitialized;
|
||||
const bool m_bMainWidget;
|
||||
|
||||
explicit ArbitraryValuesWidget(bool _isMainWidget, profiler::thread_id_t _threadId
|
||||
@ -366,6 +368,7 @@ public:
|
||||
explicit ArbitraryValuesWidget(QWidget* _parent = nullptr);
|
||||
~ArbitraryValuesWidget() override;
|
||||
|
||||
void showEvent(class QShowEvent* event) override;
|
||||
void contextMenuEvent(QContextMenuEvent*) override { /* ignore context menu event */ }
|
||||
|
||||
public slots:
|
||||
@ -377,6 +380,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
|
||||
void onHeaderSectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
void onSelectedThreadChanged(profiler::thread_id_t);
|
||||
void onSelectedBlockChanged(uint32_t _block_index);
|
||||
void onSelectedBlockIdChanged(profiler::block_id_t _id);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : for displaying arbitrary value in Diagram and Hierarchy widgets.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : for displaying arbitrary value in Diagram and Hierarchy widgets.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -24,7 +24,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -500,7 +500,12 @@ bool BackgroundItem::mouseDoubleClick(const QPointF& scenePos)
|
||||
{
|
||||
qApp->restoreOverrideCursor();
|
||||
auto editor = new BookmarkEditor(m_bookmark, false, sceneView->parentWidget());
|
||||
#ifndef _WIN32
|
||||
// Ugly workaround for Linux: without show-hide-show you can not drag the window
|
||||
editor->show();
|
||||
editor->hide();
|
||||
#endif
|
||||
editor->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -523,7 +528,12 @@ bool BackgroundItem::mouseDoubleClick(const QPointF& scenePos)
|
||||
{
|
||||
qApp->restoreOverrideCursor();
|
||||
auto editor = new BookmarkEditor(m_bookmark, true, sceneView->parentWidget());
|
||||
#ifndef _WIN32
|
||||
// Ugly workaround for Linux: without show-hide-show you can not drag the window
|
||||
editor->show();
|
||||
editor->hide();
|
||||
#endif
|
||||
editor->exec();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1528,11 +1538,11 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
|
||||
const profiler_gui::EasyBlock* selectedBlock = nullptr;
|
||||
profiler::thread_id_t selectedBlockThread = 0;
|
||||
const auto previouslySelectedBlock = EASY_GLOBALS.selected_block;
|
||||
if (m_mouseButtons & Qt::LeftButton)
|
||||
bool jumpToZone = false;
|
||||
bool changedSelectionBySelectingItem = false;
|
||||
const bool leftClickSelect = (m_mouseButtons & Qt::LeftButton) != 0;
|
||||
if (leftClickSelect)
|
||||
{
|
||||
bool clicked = false;
|
||||
|
||||
if (m_rulerItem->isVisible() && m_rulerItem->width() < 1e-6)
|
||||
{
|
||||
chronoHidden = true;
|
||||
@ -1542,44 +1552,83 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
else if (m_selectionItem->isVisible() && m_selectionItem->hoverIndicator())
|
||||
{
|
||||
// Jump to selected zone
|
||||
clicked = true;
|
||||
jumpToZone = true;
|
||||
m_flickerSpeedX = m_flickerSpeedY = 0;
|
||||
notifyVisibleRegionPosChange(m_selectionItem->left() + (m_selectionItem->width() - m_visibleRegionWidth) * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
if (!clicked && m_mouseMovePath.manhattanLength() < 5 && !m_backgroundItem->contains(scenePos))
|
||||
const bool rightClickSelect = ((m_mouseButtons & Qt::RightButton) != 0 && !changedSelection);
|
||||
if ((leftClickSelect || rightClickSelect) && !jumpToZone && m_mouseMovePath.manhattanLength() < 5 && !m_backgroundItem->contains(scenePos))
|
||||
{
|
||||
// Handle Click
|
||||
|
||||
//clicked = true;
|
||||
auto mouseClickPos = mapToScene(m_mousePressPos);
|
||||
if (mouseClickPos.x() >= 0)
|
||||
{
|
||||
// Handle Click
|
||||
mouseClickPos.setX(m_offset + mouseClickPos.x() / m_scale);
|
||||
|
||||
//clicked = true;
|
||||
auto mouseClickPos = mapToScene(m_mousePressPos);
|
||||
if (mouseClickPos.x() >= 0)
|
||||
// Try to select one of item blocks
|
||||
for (auto item : m_items)
|
||||
{
|
||||
mouseClickPos.setX(m_offset + mouseClickPos.x() / m_scale);
|
||||
|
||||
// Try to select one of item blocks
|
||||
for (auto item : m_items)
|
||||
{
|
||||
profiler::block_index_t i = ~0U;
|
||||
auto block = item->intersect(mouseClickPos, i);
|
||||
if (block != nullptr)
|
||||
{
|
||||
changedSelectedItem = true;
|
||||
selectedBlock = block;
|
||||
selectedBlockThread = item->threadId();
|
||||
EASY_GLOBALS.selected_block = i;
|
||||
EASY_GLOBALS.selected_block_id = easyBlock(i).tree.node->id();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changedSelectedItem && !profiler_gui::is_max(EASY_GLOBALS.selected_block))
|
||||
profiler::block_index_t i = ~0U;
|
||||
auto block = item->intersect(mouseClickPos, i);
|
||||
if (block != nullptr)
|
||||
{
|
||||
changedSelectedItem = true;
|
||||
profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||
profiler_gui::set_max(EASY_GLOBALS.selected_block_id);
|
||||
selectedBlock = block;
|
||||
selectedBlockThread = item->threadId();
|
||||
EASY_GLOBALS.selected_block = i;
|
||||
EASY_GLOBALS.selected_block_id = block->tree.node->id();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changedSelectedItem && !profiler_gui::is_max(EASY_GLOBALS.selected_block))
|
||||
{
|
||||
changedSelectedItem = true;
|
||||
profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||
profiler_gui::set_max(EASY_GLOBALS.selected_block_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedBlock != nullptr && rightClickSelect)
|
||||
{
|
||||
if (!m_selectedBlocks.empty())
|
||||
{
|
||||
changedSelection = true;
|
||||
m_selectedBlocks.clear();
|
||||
}
|
||||
|
||||
const auto thread_item = m_items[selectedBlock->graphics_item];
|
||||
const auto& selectedItem = thread_item->items(selectedBlock->graphics_item_level)[selectedBlock->graphics_item_index];
|
||||
const auto left = selectedItem.left();
|
||||
const auto right = selectedItem.right();
|
||||
|
||||
for (auto item : m_items)
|
||||
{
|
||||
if (!EASY_GLOBALS.only_current_thread_hierarchy || (EASY_GLOBALS.selecting_block_changes_thread && selectedBlockThread == item->threadId()))
|
||||
{
|
||||
item->getBlocks(left, right, m_selectedBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_selectedBlocks.empty())
|
||||
{
|
||||
changedSelection = true;
|
||||
m_selectionItem->setLeftRight(left, right);
|
||||
m_selectionItem->setReverse(true);
|
||||
m_selectionItem->setStrict(true);
|
||||
m_selectionItem->show();
|
||||
|
||||
m_pScrollbar->setSelectionPos(left, right);
|
||||
m_pScrollbar->showSelectionIndicator();
|
||||
|
||||
emit EASY_GLOBALS.events.rulerVisible(true);
|
||||
}
|
||||
|
||||
changedSelectionBySelectingItem = changedSelection;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1591,15 +1640,24 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
|
||||
if (changedSelection)
|
||||
{
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_selectionItem->left()), position2time(m_selectionItem->right()), m_selectionItem->reverse());
|
||||
profiler::timestamp_t left=0, right=0;
|
||||
if (changedSelectionBySelectingItem)
|
||||
{
|
||||
left = selectedBlock->tree.node->begin() - m_beginTime;
|
||||
right = selectedBlock->tree.node->end() - m_beginTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = position2time(m_selectionItem->left());
|
||||
right = position2time(m_selectionItem->right());
|
||||
}
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, left, right, m_selectionItem->strict());
|
||||
}
|
||||
|
||||
if (changedSelectedItem)
|
||||
{
|
||||
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true);
|
||||
|
||||
emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
|
||||
|
||||
if (EASY_GLOBALS.selecting_block_changes_thread && selectedBlock != nullptr && EASY_GLOBALS.selected_thread != selectedBlockThread)
|
||||
{
|
||||
EASY_GLOBALS.selected_thread = selectedBlockThread;
|
||||
@ -1609,6 +1667,8 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
emit EASY_GLOBALS.events.unlockCharts();
|
||||
}
|
||||
|
||||
emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
|
||||
|
||||
if (selectedBlock != nullptr && isDoubleClick)
|
||||
{
|
||||
if (!selectedBlock->tree.children.empty())
|
||||
@ -1641,6 +1701,10 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
||||
|
||||
repaintScene();
|
||||
}
|
||||
else if (jumpToZone)
|
||||
{
|
||||
repaintScene();
|
||||
}
|
||||
else if (chronoHidden)
|
||||
{
|
||||
emit sceneUpdated();
|
||||
@ -1677,7 +1741,13 @@ void BlocksGraphicsView::addSelectionToHierarchy()
|
||||
|
||||
if (changedSelection)
|
||||
{
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_selectionItem->left()), position2time(m_selectionItem->right()), m_selectionItem->reverse());
|
||||
emit intervalChanged(
|
||||
m_selectedBlocks,
|
||||
m_beginTime,
|
||||
position2time(m_selectionItem->left()),
|
||||
position2time(m_selectionItem->right()),
|
||||
m_selectionItem->strict()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1712,14 +1782,15 @@ void BlocksGraphicsView::onZoomSelection()
|
||||
repaintScene(); // repaint scene
|
||||
}
|
||||
|
||||
void BlocksGraphicsView::onInspectCurrentView(bool _strict)
|
||||
void BlocksGraphicsView::onInspectCurrentView(bool strict)
|
||||
{
|
||||
if (m_bEmpty)
|
||||
return;
|
||||
|
||||
if (!m_selectionItem->isVisible())
|
||||
{
|
||||
m_selectionItem->setReverse(_strict);
|
||||
m_selectionItem->setReverse(strict);
|
||||
m_selectionItem->setStrict(strict);
|
||||
m_selectionItem->setLeftRight(m_offset, m_offset + m_visibleRegionWidth);
|
||||
m_selectionItem->show();
|
||||
m_pScrollbar->setSelectionPos(m_selectionItem->left(), m_selectionItem->right());
|
||||
@ -1737,48 +1808,53 @@ void BlocksGraphicsView::onInspectCurrentView(bool _strict)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool BlocksGraphicsView::moveChrono(GraphicsRulerItem* _chronometerItem, qreal _mouseX)
|
||||
bool BlocksGraphicsView::moveChrono(GraphicsRulerItem* ruler_item, qreal mouse_x)
|
||||
{
|
||||
if (_chronometerItem->reverse())
|
||||
if (ruler_item->reverse())
|
||||
{
|
||||
if (_mouseX > _chronometerItem->right())
|
||||
if (mouse_x > ruler_item->right())
|
||||
{
|
||||
_chronometerItem->setReverse(false);
|
||||
_chronometerItem->setLeftRight(_chronometerItem->right(), _mouseX);
|
||||
ruler_item->setReverse(false);
|
||||
ruler_item->setLeftRight(ruler_item->right(), mouse_x);
|
||||
|
||||
if (_chronometerItem->hoverLeft())
|
||||
if (ruler_item->hoverLeft())
|
||||
{
|
||||
_chronometerItem->setHoverLeft(false);
|
||||
_chronometerItem->setHoverRight(true);
|
||||
ruler_item->setHoverLeft(false);
|
||||
ruler_item->setHoverRight(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_chronometerItem->setLeftRight(_mouseX, _chronometerItem->right());
|
||||
ruler_item->setLeftRight(mouse_x, ruler_item->right());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_mouseX < _chronometerItem->left())
|
||||
if (mouse_x < ruler_item->left())
|
||||
{
|
||||
_chronometerItem->setReverse(true);
|
||||
_chronometerItem->setLeftRight(_mouseX, _chronometerItem->left());
|
||||
ruler_item->setReverse(true);
|
||||
ruler_item->setLeftRight(mouse_x, ruler_item->left());
|
||||
|
||||
if (_chronometerItem->hoverRight())
|
||||
if (ruler_item->hoverRight())
|
||||
{
|
||||
_chronometerItem->setHoverLeft(true);
|
||||
_chronometerItem->setHoverRight(false);
|
||||
ruler_item->setHoverLeft(true);
|
||||
ruler_item->setHoverRight(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_chronometerItem->setLeftRight(_chronometerItem->left(), _mouseX);
|
||||
ruler_item->setLeftRight(ruler_item->left(), mouse_x);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_chronometerItem->isVisible() && _chronometerItem->width() > 1e-6)
|
||||
if (!ruler_item->hoverAnyBorder())
|
||||
{
|
||||
_chronometerItem->show();
|
||||
ruler_item->setStrict(ruler_item->reverse());
|
||||
}
|
||||
|
||||
if (!ruler_item->isVisible() && ruler_item->width() > 1e-6)
|
||||
{
|
||||
ruler_item->show();
|
||||
emit EASY_GLOBALS.events.rulerVisible(true);
|
||||
return true;
|
||||
}
|
||||
@ -1786,7 +1862,7 @@ bool BlocksGraphicsView::moveChrono(GraphicsRulerItem* _chronometerItem, qreal _
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlocksGraphicsView::mouseMoveEvent(QMouseEvent* _event)
|
||||
void BlocksGraphicsView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (needToIgnoreMouseEvent())
|
||||
return;
|
||||
@ -1795,26 +1871,26 @@ void BlocksGraphicsView::mouseMoveEvent(QMouseEvent* _event)
|
||||
|
||||
if (m_bEmpty)
|
||||
{
|
||||
_event->accept();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
auto scenePos = mapToScene(_event->pos());
|
||||
auto scenePos = mapToScene(event->pos());
|
||||
scenePos.setX(m_offset + scenePos.x() / m_scale);
|
||||
if (m_backgroundItem->mouseMove(scenePos))
|
||||
{
|
||||
_event->accept();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_mouseButtons == 0 && !m_selectionItem->isVisible() && !m_rulerItem->isVisible())
|
||||
{
|
||||
_event->accept();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
bool needUpdate = false;
|
||||
const auto pos = _event->pos();
|
||||
const auto pos = event->pos();
|
||||
const auto delta = pos - m_mousePressPos;
|
||||
m_mousePressPos = pos;
|
||||
|
||||
@ -1851,7 +1927,9 @@ void BlocksGraphicsView::mouseMoveEvent(QMouseEvent* _event)
|
||||
{
|
||||
auto vbar = verticalScrollBar();
|
||||
|
||||
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true); // Block scrollbars from updating scene rect to make it possible to do it only once
|
||||
// Block scrollbars from updating scene rect to make it possible to do it only once
|
||||
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true);
|
||||
|
||||
vbar->setValue(vbar->value() - delta.y());
|
||||
notifyVisibleRegionPosChange(m_offset - delta.x() / m_scale);
|
||||
guard.restore();
|
||||
@ -1913,16 +1991,16 @@ void BlocksGraphicsView::mouseMoveEvent(QMouseEvent* _event)
|
||||
repaintScene(); // repaint scene
|
||||
}
|
||||
|
||||
_event->accept();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BlocksGraphicsView::keyPressEvent(QKeyEvent* _event)
|
||||
void BlocksGraphicsView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
static const int KeyStep = 100;
|
||||
|
||||
const int key = _event->key();
|
||||
const int key = event->key();
|
||||
|
||||
switch (key)
|
||||
{
|
||||
@ -1971,14 +2049,14 @@ void BlocksGraphicsView::keyPressEvent(QKeyEvent* _event)
|
||||
}
|
||||
|
||||
m_idleTime = 0;
|
||||
_event->accept();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BlocksGraphicsView::resizeEvent(QResizeEvent* _event)
|
||||
void BlocksGraphicsView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
Parent::resizeEvent(_event);
|
||||
Parent::resizeEvent(event);
|
||||
|
||||
const QRectF previousRect = m_visibleSceneRect;
|
||||
const int vbar_width = updateVisibleSceneRect(); // Update scene visible rect only once
|
||||
@ -2062,7 +2140,13 @@ void BlocksGraphicsView::initMode()
|
||||
connect(globalSignals, &profiler_gui::GlobalSignals::blocksTreeModeChanged, [this]()
|
||||
{
|
||||
if (!m_selectedBlocks.empty())
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_selectionItem->left()), position2time(m_selectionItem->right()), m_selectionItem->reverse());
|
||||
emit intervalChanged(
|
||||
m_selectedBlocks,
|
||||
m_beginTime,
|
||||
position2time(m_selectionItem->left()),
|
||||
position2time(m_selectionItem->right()),
|
||||
m_selectionItem->strict()
|
||||
);
|
||||
});
|
||||
|
||||
connect(globalSignals, &profiler_gui::GlobalSignals::chartSliderChanged, this, &This::onGraphicsScrollbarValueChange);
|
||||
@ -2095,11 +2179,11 @@ void BlocksGraphicsView::onScrollbarValueChange(int)
|
||||
updateVisibleSceneRect();
|
||||
}
|
||||
|
||||
void BlocksGraphicsView::onGraphicsScrollbarValueChange(qreal _value)
|
||||
void BlocksGraphicsView::onGraphicsScrollbarValueChange(qreal value)
|
||||
{
|
||||
if (!m_bEmpty)
|
||||
{
|
||||
m_offset = _value;
|
||||
m_offset = value;
|
||||
if (!m_bUpdatingRect)
|
||||
{
|
||||
updateVisibleSceneRect();
|
||||
@ -2184,7 +2268,7 @@ void BlocksGraphicsView::onIdleTimeout()
|
||||
if (m_popupWidget != nullptr)
|
||||
return;
|
||||
|
||||
if (!window()->isActiveWindow())
|
||||
if (window() == nullptr || !window()->isActiveWindow())
|
||||
return;
|
||||
|
||||
auto focusWidget = qApp->focusWidget();
|
||||
@ -2507,7 +2591,7 @@ void BlocksGraphicsView::onIdleTimeout()
|
||||
lay->addWidget(new QLabel(QString::number(itemBlock.per_frame_stats->calls_number), widget), row + 5, col, Qt::AlignHCenter);
|
||||
}
|
||||
|
||||
if (!profiler_gui::is_max(itemBlock.per_parent_stats->parent_block))// != item->threadId())
|
||||
if (!profiler_gui::is_max(itemBlock.per_parent_stats->parent_block))
|
||||
{
|
||||
++col;
|
||||
auto parent_duration = easyBlocksTree(itemBlock.per_parent_stats->parent_block).node->duration();
|
||||
@ -2592,18 +2676,24 @@ void BlocksGraphicsView::onHierarchyFlagChange(bool)
|
||||
|
||||
if (changedSelection)
|
||||
{
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_selectionItem->left()), position2time(m_selectionItem->right()), m_selectionItem->reverse());
|
||||
emit intervalChanged(
|
||||
m_selectedBlocks,
|
||||
m_beginTime,
|
||||
position2time(m_selectionItem->left()),
|
||||
position2time(m_selectionItem->right()),
|
||||
m_selectionItem->strict()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void BlocksGraphicsView::onSelectedThreadChange(profiler::thread_id_t _id)
|
||||
void BlocksGraphicsView::onSelectedThreadChange(profiler::thread_id_t id)
|
||||
{
|
||||
if (m_pScrollbar == nullptr || m_pScrollbar->hystThread() == _id)
|
||||
if (m_pScrollbar == nullptr || m_pScrollbar->hystThread() == id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_id == 0)
|
||||
if (id == 0)
|
||||
{
|
||||
m_pScrollbar->setHistogramSource(0, nullptr);
|
||||
return;
|
||||
@ -2611,9 +2701,9 @@ void BlocksGraphicsView::onSelectedThreadChange(profiler::thread_id_t _id)
|
||||
|
||||
for (auto item : m_items)
|
||||
{
|
||||
if (item->threadId() == _id)
|
||||
if (item->threadId() == id)
|
||||
{
|
||||
m_pScrollbar->setHistogramSource(_id, item->items(0));
|
||||
m_pScrollbar->setHistogramSource(id, item->items(0));
|
||||
|
||||
bool changedSelection = false;
|
||||
if (EASY_GLOBALS.only_current_thread_hierarchy)
|
||||
@ -2634,7 +2724,13 @@ void BlocksGraphicsView::onSelectedThreadChange(profiler::thread_id_t _id)
|
||||
|
||||
if (changedSelection)
|
||||
{
|
||||
emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_selectionItem->left()), position2time(m_selectionItem->right()), m_selectionItem->reverse());
|
||||
emit intervalChanged(
|
||||
m_selectedBlocks,
|
||||
m_beginTime,
|
||||
position2time(m_selectionItem->left()),
|
||||
position2time(m_selectionItem->right()),
|
||||
m_selectionItem->strict()
|
||||
);
|
||||
}
|
||||
|
||||
repaintScene();
|
||||
@ -3007,7 +3103,7 @@ void ThreadNamesWidget::onIdleTimeout()
|
||||
if (m_popupWidget != nullptr)
|
||||
return;
|
||||
|
||||
if (!window()->isActiveWindow())
|
||||
if (window() == nullptr || !window()->isActiveWindow())
|
||||
return;
|
||||
|
||||
auto focusWidget = qApp->focusWidget();
|
||||
@ -3123,7 +3219,7 @@ void ThreadNamesWidget::onIdleTimeout()
|
||||
m_popupWidget = widget;
|
||||
if (m_popupWidget != nullptr)
|
||||
{
|
||||
auto focusWidget = qApp->focusWidget();
|
||||
focusWidget = qApp->focusWidget();
|
||||
|
||||
m_popupWidget->move(QCursor::pos());
|
||||
m_popupWidget->show();
|
||||
|
@ -20,7 +20,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -236,9 +236,9 @@ public:
|
||||
void mousePressEvent(QMouseEvent* _event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent* _event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* _event) override;
|
||||
void mouseMoveEvent(QMouseEvent* _event) override;
|
||||
void keyPressEvent(QKeyEvent* _event) override;
|
||||
void resizeEvent(QResizeEvent* _event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent*) override {}
|
||||
|
||||
@ -288,7 +288,7 @@ private:
|
||||
bool needToIgnoreMouseEvent() const;
|
||||
|
||||
GraphicsRulerItem* createRuler(bool _main = true);
|
||||
bool moveChrono(GraphicsRulerItem* _chronometerItem, qreal _mouseX);
|
||||
bool moveChrono(GraphicsRulerItem* ruler_item, qreal mouse_x);
|
||||
void initMode();
|
||||
int updateVisibleSceneRect();
|
||||
void updateTimelineStep(qreal _windowWidth);
|
||||
@ -313,7 +313,7 @@ private slots:
|
||||
void onFlickerTimeout();
|
||||
void onIdleTimeout();
|
||||
void onHierarchyFlagChange(bool _value);
|
||||
void onSelectedThreadChange(::profiler::thread_id_t _id);
|
||||
void onSelectedThreadChange(::profiler::thread_id_t id);
|
||||
void onSelectedBlockChange(unsigned int _block_index);
|
||||
void onRefreshRequired();
|
||||
void onThreadViewChanged();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@
|
||||
* : Moved sources of TreeWidgetItem into tree_widget_item.h/.cpp
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -95,13 +95,18 @@ protected:
|
||||
class QLabel* m_hintLabel;
|
||||
class ArbitraryValueToolTip* m_valueTooltip;
|
||||
TreeMode m_mode;
|
||||
int m_lastFoundIndex;
|
||||
bool m_bLocked;
|
||||
bool m_bSilentExpandCollapse;
|
||||
bool m_bCaseSensitiveSearch;
|
||||
bool m_bInitialized;
|
||||
char m_columnsHiddenStatus[COL_COLUMNS_NUMBER];
|
||||
int m_columnsMinimumWidth[COL_COLUMNS_NUMBER];
|
||||
|
||||
public:
|
||||
|
||||
using Parent::indexFromItem;
|
||||
|
||||
explicit BlocksTreeWidget(QWidget* _parent = nullptr);
|
||||
~BlocksTreeWidget() override;
|
||||
|
||||
@ -114,11 +119,22 @@ public:
|
||||
int findNext(const QString& _str, Qt::MatchFlags _flags);
|
||||
int findPrev(const QString& _str, Qt::MatchFlags _flags);
|
||||
|
||||
void resetSearch(bool repaint = true);
|
||||
|
||||
TreeMode mode() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* lastFoundItem() const;
|
||||
const QString& searchString() const;
|
||||
bool caseSensitiveSearch() const;
|
||||
int lastFoundIndex() const;
|
||||
|
||||
public slots:
|
||||
|
||||
void setTree(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree);
|
||||
|
||||
void setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _session_begin_time, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict);
|
||||
void updateHintLabelOnHover(bool hover);
|
||||
|
||||
protected:
|
||||
|
||||
@ -127,6 +143,8 @@ protected:
|
||||
|
||||
private slots:
|
||||
|
||||
void onHeaderSectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
|
||||
void onJumpToItemClicked(bool);
|
||||
|
||||
void onCollapseAllClicked(bool);
|
||||
@ -140,6 +158,7 @@ private slots:
|
||||
void onItemExpand(QTreeWidgetItem* _item);
|
||||
void onItemCollapse(QTreeWidgetItem* _item);
|
||||
void onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem*);
|
||||
void onItemDoubleClicked(QTreeWidgetItem* _item, int _column);
|
||||
|
||||
void onSelectedThreadChange(::profiler::thread_id_t _id);
|
||||
|
||||
@ -192,6 +211,8 @@ public:
|
||||
explicit HierarchyWidget(QWidget* _parent = nullptr);
|
||||
~HierarchyWidget() override;
|
||||
|
||||
void enterEvent(QEvent* event) override;
|
||||
void leaveEvent(QEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* _event) override;
|
||||
void contextMenuEvent(QContextMenuEvent* _event) override;
|
||||
void dragEnterEvent(QDragEnterEvent*) override {}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of BookmarkEditor.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -70,7 +70,6 @@ BookmarkEditor::BookmarkEditor(size_t bookmarkIndex, bool isNew, QWidget* parent
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
setSizeGripEnabled(EASY_GLOBALS.use_custom_window_header);
|
||||
setModal(true);
|
||||
|
||||
const auto& bookmark = EASY_GLOBALS.bookmarks[m_bookmarkIndex];
|
||||
|
||||
@ -128,7 +127,7 @@ BookmarkEditor::BookmarkEditor(size_t bookmarkIndex, bool isNew, QWidget* parent
|
||||
contentLayout->addWidget(m_textEdit, 1);
|
||||
|
||||
const WindowHeader::Buttons buttons {WindowHeader::MaximizeButton | WindowHeader::CloseButton};
|
||||
auto header = new WindowHeader(isNew ? "New bookmark" : "Edit bookmark", buttons, this);
|
||||
auto header = new WindowHeader(isNew ? "New bookmark" : "Edit bookmark", buttons, *this);
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(1, 1, 1, 1);
|
||||
@ -174,10 +173,11 @@ void BookmarkEditor::onColorButtonClicked(bool)
|
||||
QColorDialog colorDialog(palette.brush(QPalette::Background).color(), this);
|
||||
colorDialog.exec();
|
||||
|
||||
palette.setBrush(QPalette::Background, QBrush(colorDialog.currentColor()));
|
||||
auto color = colorDialog.currentColor();
|
||||
palette.setBrush(QPalette::Background, QBrush(color));
|
||||
m_colorButton->setPalette(palette);
|
||||
|
||||
m_colorButton->setStyleSheet(QString("background-color: %1;").arg(colorDialog.currentColor().name()));
|
||||
m_colorButton->setStyleSheet(QString("background-color: %1;").arg(color.name()));
|
||||
m_colorButton->style()->unpolish(m_colorButton);
|
||||
m_colorButton->style()->polish(m_colorButton);
|
||||
m_colorButton->update();
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains declaration of BookmarkEditor.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -96,13 +96,9 @@ struct EasyBlockItem Q_DECL_FINAL
|
||||
|
||||
}; // END of struct EasyBlockItem.
|
||||
|
||||
//#define EASY_TREE_WIDGET__USE_VECTOR
|
||||
struct EasyBlock Q_DECL_FINAL
|
||||
{
|
||||
::profiler::BlocksTree tree;
|
||||
#ifdef EASY_TREE_WIDGET__USE_VECTOR
|
||||
uint32_t tree_item;
|
||||
#endif
|
||||
uint32_t graphics_item_index;
|
||||
uint8_t graphics_item_level;
|
||||
uint8_t graphics_item;
|
||||
@ -112,9 +108,6 @@ struct EasyBlock Q_DECL_FINAL
|
||||
|
||||
EasyBlock(EasyBlock&& that) EASY_NOEXCEPT
|
||||
: tree(::std::move(that.tree))
|
||||
#ifdef EASY_TREE_WIDGET__USE_VECTOR
|
||||
, tree_item(that.tree_item)
|
||||
#endif
|
||||
, graphics_item_index(that.graphics_item_index)
|
||||
, graphics_item_level(that.graphics_item_level)
|
||||
, graphics_item(that.graphics_item)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -53,26 +53,31 @@
|
||||
* : limitations under the License.
|
||||
************************************************************************/
|
||||
|
||||
#include <QMenu>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
#include <QHeaderView>
|
||||
#include <QString>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
#include <QSignalBlocker>
|
||||
#include <QSettings>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QToolBar>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMenu>
|
||||
#include <QSettings>
|
||||
#include <QSignalBlocker>
|
||||
#include <QSplitter>
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QTextDocument>
|
||||
#include <QTimer>
|
||||
#include <QToolBar>
|
||||
#include <QVariant>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "descriptors_tree_widget.h"
|
||||
#include "arbitrary_value_inspector.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "arbitrary_value_inspector.h"
|
||||
#include "text_highlighter.h"
|
||||
#include "thread_pool.h"
|
||||
|
||||
#ifdef max
|
||||
@ -85,18 +90,6 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum DescColumns
|
||||
{
|
||||
DESC_COL_FILE_LINE = 0,
|
||||
DESC_COL_TYPE,
|
||||
DESC_COL_NAME,
|
||||
DESC_COL_STATUS,
|
||||
|
||||
DESC_COL_COLUMNS_NUMBER
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
::profiler::EasyBlockStatus nextStatus(::profiler::EasyBlockStatus _status)
|
||||
{
|
||||
switch (_status)
|
||||
@ -240,10 +233,15 @@ QVariant DescriptorsTreeItem::data(int _column, int _role) const
|
||||
DescriptorsTreeWidget::DescriptorsTreeWidget(QWidget* _parent)
|
||||
: Parent(_parent)
|
||||
, m_lastFound(nullptr)
|
||||
, m_lastFoundIndex(0)
|
||||
, m_lastSearchColumn(-1)
|
||||
, m_searchColumn(DESC_COL_NAME)
|
||||
, m_bLocked(false)
|
||||
, m_bCaseSensitiveSearch(false)
|
||||
, m_bInitialized(false)
|
||||
{
|
||||
memset(m_columnsMinimumWidth, 0, sizeof(m_columnsMinimumWidth));
|
||||
|
||||
setAutoFillBackground(false);
|
||||
setAlternatingRowColors(true);
|
||||
setItemsExpandable(true);
|
||||
@ -264,8 +262,11 @@ DescriptorsTreeWidget::DescriptorsTreeWidget(QWidget* _parent)
|
||||
connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
|
||||
connect(this, &Parent::itemDoubleClicked, this, &This::onDoubleClick);
|
||||
connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);
|
||||
connect(header(), &QHeaderView::sectionResized, this, &This::onHeaderSectionResized);
|
||||
|
||||
loadSettings();
|
||||
|
||||
setItemDelegateForColumn(m_searchColumn, new DescWidgetItemDelegate(this));
|
||||
}
|
||||
|
||||
DescriptorsTreeWidget::~DescriptorsTreeWidget()
|
||||
@ -279,11 +280,83 @@ DescriptorsTreeWidget::~DescriptorsTreeWidget()
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void DescriptorsTreeWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
Parent::showEvent(event);
|
||||
|
||||
if (!m_bInitialized)
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
const auto padding = px(9);
|
||||
#else
|
||||
const auto padding = px(6);
|
||||
#endif
|
||||
|
||||
auto header = this->header();
|
||||
auto headerItem = this->headerItem();
|
||||
|
||||
auto f = header->font();
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
f.setBold(true);
|
||||
#endif
|
||||
QFontMetrics fm(f);
|
||||
|
||||
const auto indicatorSize = header->isSortIndicatorShown() ? px(11) : 0;
|
||||
for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i)
|
||||
{
|
||||
auto minSize = static_cast<int>(fm.width(headerItem->text(i)) * profiler_gui::FONT_METRICS_FACTOR + padding);
|
||||
m_columnsMinimumWidth[i] = minSize;
|
||||
|
||||
if (header->isSortIndicatorShown() && header->sortIndicatorSection() == i)
|
||||
{
|
||||
minSize += indicatorSize;
|
||||
}
|
||||
|
||||
if (header->sectionSize(i) < minSize)
|
||||
{
|
||||
header->resizeSection(i, minSize);
|
||||
}
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DescriptorsTreeWidget::resetSearch(bool repaint)
|
||||
{
|
||||
if (m_lastSearch.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_lastSearchColumn = m_searchColumn;
|
||||
m_bCaseSensitiveSearch = false;
|
||||
m_lastSearch.clear();
|
||||
m_lastFound = nullptr;
|
||||
m_lastFoundIndex = 0;
|
||||
|
||||
if (repaint)
|
||||
{
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorsTreeWidget::setSearchColumn(int column)
|
||||
{
|
||||
const int prevColumn = m_searchColumn;
|
||||
m_searchColumn = column;
|
||||
|
||||
if (m_searchColumn != prevColumn)
|
||||
{
|
||||
auto delegate = itemDelegateForColumn(prevColumn);
|
||||
setItemDelegateForColumn(prevColumn, nullptr);
|
||||
delete delegate;
|
||||
|
||||
setItemDelegateForColumn(m_searchColumn, new DescWidgetItemDelegate(this));
|
||||
}
|
||||
|
||||
emit searchColumnChanged(column);
|
||||
}
|
||||
|
||||
@ -292,6 +365,26 @@ int DescriptorsTreeWidget::searchColumn() const
|
||||
return m_searchColumn;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* DescriptorsTreeWidget::lastFoundItem() const
|
||||
{
|
||||
return m_lastFound;
|
||||
}
|
||||
|
||||
bool DescriptorsTreeWidget::caseSensitiveSearch() const
|
||||
{
|
||||
return m_bCaseSensitiveSearch;
|
||||
}
|
||||
|
||||
const QString& DescriptorsTreeWidget::searchString() const
|
||||
{
|
||||
return m_lastSearch;
|
||||
}
|
||||
|
||||
int DescriptorsTreeWidget::lastFoundIndex() const
|
||||
{
|
||||
return m_lastFoundIndex;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DescriptorsTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
||||
@ -348,10 +441,8 @@ void DescriptorsTreeWidget::clearSilent(bool _global)
|
||||
const QSignalBlocker b(this);
|
||||
|
||||
setSortingEnabled(false);
|
||||
m_lastFound = nullptr;
|
||||
m_lastSearch.clear();
|
||||
resetSearch(false);
|
||||
|
||||
m_highlightItems.clear();
|
||||
m_items.clear();
|
||||
|
||||
if (topLevelItemCount() != 0)
|
||||
@ -464,7 +555,23 @@ void DescriptorsTreeWidget::build()
|
||||
setSortingEnabled(true);
|
||||
sortByColumn(DESC_COL_FILE_LINE, Qt::AscendingOrder);
|
||||
resizeColumnsToContents();
|
||||
QTimer::singleShot(100, [this](){ onSelectedBlockChange(EASY_GLOBALS.selected_block); });
|
||||
|
||||
QTimer::singleShot(100, [this] { onSelectedBlockChange(EASY_GLOBALS.selected_block); });
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DescriptorsTreeWidget::onHeaderSectionResized(int logicalIndex, int /*oldSize*/, int newSize)
|
||||
{
|
||||
const auto indicatorSize = header()->isSortIndicatorShown() && header()->sortIndicatorSection() == logicalIndex ? px(11) : 0;
|
||||
const auto minSize = m_columnsMinimumWidth[logicalIndex] + indicatorSize;
|
||||
|
||||
if (!m_bInitialized || newSize >= minSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
header()->resizeSection(logicalIndex, minSize);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -500,20 +607,8 @@ void DescriptorsTreeWidget::onDoubleClick(QTreeWidgetItem* _item, int _column)
|
||||
|
||||
void DescriptorsTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _prev)
|
||||
{
|
||||
if (_prev != nullptr)
|
||||
{
|
||||
auto f = font();
|
||||
for (int i = 0; i < DESC_COL_STATUS; ++i)
|
||||
_prev->setFont(i, f);
|
||||
}
|
||||
|
||||
if (_item != nullptr)
|
||||
{
|
||||
auto f = font();
|
||||
f.setBold(true);
|
||||
for (int i = 0; i < DESC_COL_STATUS; ++i)
|
||||
_item->setFont(i, f);
|
||||
|
||||
if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && _item->parent() != nullptr)
|
||||
{
|
||||
const auto id = static_cast<DescriptorsTreeItem*>(_item)->desc();
|
||||
@ -598,15 +693,6 @@ void DescriptorsTreeWidget::onSelectedBlockChange(uint32_t _block_index)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DescriptorsTreeWidget::resetHighlight()
|
||||
{
|
||||
for (auto item : m_highlightItems) {
|
||||
for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i)
|
||||
item->setBackground(i, Qt::NoBrush);
|
||||
}
|
||||
m_highlightItems.clear();
|
||||
}
|
||||
|
||||
void DescriptorsTreeWidget::loadSettings()
|
||||
{
|
||||
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
||||
@ -635,19 +721,20 @@ int DescriptorsTreeWidget::findNext(const QString& _str, Qt::MatchFlags _flags)
|
||||
{
|
||||
if (_str.isEmpty())
|
||||
{
|
||||
resetHighlight();
|
||||
m_lastSearchColumn = m_searchColumn;
|
||||
resetSearch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool isNewSearch = (m_lastSearchColumn != m_searchColumn || m_lastSearch != _str);
|
||||
auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, m_searchColumn);
|
||||
m_bCaseSensitiveSearch = _flags.testFlag(Qt::MatchCaseSensitive);
|
||||
|
||||
if (!isNewSearch)
|
||||
{
|
||||
if (!itemsList.empty())
|
||||
{
|
||||
bool stop = false;
|
||||
int i = 0;
|
||||
decltype(m_lastFound) next = nullptr;
|
||||
for (auto item : itemsList)
|
||||
{
|
||||
@ -658,29 +745,24 @@ int DescriptorsTreeWidget::findNext(const QString& _str, Qt::MatchFlags _flags)
|
||||
}
|
||||
|
||||
stop = item == m_lastFound;
|
||||
++i;
|
||||
}
|
||||
|
||||
m_lastFound = next == nullptr ? itemsList.front() : next;
|
||||
m_lastFoundIndex = next == nullptr ? 0 : i;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastFound = nullptr;
|
||||
m_lastFoundIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetHighlight();
|
||||
|
||||
m_lastSearchColumn = m_searchColumn;
|
||||
m_lastSearch = _str;
|
||||
m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr;
|
||||
|
||||
for (auto item : itemsList)
|
||||
{
|
||||
m_highlightItems.push_back(item);
|
||||
for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i)
|
||||
item->setBackgroundColor(i, QColor::fromRgba(0x80000000 | (0x00ffffff & ::profiler::colors::Yellow)));
|
||||
}
|
||||
m_lastFoundIndex = 0;
|
||||
}
|
||||
|
||||
if (m_lastFound != nullptr)
|
||||
@ -689,6 +771,8 @@ int DescriptorsTreeWidget::findNext(const QString& _str, Qt::MatchFlags _flags)
|
||||
setCurrentItem(m_lastFound);
|
||||
}
|
||||
|
||||
viewport()->update();
|
||||
|
||||
return itemsList.size();
|
||||
}
|
||||
|
||||
@ -696,48 +780,54 @@ int DescriptorsTreeWidget::findPrev(const QString& _str, Qt::MatchFlags _flags)
|
||||
{
|
||||
if (_str.isEmpty())
|
||||
{
|
||||
resetHighlight();
|
||||
m_lastSearchColumn = m_searchColumn;
|
||||
resetSearch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool isNewSearch = (m_lastSearchColumn != m_searchColumn || m_lastSearch != _str);
|
||||
auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, m_searchColumn);
|
||||
m_bCaseSensitiveSearch = _flags.testFlag(Qt::MatchCaseSensitive);
|
||||
|
||||
if (!isNewSearch)
|
||||
{
|
||||
if (!itemsList.empty())
|
||||
{
|
||||
int i = 0;
|
||||
decltype(m_lastFound) prev = nullptr;
|
||||
for (auto item : itemsList)
|
||||
{
|
||||
if (item == m_lastFound)
|
||||
{
|
||||
--i;
|
||||
break;
|
||||
}
|
||||
|
||||
prev = item;
|
||||
++i;
|
||||
}
|
||||
|
||||
m_lastFound = prev == nullptr ? itemsList.back() : prev;
|
||||
m_lastFoundIndex = prev == nullptr ? itemsList.length() - 1 : i;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastFound = nullptr;
|
||||
m_lastFoundIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetHighlight();
|
||||
|
||||
m_lastSearchColumn = m_searchColumn;
|
||||
m_lastSearch = _str;
|
||||
m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr;
|
||||
|
||||
m_highlightItems.reserve(itemsList.size());
|
||||
for (auto item : itemsList)
|
||||
if (!itemsList.empty())
|
||||
{
|
||||
m_highlightItems.push_back(item);
|
||||
for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i)
|
||||
item->setBackgroundColor(i, QColor::fromRgba(0x80000000 | (0x00ffffff & ::profiler::colors::Yellow)));
|
||||
m_lastFound = itemsList.back();
|
||||
m_lastFoundIndex = itemsList.length() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastFound = nullptr;
|
||||
m_lastFoundIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,6 +837,8 @@ int DescriptorsTreeWidget::findPrev(const QString& _str, Qt::MatchFlags _flags)
|
||||
setCurrentItem(m_lastFound);
|
||||
}
|
||||
|
||||
viewport()->update();
|
||||
|
||||
return itemsList.size();
|
||||
}
|
||||
|
||||
@ -757,7 +849,7 @@ BlockDescriptorsWidget::BlockDescriptorsWidget(QWidget* _parent) : Parent(_paren
|
||||
, m_tree(new DescriptorsTreeWidget(this))
|
||||
, m_values(new ArbitraryValuesWidget(this))
|
||||
, m_searchBox(new QLineEdit(this))
|
||||
, m_foundNumber(new QLabel("0 matches", this))
|
||||
, m_foundNumber(new QLabel(QStringLiteral("<font color=\"red\">0</font> matches"), this))
|
||||
, m_searchButton(nullptr)
|
||||
, m_bCaseSensitiveSearch(false)
|
||||
{
|
||||
@ -897,12 +989,24 @@ void BlockDescriptorsWidget::saveSettings()
|
||||
|
||||
void BlockDescriptorsWidget::keyPressEvent(QKeyEvent* _event)
|
||||
{
|
||||
if (_event->key() == Qt::Key_F3)
|
||||
switch (_event->key())
|
||||
{
|
||||
if (_event->modifiers() & Qt::ShiftModifier)
|
||||
findPrev(true);
|
||||
else
|
||||
findNext(true);
|
||||
case Qt::Key_F3:
|
||||
{
|
||||
if (_event->modifiers() & Qt::ShiftModifier)
|
||||
findPrev(true);
|
||||
else
|
||||
findNext(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Escape:
|
||||
{
|
||||
m_searchBox->clear();
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
_event->accept();
|
||||
@ -922,7 +1026,7 @@ void BlockDescriptorsWidget::showEvent(QShowEvent* event)
|
||||
void BlockDescriptorsWidget::build()
|
||||
{
|
||||
m_tree->clearSilent(false);
|
||||
m_foundNumber->setText(QString("0 matches"));
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"red\">0</font> matches"));
|
||||
m_foundNumber->hide();
|
||||
m_tree->build();
|
||||
m_values->rebuild();
|
||||
@ -931,7 +1035,7 @@ void BlockDescriptorsWidget::build()
|
||||
void BlockDescriptorsWidget::clear()
|
||||
{
|
||||
m_tree->clearSilent(true);
|
||||
m_foundNumber->setText(QString("0 matches"));
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"red\">0</font> matches"));
|
||||
m_foundNumber->hide();
|
||||
m_values->clear();
|
||||
}
|
||||
@ -943,7 +1047,7 @@ ArbitraryValuesWidget* BlockDescriptorsWidget::dataViewer() const
|
||||
|
||||
void BlockDescriptorsWidget::onSeachBoxReturnPressed()
|
||||
{
|
||||
if (m_searchButton->data().toBool() == true)
|
||||
if (m_searchButton->data().toBool())
|
||||
findNext(true);
|
||||
else
|
||||
findPrev(true);
|
||||
@ -952,7 +1056,10 @@ void BlockDescriptorsWidget::onSeachBoxReturnPressed()
|
||||
void BlockDescriptorsWidget::onSearchBoxTextChanged(const QString& _text)
|
||||
{
|
||||
if (_text.isEmpty())
|
||||
{
|
||||
m_foundNumber->hide();
|
||||
m_tree->resetSearch();
|
||||
}
|
||||
}
|
||||
|
||||
void BlockDescriptorsWidget::onSearchColumnChanged(int column)
|
||||
@ -989,15 +1096,27 @@ void BlockDescriptorsWidget::findNext(bool)
|
||||
{
|
||||
if (m_foundNumber->isVisible())
|
||||
m_foundNumber->hide();
|
||||
m_tree->resetSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
auto matches = m_tree->findNext(text, m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags());
|
||||
|
||||
if (matches == 1)
|
||||
m_foundNumber->setText(QString("1 match"));
|
||||
if (matches == 0)
|
||||
{
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"red\">0</font> matches"));
|
||||
}
|
||||
else if (matches == 1)
|
||||
{
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"#f5f5f5\" style=\"background:#e040fb\"> 1 </font> match"));
|
||||
}
|
||||
else
|
||||
m_foundNumber->setText(QString("%1 matches").arg(matches));
|
||||
{
|
||||
auto i = m_tree->lastFoundIndex() + 1;
|
||||
m_foundNumber->setText(QString("<font color=\"#f5f5f5\" style=\"background:#e040fb\"> %1 </font> of "
|
||||
"<font style=\"background:#ffeb3b\"> %2 </font> matches")
|
||||
.arg(i).arg(matches));
|
||||
}
|
||||
|
||||
if (!m_foundNumber->isVisible())
|
||||
m_foundNumber->show();
|
||||
@ -1010,15 +1129,27 @@ void BlockDescriptorsWidget::findPrev(bool)
|
||||
{
|
||||
if (m_foundNumber->isVisible())
|
||||
m_foundNumber->hide();
|
||||
m_tree->resetSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
auto matches = m_tree->findPrev(text, m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags());
|
||||
|
||||
if (matches == 1)
|
||||
m_foundNumber->setText(QString("1 match"));
|
||||
if (matches == 0)
|
||||
{
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"red\">0</font> matches"));
|
||||
}
|
||||
else if (matches == 1)
|
||||
{
|
||||
m_foundNumber->setText(QStringLiteral("<font color=\"#f5f5f5\" style=\"background:#e040fb\"> 1 </font> match"));
|
||||
}
|
||||
else
|
||||
m_foundNumber->setText(QString("%1 matches").arg(matches));
|
||||
{
|
||||
auto i = m_tree->lastFoundIndex() + 1;
|
||||
m_foundNumber->setText(QString("<font color=\"#f5f5f5\" style=\"background:#e040fb\"> %1 </font> of "
|
||||
"<font style=\"background:#ffeb3b\"> %2 </font> matches")
|
||||
.arg(i).arg(matches));
|
||||
}
|
||||
|
||||
if (!m_foundNumber->isVisible())
|
||||
m_foundNumber->show();
|
||||
@ -1029,7 +1160,7 @@ void BlockDescriptorsWidget::findNextFromMenu(bool _checked)
|
||||
if (!_checked)
|
||||
return;
|
||||
|
||||
if (m_searchButton->data().toBool() == false)
|
||||
if (!m_searchButton->data().toBool())
|
||||
{
|
||||
m_searchButton->setData(true);
|
||||
m_searchButton->setText(tr("Find next"));
|
||||
@ -1046,7 +1177,7 @@ void BlockDescriptorsWidget::findPrevFromMenu(bool _checked)
|
||||
if (!_checked)
|
||||
return;
|
||||
|
||||
if (m_searchButton->data().toBool() == true)
|
||||
if (m_searchButton->data().toBool())
|
||||
{
|
||||
m_searchButton->setData(false);
|
||||
m_searchButton->setText(tr("Find prev"));
|
||||
@ -1059,3 +1190,103 @@ void BlockDescriptorsWidget::findPrevFromMenu(bool _checked)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DescWidgetItemDelegate::DescWidgetItemDelegate(DescriptorsTreeWidget* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_treeWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DescWidgetItemDelegate::~DescWidgetItemDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DescWidgetItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
highlightMatchingText(painter, option, index);
|
||||
}
|
||||
|
||||
void DescWidgetItemDelegate::highlightMatchingText(
|
||||
QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index
|
||||
) const {
|
||||
if (m_treeWidget->lastFoundItem() != nullptr && !m_treeWidget->searchString().isEmpty())
|
||||
{
|
||||
// Highlight matching word
|
||||
auto displayData = m_treeWidget->model()->data(index);
|
||||
if (displayData.canConvert<QString>())
|
||||
{
|
||||
const auto text = displayData.toString();
|
||||
const auto caseSensitivity = m_treeWidget->caseSensitiveSearch() ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||
if (text.contains(m_treeWidget->searchString(), caseSensitivity))
|
||||
{
|
||||
auto lastFoundIndex = m_treeWidget->indexFromItem(m_treeWidget->lastFoundItem(), index.column());
|
||||
highlightMatchingText(
|
||||
painter,
|
||||
option,
|
||||
text,
|
||||
m_treeWidget->searchString(),
|
||||
caseSensitivity,
|
||||
lastFoundIndex == index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DescWidgetItemDelegate::highlightMatchingText(
|
||||
QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QString& text,
|
||||
const QString& pattern,
|
||||
Qt::CaseSensitivity caseSensitivity,
|
||||
bool current
|
||||
) const {
|
||||
const auto str = pattern.toStdString();
|
||||
(void)str;
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setDefaultFont(painter->font());
|
||||
doc.setTextWidth(option.rect.width());
|
||||
|
||||
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, std::max(option.rect.width(), 0));
|
||||
doc.setHtml(elidedText);
|
||||
|
||||
TextHighlighter highlighter(
|
||||
&doc,
|
||||
painter->pen().color(),
|
||||
QColor::fromRgb(profiler::colors::Grey100),
|
||||
pattern,
|
||||
caseSensitivity,
|
||||
current
|
||||
);
|
||||
|
||||
painter->save();
|
||||
|
||||
#ifdef _WIN32
|
||||
EASY_CONSTEXPR int fixed_padding_x = -1;
|
||||
EASY_CONSTEXPR int fixed_padding_y = 0;
|
||||
#else
|
||||
EASY_CONSTEXPR int fixed_padding_x = -1;
|
||||
EASY_CONSTEXPR int fixed_padding_y = -1;
|
||||
#endif
|
||||
|
||||
auto dh = std::max((option.rect.height() - doc.size().height()) * 0.5, 0.);
|
||||
painter->translate(option.rect.left() + fixed_padding_x, option.rect.top() + dh + fixed_padding_y);
|
||||
|
||||
QRect clip(0, 0, option.rect.width(), option.rect.height());
|
||||
painter->setClipRect(clip);
|
||||
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
ctx.clip = clip;
|
||||
ctx.palette.setColor(QPalette::Text, Qt::transparent);
|
||||
doc.documentLayout()->draw(painter, ctx);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -67,6 +67,18 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum DescColumns
|
||||
{
|
||||
DESC_COL_FILE_LINE = 0,
|
||||
DESC_COL_TYPE,
|
||||
DESC_COL_NAME,
|
||||
DESC_COL_STATUS,
|
||||
|
||||
DESC_COL_COLUMNS_NUMBER
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DescriptorsTreeItem : public QTreeWidgetItem
|
||||
{
|
||||
using Parent = QTreeWidgetItem;
|
||||
@ -121,19 +133,21 @@ class DescriptorsTreeWidget : public QTreeWidget
|
||||
using This = DescriptorsTreeWidget;
|
||||
|
||||
using Items = ::std::vector<DescriptorsTreeItem*>;
|
||||
using TreeItems = ::std::vector<QTreeWidgetItem*>;
|
||||
using ExpandedFiles = ::std::unordered_set<::std::string>;
|
||||
|
||||
protected:
|
||||
|
||||
ExpandedFiles m_expandedFilesTemp;
|
||||
Items m_items;
|
||||
TreeItems m_highlightItems;
|
||||
QString m_lastSearch;
|
||||
QTreeWidgetItem* m_lastFound;
|
||||
int m_columnsMinimumWidth[DESC_COL_COLUMNS_NUMBER];
|
||||
int m_lastFoundIndex;
|
||||
int m_lastSearchColumn;
|
||||
int m_searchColumn;
|
||||
bool m_bLocked;
|
||||
bool m_bCaseSensitiveSearch;
|
||||
bool m_bInitialized;
|
||||
|
||||
public:
|
||||
|
||||
@ -141,17 +155,29 @@ public:
|
||||
|
||||
explicit DescriptorsTreeWidget(QWidget* _parent = nullptr);
|
||||
~DescriptorsTreeWidget() override;
|
||||
|
||||
void contextMenuEvent(QContextMenuEvent* _event) override;
|
||||
void showEvent(class QShowEvent* event) override;
|
||||
|
||||
public:
|
||||
|
||||
using Parent::indexFromItem;
|
||||
|
||||
// Public non-virtual methods
|
||||
|
||||
int findNext(const QString& _str, Qt::MatchFlags _flags);
|
||||
int findPrev(const QString& _str, Qt::MatchFlags _flags);
|
||||
|
||||
void resetSearch(bool repaint = true);
|
||||
|
||||
void setSearchColumn(int column);
|
||||
int searchColumn() const;
|
||||
|
||||
QTreeWidgetItem* lastFoundItem() const;
|
||||
const QString& searchString() const;
|
||||
bool caseSensitiveSearch() const;
|
||||
int lastFoundIndex() const;
|
||||
|
||||
signals:
|
||||
|
||||
void searchColumnChanged(int column);
|
||||
@ -163,6 +189,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
|
||||
void onHeaderSectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
void onBlockStatusChangeClicked(bool);
|
||||
void onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _prev);
|
||||
void onItemExpand(QTreeWidgetItem* _item);
|
||||
@ -175,7 +202,6 @@ private:
|
||||
|
||||
// Private methods
|
||||
|
||||
void resetHighlight();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
@ -243,6 +269,35 @@ private:
|
||||
|
||||
}; // END of class BlockDescriptorsWidget.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DescWidgetItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
DescriptorsTreeWidget* m_treeWidget;
|
||||
|
||||
public:
|
||||
|
||||
explicit DescWidgetItemDelegate(DescriptorsTreeWidget* parent = nullptr);
|
||||
~DescWidgetItemDelegate() override;
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
|
||||
private:
|
||||
|
||||
void highlightMatchingText(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
void highlightMatchingText(
|
||||
QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QString& text,
|
||||
const QString& pattern,
|
||||
Qt::CaseSensitivity caseSensitivity,
|
||||
bool current
|
||||
) const;
|
||||
|
||||
}; // END of class DescWidgetItemDelegate.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // EASY_DESCRIPTORS_WIDGET_H
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of Dialog.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -75,7 +75,7 @@ Dialog::Dialog(QWidget* parent, const QString& title, QWidget* content, WindowHe
|
||||
{
|
||||
setSizeGripEnabled(EASY_GLOBALS.use_custom_window_header);
|
||||
|
||||
m_header = new WindowHeader(title, headerButtons, this);
|
||||
m_header = new WindowHeader(title, headerButtons, *this);
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(1, 1, 1, 1);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : for all dialogs in the application.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -268,11 +268,12 @@ FpsWidget::FpsWidget(QWidget* _parent) : Parent(_parent), m_fpsItem(nullptr)
|
||||
centerOn(0, 0);
|
||||
|
||||
// Dirty hack for QDockWidget stupid initial size policy :(
|
||||
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
||||
setFixedHeight(10); // Set very small height to enable appropriate minimum height on the application startup
|
||||
QTimer::singleShot(100, [this]
|
||||
{
|
||||
// Now set appropriate minimum height
|
||||
setMinimumHeight((QFontMetrics(scene()->font()).height() + 3) * 6);
|
||||
setMinimumHeight((QFontMetrics(scene()->font()).height() + px(3)) * 3);
|
||||
setMaximumHeight(minimumHeight() * 20);
|
||||
});
|
||||
}
|
||||
@ -294,6 +295,16 @@ void FpsWidget::addPoint(uint32_t _maxFrameTime, uint32_t _avgFrameTime)
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
QSize FpsWidget::sizeHint() const
|
||||
{
|
||||
return QSize(Parent::sizeHint().width(), minimumHeight());
|
||||
}
|
||||
|
||||
QSize FpsWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(Parent::minimumSizeHint().width(), minimumHeight());
|
||||
}
|
||||
|
||||
void FpsWidget::resizeEvent(QResizeEvent* _event)
|
||||
{
|
||||
Parent::resizeEvent(_event);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -109,6 +109,8 @@ public:
|
||||
explicit FpsWidget(QWidget* _parent = nullptr);
|
||||
~FpsWidget() override;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
void resizeEvent(QResizeEvent* _event) override;
|
||||
void hideEvent(QHideEvent* _event) override;
|
||||
void showEvent(QShowEvent* _event) override;
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -59,69 +59,69 @@
|
||||
|
||||
namespace profiler_gui {
|
||||
|
||||
Globals& Globals::instance()
|
||||
{
|
||||
// It's okay even without C++11 "magic statics" feature because first call happens
|
||||
// on application initialization - there is only one thread and no data races occur.
|
||||
static Globals globals;
|
||||
return globals;
|
||||
}
|
||||
Globals& Globals::instance()
|
||||
{
|
||||
// It's okay even without C++11 "magic statics" feature because first call happens
|
||||
// on application initialization - there is only one thread and no data races occur.
|
||||
static Globals globals;
|
||||
return globals;
|
||||
}
|
||||
|
||||
Globals::Fonts::Fonts()
|
||||
: default_font(::profiler_gui::EFont("DejaVu Sans", 13))
|
||||
, background(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Bold))
|
||||
, ruler(::profiler_gui::EFont("DejaVu Sans", 16, QFont::Bold))
|
||||
, item(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Medium))
|
||||
, selected_item(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Medium))
|
||||
{
|
||||
Globals::Fonts::Fonts()
|
||||
: default_font(::profiler_gui::EFont("DejaVu Sans", 13))
|
||||
, background(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Bold))
|
||||
, ruler(::profiler_gui::EFont("DejaVu Sans", 16, QFont::Bold))
|
||||
, item(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Medium))
|
||||
, selected_item(::profiler_gui::EFont("DejaVu Sans", 13, QFont::Medium))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Globals::Globals()
|
||||
: theme("default")
|
||||
, pid(0)
|
||||
, begin_time(0)
|
||||
, selected_thread(0U)
|
||||
, selected_block(::profiler_gui::numeric_max<decltype(selected_block)>())
|
||||
, selected_block_id(::profiler_gui::numeric_max<decltype(selected_block_id)>())
|
||||
, version(0)
|
||||
, frame_time(16700)
|
||||
, blocks_spacing(0)
|
||||
, blocks_size_min(2)
|
||||
, blocks_narrow_size(20)
|
||||
, max_fps_history(90)
|
||||
, fps_timer_interval(500)
|
||||
, fps_widget_line_width(2)
|
||||
, bookmark_default_color(0)
|
||||
, chrono_text_position(RulerTextPosition_Top)
|
||||
, time_units(TimeUnits_ms)
|
||||
, connected(false)
|
||||
, has_local_changes(false)
|
||||
, use_custom_window_header(true)
|
||||
, is_right_window_header_controls(true)
|
||||
, fps_enabled(true)
|
||||
, use_decorated_thread_name(false)
|
||||
, hex_thread_id(false)
|
||||
, enable_event_markers(true)
|
||||
, enable_statistics(true)
|
||||
, enable_zero_length(true)
|
||||
, add_zero_blocks_to_hierarchy(false)
|
||||
, draw_graphics_items_borders(true)
|
||||
, hide_narrow_children(false)
|
||||
, hide_minsize_blocks(false)
|
||||
, display_only_relevant_stats(true)
|
||||
, collapse_items_on_tree_close(false)
|
||||
, all_items_expanded_by_default(true)
|
||||
, only_current_thread_hierarchy(false)
|
||||
, highlight_blocks_with_same_id(true)
|
||||
, selecting_block_changes_thread(true)
|
||||
, auto_adjust_histogram_height(true)
|
||||
, auto_adjust_chart_height(false)
|
||||
, display_only_frames_on_histogram(false)
|
||||
, bind_scene_and_tree_expand_status(true)
|
||||
{
|
||||
Globals::Globals()
|
||||
: theme("default")
|
||||
, pid(0)
|
||||
, begin_time(0)
|
||||
, selected_thread(0U)
|
||||
, selected_block(::profiler_gui::numeric_max<decltype(selected_block)>())
|
||||
, selected_block_id(::profiler_gui::numeric_max<decltype(selected_block_id)>())
|
||||
, version(0)
|
||||
, frame_time(16700)
|
||||
, blocks_spacing(0)
|
||||
, blocks_size_min(2)
|
||||
, blocks_narrow_size(20)
|
||||
, max_fps_history(90)
|
||||
, fps_timer_interval(500)
|
||||
, fps_widget_line_width(2)
|
||||
, bookmark_default_color(0)
|
||||
, chrono_text_position(RulerTextPosition_Top)
|
||||
, time_units(TimeUnits_ms)
|
||||
, connected(false)
|
||||
, has_local_changes(false)
|
||||
, use_custom_window_header(true)
|
||||
, is_right_window_header_controls(true)
|
||||
, fps_enabled(true)
|
||||
, use_decorated_thread_name(false)
|
||||
, hex_thread_id(false)
|
||||
, enable_event_markers(true)
|
||||
, enable_statistics(true)
|
||||
, enable_zero_length(true)
|
||||
, add_zero_blocks_to_hierarchy(false)
|
||||
, draw_graphics_items_borders(true)
|
||||
, hide_narrow_children(false)
|
||||
, hide_minsize_blocks(false)
|
||||
, display_only_relevant_stats(false)
|
||||
, collapse_items_on_tree_close(false)
|
||||
, all_items_expanded_by_default(true)
|
||||
, only_current_thread_hierarchy(false)
|
||||
, highlight_blocks_with_same_id(true)
|
||||
, selecting_block_changes_thread(true)
|
||||
, auto_adjust_histogram_height(true)
|
||||
, auto_adjust_chart_height(false)
|
||||
, display_only_frames_on_histogram(false)
|
||||
, bind_scene_and_tree_expand_status(true)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // END of namespace profiler_gui.
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -273,38 +273,38 @@ inline profiler::SerializedBlockDescriptor& easyDescriptor(profiler::block_id_t
|
||||
return *EASY_GLOBALS.descriptors[i];
|
||||
}
|
||||
|
||||
inline profiler::SerializedBlockDescriptor& easyDescriptor(const profiler::BlocksTree& _block) {
|
||||
return easyDescriptor(_block.node->id());
|
||||
inline profiler::SerializedBlockDescriptor& easyDescriptor(const profiler::BlocksTree& block) {
|
||||
return easyDescriptor(block.node->id());
|
||||
}
|
||||
|
||||
EASY_FORCE_INLINE const profiler::BlocksTree& easyBlocksTree(profiler::block_index_t i) {
|
||||
return easyBlock(i).tree;
|
||||
}
|
||||
|
||||
EASY_FORCE_INLINE const char* easyBlockName(const profiler::BlocksTree& _block) {
|
||||
const char* name = _block.node->name();
|
||||
return *name != 0 ? name : easyDescriptor(_block.node->id()).name();
|
||||
EASY_FORCE_INLINE const char* easyBlockName(const profiler::BlocksTree& block) {
|
||||
const char* name = block.node->name();
|
||||
return *name != 0 ? name : easyDescriptor(block.node->id()).name();
|
||||
}
|
||||
|
||||
EASY_FORCE_INLINE const char* easyBlockName(const profiler::BlocksTree& _block, const profiler::SerializedBlockDescriptor& _desc) {
|
||||
const char* name = _block.node->name();
|
||||
return *name != 0 ? name : _desc.name();
|
||||
EASY_FORCE_INLINE const char* easyBlockName(const profiler::BlocksTree& block, const profiler::SerializedBlockDescriptor& desc) {
|
||||
const char* name = block.node->name();
|
||||
return *name != 0 ? name : desc.name();
|
||||
}
|
||||
|
||||
EASY_FORCE_INLINE const char* easyBlockName(profiler::block_index_t i) {
|
||||
return easyBlockName(easyBlock(i).tree);
|
||||
}
|
||||
|
||||
inline qreal sceneX(profiler::timestamp_t _time) {
|
||||
return PROF_MICROSECONDS(qreal(_time - EASY_GLOBALS.begin_time));
|
||||
inline qreal sceneX(profiler::timestamp_t time) {
|
||||
return PROF_MICROSECONDS(qreal(time - EASY_GLOBALS.begin_time));
|
||||
}
|
||||
|
||||
inline QString imagePath(const QString& _resource) {
|
||||
return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(_resource);
|
||||
inline QString imagePath(const QString& resource_name) {
|
||||
return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(resource_name);
|
||||
}
|
||||
|
||||
inline QString imagePath(const char* _resource) {
|
||||
return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(_resource);
|
||||
inline QString imagePath(const char* resource_name) {
|
||||
return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(resource_name);
|
||||
}
|
||||
|
||||
inline QSize applicationIconsSize() {
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of GraphicsBlockItem.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -1146,7 +1146,7 @@ void GraphicsBlockItem::getBlocks(qreal _left, qreal _right, ::profiler_gui::Tre
|
||||
size_t itemIndex = 0;
|
||||
if (first != level0.end())
|
||||
{
|
||||
itemIndex = first - level0.begin();
|
||||
itemIndex = static_cast<size_t>(std::distance(level0.begin(), first));
|
||||
if (itemIndex > 0)
|
||||
itemIndex -= 1;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : used to draw profiler blocks on graphics scene.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of GraphicsImageItem.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -70,6 +70,7 @@ GraphicsImageItem::GraphicsImageItem() : Parent(nullptr)
|
||||
, m_maxValue(0)
|
||||
, m_minValue(0)
|
||||
, m_timer(::std::bind(&This::onTimeout, this))
|
||||
, m_bEmpty(true)
|
||||
, m_bPermitImageUpdate(true)
|
||||
{
|
||||
m_bReady = false;
|
||||
@ -97,6 +98,16 @@ void GraphicsImageItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h)
|
||||
m_boundingRect.setRect(x, y, w, h);
|
||||
}
|
||||
|
||||
bool GraphicsImageItem::isEmpty() const
|
||||
{
|
||||
return m_bEmpty;
|
||||
}
|
||||
|
||||
void GraphicsImageItem::setEmpty(bool empty)
|
||||
{
|
||||
m_bEmpty = empty;
|
||||
}
|
||||
|
||||
void GraphicsImageItem::setMousePos(const QPointF& pos)
|
||||
{
|
||||
m_mousePos = pos;
|
||||
@ -173,6 +184,11 @@ bool GraphicsImageItem::cancelImageUpdate()
|
||||
|
||||
bool GraphicsImageItem::pickTopValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto y = m_mousePos.y();
|
||||
if (isImageUpdatePermitted() && m_boundingRect.top() < y && y < m_boundingRect.bottom())
|
||||
{
|
||||
@ -187,6 +203,11 @@ bool GraphicsImageItem::pickTopValue()
|
||||
|
||||
bool GraphicsImageItem::increaseTopValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isImageUpdatePermitted() && m_topValue < m_maxValue)
|
||||
{
|
||||
auto step = 0.05 * (m_maxValue - m_bottomValue);
|
||||
@ -202,6 +223,11 @@ bool GraphicsImageItem::increaseTopValue()
|
||||
|
||||
bool GraphicsImageItem::decreaseTopValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isImageUpdatePermitted() && m_topValue > m_bottomValue)
|
||||
{
|
||||
auto step = 0.05 * (m_maxValue - m_bottomValue);
|
||||
@ -221,6 +247,11 @@ bool GraphicsImageItem::decreaseTopValue()
|
||||
|
||||
bool GraphicsImageItem::pickBottomValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto y = m_mousePos.y();
|
||||
if (isImageUpdatePermitted() && m_boundingRect.top() < y && y < m_boundingRect.bottom())
|
||||
{
|
||||
@ -235,6 +266,11 @@ bool GraphicsImageItem::pickBottomValue()
|
||||
|
||||
bool GraphicsImageItem::increaseBottomValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isImageUpdatePermitted() && m_bottomValue < m_topValue)
|
||||
{
|
||||
auto step = 0.05 * (m_topValue - m_minValue);
|
||||
@ -254,6 +290,11 @@ bool GraphicsImageItem::increaseBottomValue()
|
||||
|
||||
bool GraphicsImageItem::decreaseBottomValue()
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isImageUpdatePermitted() && m_bottomValue > m_minValue)
|
||||
{
|
||||
auto step = 0.05 * (m_topValue - m_minValue);
|
||||
@ -270,7 +311,7 @@ bool GraphicsImageItem::decreaseBottomValue()
|
||||
void GraphicsImageItem::paintImage(QPainter* _painter)
|
||||
{
|
||||
_painter->setPen(Qt::NoPen);
|
||||
_painter->drawImage(0, m_boundingRect.top(), m_image);
|
||||
_painter->drawImage(0, static_cast<int>(m_boundingRect.top()), m_image);
|
||||
}
|
||||
|
||||
void GraphicsImageItem::paintImage(QPainter* _painter, qreal _scale, qreal _sceneLeft, qreal _sceneRight,
|
||||
|
@ -9,7 +9,7 @@
|
||||
* : used to display, scroll and zoom QImage on graphics scene.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -80,11 +80,12 @@ protected:
|
||||
qreal m_bottomValue;
|
||||
qreal m_maxValue;
|
||||
qreal m_minValue;
|
||||
bool m_bEmpty;
|
||||
std::atomic_bool m_bReady;
|
||||
|
||||
private:
|
||||
|
||||
Timer m_timer;
|
||||
Timer m_timer;
|
||||
bool m_bPermitImageUpdate; ///< Is false when m_workerThread is parsing input dataset (when setSource(_block_id) is called)
|
||||
|
||||
public:
|
||||
@ -111,6 +112,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
bool isEmpty() const;
|
||||
void onValueChanged();
|
||||
void setMousePos(const QPointF& pos);
|
||||
void setMousePos(qreal x, qreal y);
|
||||
@ -120,6 +122,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void setEmpty(bool empty);
|
||||
void paintImage(QPainter* _painter);
|
||||
void paintImage(QPainter* _painter, qreal _scale, qreal _sceneLeft, qreal _sceneRight,
|
||||
qreal _visibleRegionLeft, qreal _visibleRegionWidth);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -72,16 +72,17 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GraphicsRulerItem::GraphicsRulerItem(bool _main)
|
||||
GraphicsRulerItem::GraphicsRulerItem(bool main)
|
||||
: Parent()
|
||||
, m_color(profiler_gui::RULER_COLOR)
|
||||
, m_left(0)
|
||||
, m_right(0)
|
||||
, m_bMain(_main)
|
||||
, m_bReverse(false)
|
||||
, m_bHoverIndicator(false)
|
||||
, m_bHoverLeftBorder(false)
|
||||
, m_bHoverRightBorder(false)
|
||||
, m_main(main)
|
||||
, m_reverse(false)
|
||||
, m_strict(false)
|
||||
, m_hover_on_indicator(false)
|
||||
, m_hover_on_left_border(false)
|
||||
, m_hover_on_right_border(false)
|
||||
{
|
||||
m_indicator.reserve(3);
|
||||
}
|
||||
@ -92,10 +93,10 @@ GraphicsRulerItem::~GraphicsRulerItem()
|
||||
|
||||
QRectF GraphicsRulerItem::boundingRect() const
|
||||
{
|
||||
return m_boundingRect;
|
||||
return m_bounding_rect;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*)
|
||||
void GraphicsRulerItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
|
||||
{
|
||||
auto const sceneView = view();
|
||||
const auto currentScale = sceneView->scale();
|
||||
@ -103,19 +104,19 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
const auto visibleSceneRect = sceneView->visibleSceneRect();
|
||||
auto sceneLeft = offset, sceneRight = offset + visibleSceneRect.width() / currentScale;
|
||||
|
||||
if (m_bMain)
|
||||
if (m_main)
|
||||
m_indicator.clear();
|
||||
|
||||
if (m_left > sceneRight || m_right < sceneLeft)
|
||||
{
|
||||
// This item is out of screen
|
||||
|
||||
if (m_bMain)
|
||||
if (m_main)
|
||||
{
|
||||
const int size = m_bHoverIndicator ? 12 : 10;
|
||||
const int size = m_hover_on_indicator ? 12 : 10;
|
||||
auto vcenter = visibleSceneRect.top() + visibleSceneRect.height() * 0.5;
|
||||
auto color = QColor::fromRgb(m_color.rgb());
|
||||
auto pen = _painter->pen();
|
||||
auto pen = painter->pen();
|
||||
pen.setColor(color);
|
||||
|
||||
m_indicator.clear();
|
||||
@ -134,19 +135,24 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
m_indicator.push_back(QPointF(sceneLeft + size, vcenter + size));
|
||||
}
|
||||
|
||||
_painter->save();
|
||||
_painter->setTransform(QTransform::fromTranslate(-x(), -y()), true);
|
||||
_painter->setBrush(m_bHoverIndicator ? QColor::fromRgb(0xffff0000) : color);
|
||||
_painter->setPen(pen);
|
||||
_painter->drawPolygon(m_indicator);
|
||||
_painter->restore();
|
||||
painter->save();
|
||||
painter->setTransform(QTransform::fromTranslate(-x(), -y()), true);
|
||||
painter->setBrush(m_hover_on_indicator ? QColor::fromRgb(0xffff0000) : color);
|
||||
painter->setPen(pen);
|
||||
painter->drawPolygon(m_indicator);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto selectedInterval = width();
|
||||
QRectF rect((m_left - offset) * currentScale, visibleSceneRect.top(), ::std::max(selectedInterval * currentScale, 1.0), visibleSceneRect.height());
|
||||
QRectF rect(
|
||||
(m_left - offset) * currentScale,
|
||||
visibleSceneRect.top(),
|
||||
::std::max(selectedInterval * currentScale, 1.0),
|
||||
visibleSceneRect.height()
|
||||
);
|
||||
selectedInterval = units2microseconds(selectedInterval);
|
||||
|
||||
const QString text = profiler_gui::timeStringReal(EASY_GLOBALS.time_units, selectedInterval); // Displayed text
|
||||
@ -156,10 +162,10 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
|
||||
|
||||
// Paint!--------------------------
|
||||
_painter->save();
|
||||
painter->save();
|
||||
|
||||
// instead of scrollbar we're using manual offset
|
||||
_painter->setTransform(QTransform::fromTranslate(-x(), -y()), true);
|
||||
painter->setTransform(QTransform::fromTranslate(-x(), -y()), true);
|
||||
|
||||
if (m_left < sceneLeft)
|
||||
rect.setLeft(0);
|
||||
@ -174,87 +180,87 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
g.setColorAt(0.2, QColor::fromRgba(0x14000000 | rgb));
|
||||
g.setColorAt(0.8, QColor::fromRgba(0x14000000 | rgb));
|
||||
g.setColorAt(1, m_color);
|
||||
_painter->setBrush(g);
|
||||
_painter->setPen(Qt::NoPen);
|
||||
_painter->drawRect(rect);
|
||||
painter->setBrush(g);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRect(rect);
|
||||
|
||||
// draw left and right borders
|
||||
_painter->setBrush(Qt::NoBrush);
|
||||
if (m_bMain && !m_bReverse)
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
if (m_main && !m_strict)
|
||||
{
|
||||
QPen p(QColor::fromRgba(0xd0000000 | rgb));
|
||||
p.setStyle(Qt::DotLine);
|
||||
_painter->setPen(p);
|
||||
painter->setPen(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter->setPen(QColor::fromRgba(0xd0000000 | rgb));
|
||||
painter->setPen(QColor::fromRgba(0xd0000000 | rgb));
|
||||
}
|
||||
|
||||
if (m_left > sceneLeft)
|
||||
{
|
||||
if (m_bHoverLeftBorder)
|
||||
if (m_hover_on_left_border)
|
||||
{
|
||||
// Set bold if border is hovered
|
||||
QPen p = _painter->pen();
|
||||
QPen p = painter->pen();
|
||||
p.setWidth(3);
|
||||
_painter->setPen(p);
|
||||
painter->setPen(p);
|
||||
}
|
||||
|
||||
_painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom()));
|
||||
painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom()));
|
||||
}
|
||||
|
||||
if (m_right < sceneRight)
|
||||
{
|
||||
if (m_bHoverLeftBorder)
|
||||
if (m_hover_on_left_border)
|
||||
{
|
||||
// Restore width
|
||||
QPen p = _painter->pen();
|
||||
QPen p = painter->pen();
|
||||
p.setWidth(1);
|
||||
_painter->setPen(p);
|
||||
painter->setPen(p);
|
||||
}
|
||||
else if (m_bHoverRightBorder)
|
||||
else if (m_hover_on_right_border)
|
||||
{
|
||||
// Set bold if border is hovered
|
||||
QPen p = _painter->pen();
|
||||
QPen p = painter->pen();
|
||||
p.setWidth(3);
|
||||
_painter->setPen(p);
|
||||
painter->setPen(p);
|
||||
}
|
||||
|
||||
_painter->drawLine(QPointF(rect.right(), rect.top()), QPointF(rect.right(), rect.bottom()));
|
||||
painter->drawLine(QPointF(rect.right(), rect.top()), QPointF(rect.right(), rect.bottom()));
|
||||
|
||||
// This is not necessary because another setPen() invoked for draw text
|
||||
//if (m_bHoverRightBorder)
|
||||
//if (m_hover_on_right_border)
|
||||
//{
|
||||
// // Restore width
|
||||
// QPen p = _painter->pen();
|
||||
// QPen p = painter->pen();
|
||||
// p.setWidth(1);
|
||||
// _painter->setPen(p);
|
||||
// painter->setPen(p);
|
||||
//}
|
||||
}
|
||||
|
||||
// draw text
|
||||
_painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background
|
||||
_painter->setRenderHint(QPainter::TextAntialiasing);
|
||||
_painter->setPen(0x00ffffff - rgb);
|
||||
_painter->setFont(EASY_GLOBALS.font.ruler);
|
||||
painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background
|
||||
painter->setRenderHint(QPainter::TextAntialiasing);
|
||||
painter->setPen(0x00ffffff - rgb);
|
||||
painter->setFont(EASY_GLOBALS.font.ruler);
|
||||
|
||||
int textFlags = 0;
|
||||
switch (EASY_GLOBALS.chrono_text_position)
|
||||
{
|
||||
case profiler_gui::RulerTextPosition_Top:
|
||||
textFlags = Qt::AlignTop | Qt::AlignHCenter;
|
||||
if (!m_bMain) rect.setTop(rect.top() + textRect.height() * 0.75);
|
||||
if (!m_main) rect.setTop(rect.top() + textRect.height() * 0.75);
|
||||
break;
|
||||
|
||||
case profiler_gui::RulerTextPosition_Center:
|
||||
textFlags = Qt::AlignCenter;
|
||||
if (!m_bMain) rect.setTop(rect.top() + textRect.height() * 1.5);
|
||||
if (!m_main) rect.setTop(rect.top() + textRect.height() * 1.5);
|
||||
break;
|
||||
|
||||
case profiler_gui::RulerTextPosition_Bottom:
|
||||
textFlags = Qt::AlignBottom | Qt::AlignHCenter;
|
||||
if (!m_bMain) rect.setHeight(rect.height() - textRect.height() * 0.75);
|
||||
if (!m_main) rect.setHeight(rect.height() - textRect.height() * 0.75);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -262,8 +268,8 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
if (textRect_width < rect.width())
|
||||
{
|
||||
// Text will be drawed inside rectangle
|
||||
_painter->drawText(rect, textFlags, text);
|
||||
_painter->restore();
|
||||
painter->drawText(rect, textFlags, text);
|
||||
painter->restore();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -284,101 +290,107 @@ void GraphicsRulerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem
|
||||
}
|
||||
//else // Text will be drawed inside rectangle
|
||||
|
||||
_painter->drawText(rect, textFlags | Qt::TextDontClip, text);
|
||||
painter->drawText(rect, textFlags | Qt::TextDontClip, text);
|
||||
|
||||
_painter->restore();
|
||||
painter->restore();
|
||||
// END Paint!~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::hide()
|
||||
{
|
||||
m_bHoverIndicator = false;
|
||||
m_bHoverLeftBorder = false;
|
||||
m_bHoverRightBorder = false;
|
||||
m_bReverse = false;
|
||||
m_hover_on_indicator = false;
|
||||
m_hover_on_left_border = false;
|
||||
m_hover_on_right_border = false;
|
||||
m_reverse = false;
|
||||
m_strict = false;
|
||||
Parent::hide();
|
||||
}
|
||||
|
||||
bool GraphicsRulerItem::indicatorContains(const QPointF& _pos) const
|
||||
bool GraphicsRulerItem::indicatorContains(const QPointF& pos) const
|
||||
{
|
||||
if (m_indicator.empty())
|
||||
return false;
|
||||
|
||||
const auto itemX = toItem(_pos.x());
|
||||
return m_indicator.containsPoint(QPointF(itemX, _pos.y()), Qt::OddEvenFill);
|
||||
const auto itemX = toItem(pos.x());
|
||||
return m_indicator.containsPoint(QPointF(itemX, pos.y()), Qt::OddEvenFill);
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setHoverLeft(bool _hover)
|
||||
void GraphicsRulerItem::setHoverLeft(bool hover)
|
||||
{
|
||||
m_bHoverLeftBorder = _hover;
|
||||
m_hover_on_left_border = hover;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setHoverRight(bool _hover)
|
||||
void GraphicsRulerItem::setHoverRight(bool hover)
|
||||
{
|
||||
m_bHoverRightBorder = _hover;
|
||||
m_hover_on_right_border = hover;
|
||||
}
|
||||
|
||||
bool GraphicsRulerItem::hoverLeft(qreal _x) const
|
||||
bool GraphicsRulerItem::hoverLeft(qreal x) const
|
||||
{
|
||||
const auto dx = fabs(_x - m_left) * view()->scale();
|
||||
const auto dx = fabs(x - m_left) * view()->scale();
|
||||
return dx < 4;
|
||||
}
|
||||
|
||||
bool GraphicsRulerItem::hoverRight(qreal _x) const
|
||||
bool GraphicsRulerItem::hoverRight(qreal x) const
|
||||
{
|
||||
const auto dx = fabs(_x - m_right) * view()->scale();
|
||||
const auto dx = fabs(x - m_right) * view()->scale();
|
||||
return dx < 4;
|
||||
}
|
||||
|
||||
QPointF GraphicsRulerItem::toItem(const QPointF& _pos) const
|
||||
QPointF GraphicsRulerItem::toItem(const QPointF& pos) const
|
||||
{
|
||||
const auto sceneView = view();
|
||||
return QPointF((_pos.x() - sceneView->offset()) * sceneView->scale() - x(), _pos.y());
|
||||
return QPointF((pos.x() - sceneView->offset()) * sceneView->scale() - x(), pos.y());
|
||||
}
|
||||
|
||||
qreal GraphicsRulerItem::toItem(qreal _x) const
|
||||
qreal GraphicsRulerItem::toItem(qreal x) const
|
||||
{
|
||||
const auto sceneView = view();
|
||||
return (_x - sceneView->offset()) * sceneView->scale() - x();
|
||||
return (x - sceneView->offset()) * sceneView->scale() - this->x();
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setColor(const QColor& _color)
|
||||
void GraphicsRulerItem::setColor(const QColor& color)
|
||||
{
|
||||
m_color = _color;
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h)
|
||||
{
|
||||
m_boundingRect.setRect(x, y, w, h);
|
||||
m_bounding_rect.setRect(x, y, w, h);
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setBoundingRect(const QRectF& _rect)
|
||||
void GraphicsRulerItem::setBoundingRect(const QRectF& rect)
|
||||
{
|
||||
m_boundingRect = _rect;
|
||||
m_bounding_rect = rect;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setLeftRight(qreal _left, qreal _right)
|
||||
void GraphicsRulerItem::setLeftRight(qreal left, qreal right)
|
||||
{
|
||||
if (_left < _right)
|
||||
if (left < right)
|
||||
{
|
||||
m_left = _left;
|
||||
m_right = _right;
|
||||
m_left = left;
|
||||
m_right = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_left = _right;
|
||||
m_right = _left;
|
||||
m_left = right;
|
||||
m_right = left;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setReverse(bool _reverse)
|
||||
void GraphicsRulerItem::setReverse(bool reverse)
|
||||
{
|
||||
m_bReverse = _reverse;
|
||||
m_reverse = reverse;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setHoverIndicator(bool _hover)
|
||||
void GraphicsRulerItem::setStrict(bool strict)
|
||||
{
|
||||
m_bHoverIndicator = _hover;
|
||||
m_strict = strict;
|
||||
}
|
||||
|
||||
void GraphicsRulerItem::setHoverIndicator(bool hover)
|
||||
{
|
||||
m_hover_on_indicator = hover;
|
||||
}
|
||||
|
||||
const BlocksGraphicsView* GraphicsRulerItem::view() const
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -74,25 +74,26 @@ class GraphicsRulerItem : public QGraphicsItem
|
||||
typedef QGraphicsItem Parent;
|
||||
typedef GraphicsRulerItem This;
|
||||
|
||||
QPolygonF m_indicator; ///< Indicator displayed when this chrono item is out of screen (displaying only for main item)
|
||||
QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem)
|
||||
QColor m_color; ///< Color of the item
|
||||
qreal m_left, m_right; ///< Left and right bounds of the selection zone
|
||||
bool m_bMain; ///< Is this chronometer main (true, by default)
|
||||
bool m_bReverse; ///<
|
||||
bool m_bHoverIndicator; ///< Mouse hover above indicator
|
||||
bool m_bHoverLeftBorder;
|
||||
bool m_bHoverRightBorder;
|
||||
QPolygonF m_indicator; ///< Indicator displayed when this chrono item is out of screen (displaying only for main item)
|
||||
QRectF m_bounding_rect; ///< boundingRect (see QGraphicsItem)
|
||||
QColor m_color; ///< Color of the item
|
||||
qreal m_left, m_right; ///< Left and right bounds of the selection zone
|
||||
bool m_main; ///< Is this ruler item main (true, by default)
|
||||
bool m_reverse; ///<
|
||||
bool m_strict; ///<
|
||||
bool m_hover_on_indicator; ///< Mouse hover above indicator
|
||||
bool m_hover_on_left_border;
|
||||
bool m_hover_on_right_border;
|
||||
|
||||
public:
|
||||
|
||||
explicit GraphicsRulerItem(bool _main = true);
|
||||
explicit GraphicsRulerItem(bool main = true);
|
||||
virtual ~GraphicsRulerItem();
|
||||
|
||||
// Public virtual methods
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override;
|
||||
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
|
||||
|
||||
public:
|
||||
|
||||
@ -100,46 +101,57 @@ public:
|
||||
|
||||
void hide();
|
||||
|
||||
void setColor(const QColor& _color);
|
||||
void setColor(const QColor& color);
|
||||
|
||||
void setBoundingRect(qreal x, qreal y, qreal w, qreal h);
|
||||
void setBoundingRect(const QRectF& _rect);
|
||||
void setBoundingRect(const QRectF& rect);
|
||||
|
||||
void setLeftRight(qreal _left, qreal _right);
|
||||
void setLeftRight(qreal left, qreal right);
|
||||
|
||||
void setReverse(bool _reverse);
|
||||
void setReverse(bool reverse);
|
||||
void setStrict(bool strict);
|
||||
|
||||
void setHoverIndicator(bool _hover);
|
||||
void setHoverIndicator(bool hover);
|
||||
|
||||
bool indicatorContains(const QPointF& _pos) const;
|
||||
bool indicatorContains(const QPointF& pos) const;
|
||||
|
||||
void setHoverLeft(bool _hover);
|
||||
void setHoverRight(bool _hover);
|
||||
void setHoverLeft(bool hover);
|
||||
void setHoverRight(bool hover);
|
||||
|
||||
bool hoverLeft(qreal _x) const;
|
||||
bool hoverRight(qreal _x) const;
|
||||
bool hoverLeft(qreal x) const;
|
||||
bool hoverRight(qreal x) const;
|
||||
|
||||
QPointF toItem(const QPointF& _pos) const;
|
||||
qreal toItem(qreal _x) const;
|
||||
QPointF toItem(const QPointF& pos) const;
|
||||
qreal toItem(qreal x) const;
|
||||
|
||||
inline bool hoverIndicator() const
|
||||
{
|
||||
return m_bHoverIndicator;
|
||||
return m_hover_on_indicator;
|
||||
}
|
||||
|
||||
inline bool hoverLeft() const
|
||||
{
|
||||
return m_bHoverLeftBorder;
|
||||
return m_hover_on_left_border;
|
||||
}
|
||||
|
||||
inline bool hoverRight() const
|
||||
{
|
||||
return m_bHoverRightBorder;
|
||||
return m_hover_on_right_border;
|
||||
}
|
||||
|
||||
inline bool hoverAnyBorder() const
|
||||
{
|
||||
return m_hover_on_left_border || m_hover_on_right_border;
|
||||
}
|
||||
|
||||
inline bool reverse() const
|
||||
{
|
||||
return m_bReverse;
|
||||
return m_reverse;
|
||||
}
|
||||
|
||||
inline bool strict() const
|
||||
{
|
||||
return m_strict;
|
||||
}
|
||||
|
||||
inline qreal left() const
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -115,6 +115,11 @@ void GraphicsHistogramItem::paint(QPainter* _painter, const QStyleOptionGraphics
|
||||
|
||||
void GraphicsHistogramItem::paintMouseIndicator(QPainter* _painter, qreal _top, qreal _bottom, qreal _width, qreal _height, qreal _top_width, qreal _mouse_y, qreal _delta_time, int _font_h)
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_font_h != 0 && _top < _mouse_y && _mouse_y < _bottom)
|
||||
{
|
||||
const int half_font_h = _font_h >> 1;
|
||||
@ -178,7 +183,7 @@ void GraphicsHistogramItem::paintByPtr(QPainter* _painter)
|
||||
_painter->setPen(profiler_gui::TEXT_COLOR);
|
||||
_painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, bindMode ? " Mode: Zoom" : " Mode: Overview");
|
||||
|
||||
if (!m_topDurationStr.isEmpty())
|
||||
if (!isEmpty() && !m_topDurationStr.isEmpty())
|
||||
{
|
||||
if (m_timeUnits != EASY_GLOBALS.time_units)
|
||||
{
|
||||
@ -204,7 +209,7 @@ void GraphicsHistogramItem::paintByPtr(QPainter* _painter)
|
||||
|
||||
paintMouseIndicator(_painter, m_boundingRect.top(), bottom, width, m_boundingRect.height(), top_width, m_mousePos.y(), dtime, font_h);
|
||||
|
||||
if (m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue)
|
||||
if (!isEmpty() && m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue)
|
||||
{
|
||||
// Draw marker displaying expected frame_time step
|
||||
const auto h = bottom - (EASY_GLOBALS.frame_time - m_bottomValue) * coeff;
|
||||
@ -270,7 +275,7 @@ void GraphicsHistogramItem::paintById(QPainter* _painter)
|
||||
_painter->setPen(profiler_gui::TEXT_COLOR);
|
||||
_painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, bindMode ? " Mode: Zoom" : " Mode: Overview");
|
||||
|
||||
if (!m_topDurationStr.isEmpty())
|
||||
if (!isEmpty() && !m_topDurationStr.isEmpty())
|
||||
{
|
||||
if (m_timeUnits != EASY_GLOBALS.time_units)
|
||||
{
|
||||
@ -296,7 +301,7 @@ void GraphicsHistogramItem::paintById(QPainter* _painter)
|
||||
|
||||
paintMouseIndicator(_painter, m_boundingRect.top(), bottom, width, m_boundingRect.height(), top_width, m_mousePos.y(), dtime, font_h);
|
||||
|
||||
if (m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue)
|
||||
if (!isEmpty() && m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue)
|
||||
{
|
||||
// Draw marker displaying required frame_time step
|
||||
const auto h = bottom - (EASY_GLOBALS.frame_time - m_bottomValue) * coeff;
|
||||
@ -315,20 +320,20 @@ void GraphicsHistogramItem::paintById(QPainter* _painter)
|
||||
_painter->setPen(profiler_gui::TEXT_COLOR);
|
||||
rect.setRect(0, bottom + 2, width, font_h);
|
||||
|
||||
if (!m_selectedBlocks.empty())
|
||||
if (!items.empty())
|
||||
{
|
||||
if (m_threadProfiledTime != 0)
|
||||
{
|
||||
_painter->drawText(rect, Qt::AlignCenter | Qt::TextDontClip,
|
||||
QString("%1 | %2 | %3 calls | %4% of thread profiled time")
|
||||
.arg(m_threadName).arg(m_blockName).arg(m_selectedBlocks.size())
|
||||
.arg(m_threadName).arg(m_blockName).arg(items.size())
|
||||
.arg(QString::number(100. * (double)m_blockTotalDuraion / (double)m_threadProfiledTime, 'f', 2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter->drawText(rect, Qt::AlignCenter | Qt::TextDontClip,
|
||||
QString("%1 | %2 | %3 calls | 100% of thread profiled time")
|
||||
.arg(m_threadName).arg(m_blockName).arg(m_selectedBlocks.size()));
|
||||
.arg(m_threadName).arg(m_blockName).arg(items.size()));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -380,6 +385,7 @@ void GraphicsHistogramItem::setSource(profiler::thread_id_t _thread_id, const pr
|
||||
m_imageScaleUpdate = m_imageScale = 1;
|
||||
|
||||
m_selectedBlocks.clear();
|
||||
setEmpty(true);
|
||||
{ profiler::BlocksTree::children_t().swap(m_selectedBlocks); }
|
||||
|
||||
setImageUpdatePermitted(false);
|
||||
@ -464,6 +470,7 @@ void GraphicsHistogramItem::setSource(profiler::thread_id_t _thread_id, const pr
|
||||
m_bottomDurationStr.clear();
|
||||
}
|
||||
|
||||
setEmpty(empty);
|
||||
setReady(true);
|
||||
|
||||
}, m_bReady);
|
||||
@ -505,6 +512,7 @@ void GraphicsHistogramItem::setSource(profiler::thread_id_t _thread_id, profiler
|
||||
m_imageScaleUpdate = m_imageScale = 1;
|
||||
|
||||
m_selectedBlocks.clear();
|
||||
setEmpty(true);
|
||||
{ profiler::BlocksTree::children_t().swap(m_selectedBlocks); }
|
||||
|
||||
m_threadId = _thread_id;
|
||||
@ -658,6 +666,7 @@ void GraphicsHistogramItem::setSource(profiler::thread_id_t _thread_id, profiler
|
||||
m_topValue = m_maxValue;
|
||||
m_bottomValue = m_minValue;
|
||||
|
||||
setEmpty(m_selectedBlocks.empty());
|
||||
setReady(true);
|
||||
|
||||
}, m_bReady);
|
||||
@ -770,7 +779,7 @@ bool GraphicsHistogramItem::decreaseBottomValue()
|
||||
|
||||
void GraphicsHistogramItem::pickFrameTime(qreal _y) const
|
||||
{
|
||||
if (isImageUpdatePermitted() && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty())
|
||||
if (!isEmpty() && isImageUpdatePermitted() && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty())
|
||||
{
|
||||
const auto frame_time = m_bottomValue + (m_topValue - m_bottomValue) * (m_boundingRect.bottom() - _y) / m_boundingRect.height();
|
||||
EASY_GLOBALS.frame_time = static_cast<decltype(EASY_GLOBALS.frame_time)>(frame_time);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -51,6 +51,5 @@ default/crop.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/yx.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/svg2.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/svg3.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/to-fullscreen.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/to-window.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/window.svg - Icon made by Freepik from www.flaticon.com
|
||||
|
@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#504040" d="M359.277,137.723H152.721c-8.284,0-15,6.716-15,15V359.28c0,8.284,6.716,15,15,15h206.557c8.284,0,15-6.716,15-15V152.723
|
||||
C374.277,144.439,367.561,137.723,359.277,137.723z M344.278,344.279L344.278,344.279H167.721V167.723h176.557V344.279z"/>
|
||||
<rect stroke="black" stroke-width="5" stroke-linecap="butt" stroke-linejoin="miter" fill="none" x="38" y="38" width="52" height="52"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 506 B |
@ -8,7 +8,7 @@
|
||||
* description : Main file for EasyProfiler GUI.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -18,7 +18,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -87,6 +87,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QProgressDialog>
|
||||
#include <QTextCodec>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTextStream>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
@ -128,7 +129,7 @@ const auto NETWORK_CACHE_FILE = "easy_profiler_stream.cache";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline const QStringList& UI_themes()
|
||||
static const QStringList& UI_themes()
|
||||
{
|
||||
static const QStringList themes {
|
||||
"default"
|
||||
@ -150,7 +151,80 @@ inline void clear_stream(std::stringstream& _stream)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void loadTheme(const QString& _theme)
|
||||
static void convertPointSizes(QString& style)
|
||||
{
|
||||
// Find font family
|
||||
const auto fontMatch = QRegularExpression("font-family:\\s*\\\"(.*)\\\"\\s*;").match(style);
|
||||
const auto fontFamily = fontMatch.hasMatch() ? fontMatch.captured(fontMatch.lastCapturedIndex()) : QString("DejaVu Sans");
|
||||
//QMessageBox::information(nullptr, "Found font family", fontFamily);
|
||||
|
||||
// Calculate point size using current font
|
||||
const auto pointSizeF = QFontMetricsF(QFont(fontFamily, 100)).height() * 1e-2;
|
||||
//QMessageBox::information(nullptr, "Point size", QString("100pt = %1\n1pt = %2").arg(pointSizeF * 1e2).arg(pointSizeF));
|
||||
|
||||
// Find and convert all sizes from points to pixels
|
||||
QRegularExpression re("(\\d+\\.?\\d*)ex");
|
||||
auto it = re.globalMatch(style);
|
||||
|
||||
std::vector<QStringList> matches;
|
||||
{
|
||||
QSet<QString> uniqueMatches;
|
||||
while (it.hasNext())
|
||||
{
|
||||
const auto match = it.next();
|
||||
if (!uniqueMatches.contains(match.captured()))
|
||||
{
|
||||
uniqueMatches.insert(match.captured());
|
||||
matches.emplace_back(match.capturedTexts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& capturedTexts : matches)
|
||||
{
|
||||
const auto pt = capturedTexts.back().toDouble();
|
||||
const int pixels = static_cast<int>(lround(pointSizeF * pt));
|
||||
style.replace(QString(" %1").arg(capturedTexts.front()), QString(" %1px").arg(pixels));
|
||||
style.replace(QString(":%1").arg(capturedTexts.front()), QString(":%1px").arg(pixels));
|
||||
}
|
||||
}
|
||||
|
||||
static void replaceOsDependentSettings(QString& style)
|
||||
{
|
||||
// Find and convert all OS dependent options
|
||||
// Example: "/*{lin}font-weight: bold;*/" -> "font-weight: bold;"
|
||||
|
||||
#if defined(_WIN32)
|
||||
QRegularExpression re("/\\*\\{win\\}(.*)\\*/");
|
||||
#elif defined(__APPLE__)
|
||||
QRegularExpression re("/\\*\\{mac\\}(.*)\\*/");
|
||||
#else
|
||||
QRegularExpression re("/\\*\\{lin\\}(.*)\\*/");
|
||||
#endif
|
||||
|
||||
auto it = re.globalMatch(style);
|
||||
|
||||
std::vector<QStringList> matches;
|
||||
{
|
||||
QSet<QString> uniqueMatches;
|
||||
while (it.hasNext())
|
||||
{
|
||||
const auto match = it.next();
|
||||
if (!uniqueMatches.contains(match.captured()))
|
||||
{
|
||||
uniqueMatches.insert(match.captured());
|
||||
matches.emplace_back(match.capturedTexts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& capturedTexts : matches)
|
||||
{
|
||||
style.replace(capturedTexts.front(), capturedTexts.back());
|
||||
}
|
||||
}
|
||||
|
||||
static void loadTheme(const QString& _theme)
|
||||
{
|
||||
QFile file(QStringLiteral(":/themes/") + _theme);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text))
|
||||
@ -159,41 +233,8 @@ inline void loadTheme(const QString& _theme)
|
||||
QString style = in.readAll();
|
||||
if (!style.isEmpty())
|
||||
{
|
||||
// Find font family
|
||||
const auto fontMatch = QRegularExpression("font-family:\\s*\\\"(.*)\\\"\\s*;").match(style);
|
||||
const auto fontFamily = fontMatch.hasMatch() ? fontMatch.captured(fontMatch.lastCapturedIndex()) : QString("DejaVu Sans");
|
||||
//QMessageBox::information(nullptr, "Found font family", fontFamily);
|
||||
|
||||
// Calculate point size using current font
|
||||
const auto pointSizeF = QFontMetricsF(QFont(fontFamily, 100)).height() * 1e-2;
|
||||
//QMessageBox::information(nullptr, "Point size", QString("100pt = %1\n1pt = %2").arg(pointSizeF * 1e2).arg(pointSizeF));
|
||||
|
||||
// Find and convert all sizes from points to pixels
|
||||
QRegularExpression re("(\\d+\\.?\\d*)ex");
|
||||
auto it = re.globalMatch(style);
|
||||
|
||||
std::vector<QStringList> matches;
|
||||
{
|
||||
QSet<QString> uniqueMatches;
|
||||
while (it.hasNext())
|
||||
{
|
||||
const auto match = it.next();
|
||||
if (!uniqueMatches.contains(match.captured()))
|
||||
{
|
||||
uniqueMatches.insert(match.captured());
|
||||
matches.emplace_back(match.capturedTexts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& capturedTexts : matches)
|
||||
{
|
||||
const auto pt = capturedTexts.back().toDouble();
|
||||
const int pixels = static_cast<int>(pointSizeF * pt + 0.5);
|
||||
//QMessageBox::information(nullptr, "Style-sheet modification", QString("Replacing '%1'\nwith\n'%2px'\n\npt count: %3").arg(capturedTexts.front()).arg(pixels).arg(pt));
|
||||
style.replace(capturedTexts.front(), QString("%1px").arg(pixels));
|
||||
}
|
||||
|
||||
convertPointSizes(style);
|
||||
replaceOsDependentSettings(style);
|
||||
qApp->setStyleSheet(style);
|
||||
}
|
||||
}
|
||||
@ -253,7 +294,7 @@ void MainWindow::configureSizes()
|
||||
EASY_GLOBALS.font.default_font = w.font();
|
||||
const QFontMetricsF fm(w.font());
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
EASY_CONSTEXPR qreal DefaultHeight = 16;
|
||||
#else
|
||||
EASY_CONSTEXPR qreal DefaultHeight = 17;
|
||||
@ -268,7 +309,7 @@ void MainWindow::configureSizes()
|
||||
size.graphics_row_full = size.graphics_row_height;
|
||||
size.threads_row_spacing = size.graphics_row_full >> 1;
|
||||
size.timeline_height = size.font_height + px(10);
|
||||
size.icon_size = size.font_height + px(11);
|
||||
size.icon_size = size.font_height + px(5);
|
||||
|
||||
const auto fontFamily = w.font().family();
|
||||
const auto pixelSize = w.font().pixelSize();
|
||||
@ -543,6 +584,12 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos
|
||||
action->setChecked(EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
connect(action, &QAction::triggered, this, &This::onBindExpandStatusChange);
|
||||
|
||||
action = submenu->addAction("Hide stats for single blocks in tree");
|
||||
action->setToolTip("If checked then such stats like Min,Max,Avg etc.\nwill not be displayed in stats tree for blocks\nwith number of calls == 1");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(EASY_GLOBALS.display_only_relevant_stats);
|
||||
connect(action, &QAction::triggered, this, &This::onDisplayRelevantStatsChange);
|
||||
|
||||
action = submenu->addAction("Selecting block changes current thread");
|
||||
action->setToolTip("Automatically select thread while selecting a block.\nIf not checked then you will have to select current thread\nmanually double clicking on thread name on a diagram.");
|
||||
action->setCheckable(true);
|
||||
@ -1375,6 +1422,11 @@ void MainWindow::onBindExpandStatusChange(bool _checked)
|
||||
EASY_GLOBALS.bind_scene_and_tree_expand_status = _checked;
|
||||
}
|
||||
|
||||
void MainWindow::onDisplayRelevantStatsChange(bool _checked)
|
||||
{
|
||||
EASY_GLOBALS.display_only_relevant_stats = _checked;
|
||||
}
|
||||
|
||||
void MainWindow::onHierarchyFlagChange(bool _checked)
|
||||
{
|
||||
EASY_GLOBALS.only_current_thread_hierarchy = _checked;
|
||||
@ -1467,8 +1519,14 @@ void MainWindow::onEditBlocksClicked(bool)
|
||||
{
|
||||
if (m_descTreeDialog.ptr != nullptr)
|
||||
{
|
||||
if (m_descTreeDialog.ptr->isMinimized())
|
||||
{
|
||||
m_descTreeDialog.ptr->setWindowState((m_descTreeDialog.ptr->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
||||
}
|
||||
|
||||
m_descTreeDialog.ptr->raise();
|
||||
m_descTreeDialog.ptr->setFocus();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1647,6 +1705,10 @@ void MainWindow::loadSettings()
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool();
|
||||
|
||||
flag = settings.value("display_only_relevant_stats");
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.display_only_relevant_stats = flag.toBool();
|
||||
|
||||
flag = settings.value("selecting_block_changes_thread");
|
||||
if (!flag.isNull())
|
||||
EASY_GLOBALS.selecting_block_changes_thread = flag.toBool();
|
||||
@ -1779,6 +1841,7 @@ void MainWindow::saveSettingsAndGeometry()
|
||||
settings.setValue("add_zero_blocks_to_hierarchy", EASY_GLOBALS.add_zero_blocks_to_hierarchy);
|
||||
settings.setValue("highlight_blocks_with_same_id", EASY_GLOBALS.highlight_blocks_with_same_id);
|
||||
settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status);
|
||||
settings.setValue("display_only_relevant_stats", EASY_GLOBALS.display_only_relevant_stats);
|
||||
settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread);
|
||||
settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_markers);
|
||||
settings.setValue("auto_adjust_histogram_height", EASY_GLOBALS.auto_adjust_histogram_height);
|
||||
@ -2106,9 +2169,6 @@ void MainWindow::onLoadingFinish(profiler::block_index_t& _nblocks)
|
||||
{
|
||||
auto& guiblock = EASY_GLOBALS.gui_blocks[i];
|
||||
guiblock.tree = std::move(blocks[i]);
|
||||
#ifdef EASY_TREE_WIDGET__USE_VECTOR
|
||||
profiler_gui::set_max(guiblock.tree_item);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_saveAction->setEnabled(true);
|
||||
@ -2818,12 +2878,7 @@ void MainWindow::onSelectValue(profiler::thread_id_t _thread_id, uint32_t _value
|
||||
|
||||
void DialogWithGeometry::create(QWidget* content, QWidget* parent)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const WindowHeader::Buttons buttons = WindowHeader::AllButtons;
|
||||
#else
|
||||
const WindowHeader::Buttons buttons {WindowHeader::MaximizeButton | WindowHeader::CloseButton};
|
||||
#endif
|
||||
ptr = new Dialog(parent, EASY_DEFAULT_WINDOW_TITLE, content, buttons, QMessageBox::NoButton);
|
||||
ptr = new Dialog(parent, EASY_DEFAULT_WINDOW_TITLE, content, WindowHeader::AllButtons, QMessageBox::NoButton);
|
||||
ptr->setProperty("stayVisible", true);
|
||||
ptr->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -337,6 +337,7 @@ protected slots:
|
||||
void onAllItemsExpandedByDefaultChange(bool);
|
||||
void onBindExpandStatusChange(bool);
|
||||
void onHierarchyFlagChange(bool);
|
||||
void onDisplayRelevantStatsChange(bool);
|
||||
void onExpandAllClicked(bool);
|
||||
void onCollapseAllClicked(bool);
|
||||
void onViewportInfoClicked(bool);
|
||||
|
@ -18,7 +18,7 @@ BEGIN
|
||||
VALUE "CompanyName", "EasySolutions"
|
||||
VALUE "FileDescription", "EasyProfiler"
|
||||
VALUE "InternalName", "profiler_gui"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2016-2018 Victor Zarubkin, Sergey Yagovtsev"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2016-2019 Victor Zarubkin, Sergey Yagovtsev"
|
||||
VALUE "LegalTrademarks1", "All Rights Reserved"
|
||||
VALUE "LegalTrademarks2", "All Rights Reserved"
|
||||
VALUE "OriginalFilename", "profiler_gui.exe"
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of RoundProgressWidget.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains declaration of RoundProgressWidget.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
104
profiler_gui/text_highlighter.cpp
Normal file
104
profiler_gui/text_highlighter.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/************************************************************************
|
||||
* file name : text_highlighter.cpp
|
||||
* ----------------- :
|
||||
* creation time : 2019/10/12
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains implementation of TextHighlighter.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* : at your option.
|
||||
* :
|
||||
* : The MIT License
|
||||
* :
|
||||
* : Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* : of this software and associated documentation files (the "Software"), to deal
|
||||
* : in the Software without restriction, including without limitation the rights
|
||||
* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* : of the Software, and to permit persons to whom the Software is furnished
|
||||
* : to do so, subject to the following conditions:
|
||||
* :
|
||||
* : The above copyright notice and this permission notice shall be included in all
|
||||
* : copies or substantial portions of the Software.
|
||||
* :
|
||||
* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* : USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* :
|
||||
* : The Apache License, Version 2.0 (the "License")
|
||||
* :
|
||||
* : You may not use this file except in compliance with the License.
|
||||
* : You may obtain a copy of the License at
|
||||
* :
|
||||
* : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* :
|
||||
* : Unless required by applicable law or agreed to in writing, software
|
||||
* : distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* : See the License for the specific language governing permissions and
|
||||
* : limitations under the License.
|
||||
************************************************************************/
|
||||
|
||||
#include "text_highlighter.h"
|
||||
#include <QColor>
|
||||
#include <QRegExp>
|
||||
|
||||
#include <easy/details/profiler_colors.h>
|
||||
#include "common_functions.h"
|
||||
|
||||
EASY_CONSTEXPR auto HighlightColor = profiler::colors::Yellow;
|
||||
EASY_CONSTEXPR auto CurrentHighlightColor = profiler::colors::Magenta;
|
||||
|
||||
TextHighlighter::TextHighlighter(
|
||||
QTextDocument* doc,
|
||||
const QColor& normalTextColor,
|
||||
const QColor& lightTextColor,
|
||||
const QString& pattern,
|
||||
Qt::CaseSensitivity caseSensitivity,
|
||||
bool current
|
||||
)
|
||||
: QSyntaxHighlighter(doc)
|
||||
, m_pattern(pattern)
|
||||
, m_caseSensitivity(caseSensitivity)
|
||||
{
|
||||
auto color = current ? CurrentHighlightColor : HighlightColor;
|
||||
m_textCharFormat.setBackground(QColor::fromRgba(color));
|
||||
m_textCharFormat.setForeground(profiler_gui::isLightColor(color) ? normalTextColor : lightTextColor);
|
||||
}
|
||||
|
||||
TextHighlighter::~TextHighlighter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TextHighlighter::highlightBlock(const QString& text)
|
||||
{
|
||||
if (m_pattern.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QRegExp expression(m_pattern, m_caseSensitivity);
|
||||
int index = text.indexOf(expression);
|
||||
while (index >= 0)
|
||||
{
|
||||
const auto length = expression.cap().length();
|
||||
setFormat(index, length, m_textCharFormat);
|
||||
|
||||
auto prevIndex = index;
|
||||
index = text.indexOf(expression, index + length);
|
||||
if (index <= prevIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
83
profiler_gui/text_highlighter.h
Normal file
83
profiler_gui/text_highlighter.h
Normal file
@ -0,0 +1,83 @@
|
||||
/************************************************************************
|
||||
* file name : text_highlighter.h
|
||||
* ----------------- :
|
||||
* creation time : 2019/10/12
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains declaration of TextHighlighter - an auxiliary class
|
||||
* : for highlighting text in QTextDocument.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* : at your option.
|
||||
* :
|
||||
* : The MIT License
|
||||
* :
|
||||
* : Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* : of this software and associated documentation files (the "Software"), to deal
|
||||
* : in the Software without restriction, including without limitation the rights
|
||||
* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* : of the Software, and to permit persons to whom the Software is furnished
|
||||
* : to do so, subject to the following conditions:
|
||||
* :
|
||||
* : The above copyright notice and this permission notice shall be included in all
|
||||
* : copies or substantial portions of the Software.
|
||||
* :
|
||||
* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* : USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* :
|
||||
* : The Apache License, Version 2.0 (the "License")
|
||||
* :
|
||||
* : You may not use this file except in compliance with the License.
|
||||
* : You may obtain a copy of the License at
|
||||
* :
|
||||
* : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* :
|
||||
* : Unless required by applicable law or agreed to in writing, software
|
||||
* : distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* : See the License for the specific language governing permissions and
|
||||
* : limitations under the License.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef EASY_PROFILER_TEXT_HIGHLIGHTER_H
|
||||
#define EASY_PROFILER_TEXT_HIGHLIGHTER_H
|
||||
|
||||
#include <QSyntaxHighlighter>
|
||||
|
||||
class TextHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QString m_pattern;
|
||||
Qt::CaseSensitivity m_caseSensitivity;
|
||||
QTextCharFormat m_textCharFormat;
|
||||
|
||||
public:
|
||||
|
||||
TextHighlighter(
|
||||
QTextDocument* doc,
|
||||
const QColor& normalTextColor,
|
||||
const QColor& lightTextColor,
|
||||
const QString& pattern,
|
||||
Qt::CaseSensitivity caseSensitivity,
|
||||
bool current
|
||||
);
|
||||
|
||||
~TextHighlighter() override;
|
||||
|
||||
protected:
|
||||
|
||||
void highlightBlock(const QString& text) override;
|
||||
};
|
||||
|
||||
#endif //EASY_PROFILER_TEXT_HIGHLIGHTER_H
|
@ -64,7 +64,10 @@ QSplitter::handle:pressed {
|
||||
|
||||
QLabel#BlocksTreeWidget_HintLabel {
|
||||
color: gray;
|
||||
font-size: 13pt; }
|
||||
font-size: 12pt; }
|
||||
|
||||
QLabel#BlocksTreeWidget_HintLabel[hovered=true] {
|
||||
color: black; }
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
QLineEdit, QSpinBox {
|
||||
@ -303,9 +306,10 @@ QMenu::indicator:exclusive:checked:disabled {
|
||||
/* ****************************************************************************************************************** */
|
||||
QHeaderView::section {
|
||||
height: 15.3ex;
|
||||
width: 60ex;
|
||||
min-width: 40ex;
|
||||
background: #eeeeee; }
|
||||
min-height: 15.3ex;
|
||||
max-height: 15.3ex;
|
||||
background: #eeeeee;
|
||||
/*{lin}font-weight: bold;*/ }
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
DockWidget QWidget#EasyDockWidgetTitle {
|
||||
@ -399,9 +403,9 @@ QScrollBar::add-line, QScrollBar::sub-line {
|
||||
|
||||
WindowHeader {
|
||||
background-color: white;
|
||||
height: 24ex;
|
||||
min-height: 24ex;
|
||||
max-height: 24ex;
|
||||
height: 15.6ex;
|
||||
min-height: 15.6ex;
|
||||
max-height: 15.6ex;
|
||||
margin: 0;
|
||||
padding: 0 0 0 6ex;
|
||||
border: none; }
|
||||
@ -426,8 +430,8 @@ WindowHeader {
|
||||
image: url(":/images/default/minimize");
|
||||
padding: 2ex; }
|
||||
WindowHeader QPushButton#WindowHeader_MinButton:hover {
|
||||
background-color: #d1d1d1;
|
||||
border-bottom: 1px solid #d1d1d1; }
|
||||
background-color: #e8e8e8;
|
||||
border-bottom: 1px solid #e8e8e8; }
|
||||
WindowHeader QPushButton#WindowHeader_MinButton:pressed {
|
||||
background-color: #c4c4c4;
|
||||
border-bottom: 1px solid #c4c4c4; }
|
||||
@ -438,8 +442,8 @@ WindowHeader {
|
||||
image: url(":/images/default/to-window");
|
||||
padding: 1ex; }
|
||||
WindowHeader QPushButton#WindowHeader_MaxButton:hover {
|
||||
background-color: #d1d1d1;
|
||||
border-bottom: 1px solid #d1d1d1; }
|
||||
background-color: #e8e8e8;
|
||||
border-bottom: 1px solid #e8e8e8; }
|
||||
WindowHeader QPushButton#WindowHeader_MaxButton:pressed {
|
||||
background-color: #c4c4c4;
|
||||
border-bottom: 1px solid #c4c4c4; }
|
||||
|
@ -40,11 +40,12 @@ $IndicatorBorderColor: darken($DarkSelectionColor, 5%);
|
||||
$DisabledIndicatorBackgroundColor: $SelectionColor;
|
||||
$DisabledIndicatorBorderColor: darken($SelectionColor, 5%);
|
||||
|
||||
$FocusBorderColor: $DarkSelectionColor;//#ffbcbc;
|
||||
$FocusBorderColor: $DarkSelectionColor; // #ffbcbc;
|
||||
$TooltipColor: #ffeccc;
|
||||
|
||||
$InputHeight: 15ex;
|
||||
$WindowHeaderSize: 24ex;
|
||||
$WindowHeaderSize: 15.6ex;
|
||||
$WindowHeaderHoverColor: lighten($BorderColor, 14%); // #e8e8e8
|
||||
|
||||
// STYLES -------------------------------------------------
|
||||
* {
|
||||
@ -122,7 +123,11 @@ QSplitter::handle:pressed {
|
||||
|
||||
QLabel#BlocksTreeWidget_HintLabel {
|
||||
color: gray;
|
||||
font-size: 13pt;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
QLabel#BlocksTreeWidget_HintLabel[hovered=true] {
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
@ -407,9 +412,10 @@ QMenu::indicator:exclusive:checked:disabled {
|
||||
/* ****************************************************************************************************************** */
|
||||
QHeaderView::section {
|
||||
height: 15.3ex;
|
||||
width: 60ex;
|
||||
min-width: 40ex;
|
||||
min-height: 15.3ex;
|
||||
max-height: 15.3ex;
|
||||
background: #eeeeee;
|
||||
/*{lin}font-weight: bold;*/
|
||||
}
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
@ -548,8 +554,8 @@ WindowHeader {
|
||||
}
|
||||
|
||||
QPushButton#WindowHeader_MinButton:hover {
|
||||
background-color: lighten($BorderColor, 5%);
|
||||
border-bottom: 1px solid lighten($BorderColor, 5%);
|
||||
background-color: $WindowHeaderHoverColor;
|
||||
border-bottom: 1px solid $WindowHeaderHoverColor;
|
||||
}
|
||||
|
||||
QPushButton#WindowHeader_MinButton:pressed {
|
||||
@ -568,8 +574,8 @@ WindowHeader {
|
||||
}
|
||||
|
||||
QPushButton#WindowHeader_MaxButton:hover {
|
||||
background-color: lighten($BorderColor, 5%);
|
||||
border-bottom: 1px solid lighten($BorderColor, 5%);
|
||||
background-color: $WindowHeaderHoverColor;
|
||||
border-bottom: 1px solid $WindowHeaderHoverColor;
|
||||
}
|
||||
|
||||
QPushButton#WindowHeader_MaxButton:pressed {
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of ThreadPool.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains declaration of ThreadPool.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains implementation of ThreadPoolTask.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -51,22 +51,25 @@
|
||||
#include "thread_pool_task.h"
|
||||
#include "thread_pool.h"
|
||||
|
||||
ThreadPoolTask::ThreadPoolTask() : m_func([]{}), m_interrupt(nullptr)
|
||||
static std::atomic_bool s_dummy_flag {false};
|
||||
|
||||
ThreadPoolTask::ThreadPoolTask() : m_func([] {}), m_interrupt(&s_dummy_flag)
|
||||
{
|
||||
m_status = static_cast<int8_t>(TaskStatus::Finished);
|
||||
}
|
||||
|
||||
ThreadPoolTask::~ThreadPoolTask()
|
||||
{
|
||||
m_signals.disconnect();
|
||||
dequeue();
|
||||
}
|
||||
|
||||
void ThreadPoolTask::enqueue(std::function<void()>&& func, std::atomic_bool& interruptFlag)
|
||||
void ThreadPoolTask::enqueue(Func&& func, std::atomic_bool& interruptFlag)
|
||||
{
|
||||
dequeue();
|
||||
setStatus(TaskStatus::Enqueued);
|
||||
|
||||
m_interrupt = & interruptFlag;
|
||||
m_interrupt = &interruptFlag;
|
||||
m_interrupt->store(false, std::memory_order_release);
|
||||
m_func = std::move(func);
|
||||
|
||||
@ -75,19 +78,22 @@ void ThreadPoolTask::enqueue(std::function<void()>&& func, std::atomic_bool& int
|
||||
|
||||
void ThreadPoolTask::dequeue()
|
||||
{
|
||||
if (m_interrupt == nullptr || status() == TaskStatus::Finished)
|
||||
if (m_interrupt == nullptr || m_interrupt == &s_dummy_flag || status() == TaskStatus::Finished)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_interrupt->store(true, std::memory_order_release);
|
||||
|
||||
ThreadPool::instance().dequeue(*this);
|
||||
|
||||
// wait for finish
|
||||
m_mutex.lock();
|
||||
setStatus(TaskStatus::Finished);
|
||||
m_mutex.unlock();
|
||||
{
|
||||
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||
setStatus(TaskStatus::Finished);
|
||||
}
|
||||
|
||||
m_interrupt->store(false, std::memory_order_release);
|
||||
//m_interrupt->store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
TaskStatus ThreadPoolTask::status() const
|
||||
@ -97,16 +103,29 @@ TaskStatus ThreadPoolTask::status() const
|
||||
|
||||
void ThreadPoolTask::execute()
|
||||
{
|
||||
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||
// execute if not cancelled
|
||||
{
|
||||
const std::lock_guard<std::mutex> guard(m_mutex);
|
||||
|
||||
if (status() == TaskStatus::Finished || m_interrupt->load(std::memory_order_acquire))
|
||||
return;
|
||||
if (status() == TaskStatus::Finished || m_interrupt->load(std::memory_order_acquire))
|
||||
{
|
||||
// cancelled
|
||||
return;
|
||||
}
|
||||
|
||||
m_func();
|
||||
setStatus(TaskStatus::Finished);
|
||||
m_func();
|
||||
setStatus(TaskStatus::Finished);
|
||||
}
|
||||
|
||||
emit m_signals.finished();
|
||||
}
|
||||
|
||||
void ThreadPoolTask::setStatus(TaskStatus status)
|
||||
{
|
||||
m_status.store(static_cast<int8_t>(status), std::memory_order_release);
|
||||
}
|
||||
|
||||
ThreadPoolTaskSignals& ThreadPoolTask::events()
|
||||
{
|
||||
return m_signals;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* description : The file contains declaration of ThreadPoolTask.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -56,6 +56,8 @@
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
enum class TaskStatus : int8_t
|
||||
{
|
||||
Enqueued,
|
||||
@ -63,14 +65,34 @@ enum class TaskStatus : int8_t
|
||||
Finished,
|
||||
};
|
||||
|
||||
class ThreadPoolTaskSignals : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
|
||||
ThreadPoolTaskSignals() : QObject() {}
|
||||
|
||||
signals:
|
||||
|
||||
void finished();
|
||||
};
|
||||
|
||||
class ThreadPoolTask EASY_FINAL
|
||||
{
|
||||
public:
|
||||
|
||||
using Func = std::function<void()>;
|
||||
|
||||
private:
|
||||
|
||||
friend class ThreadPool;
|
||||
|
||||
std::function<void()> m_func;
|
||||
std::mutex m_mutex;
|
||||
std::atomic<int8_t> m_status;
|
||||
std::atomic_bool* m_interrupt;
|
||||
ThreadPoolTaskSignals m_signals;
|
||||
Func m_func;
|
||||
std::atomic_bool* m_interrupt;
|
||||
std::mutex m_mutex;
|
||||
std::atomic<int8_t> m_status;
|
||||
|
||||
public:
|
||||
|
||||
@ -80,9 +102,11 @@ public:
|
||||
ThreadPoolTask();
|
||||
~ThreadPoolTask();
|
||||
|
||||
void enqueue(std::function<void()>&& func, std::atomic_bool& interruptFlag);
|
||||
void enqueue(Func&& func, std::atomic_bool& interruptFlag);
|
||||
void dequeue();
|
||||
|
||||
ThreadPoolTaskSignals& events();
|
||||
|
||||
private:
|
||||
|
||||
void execute();
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
|
@ -13,7 +13,7 @@
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin
|
||||
* : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
@ -54,32 +54,39 @@
|
||||
************************************************************************/
|
||||
|
||||
#include "tree_widget_item.h"
|
||||
#include "globals.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QFont>
|
||||
#include <QPainter>
|
||||
#include <QPoint>
|
||||
#include <QBrush>
|
||||
#include <QRect>
|
||||
#include <QSize>
|
||||
#include <QTextDocument>
|
||||
#include <QVariant>
|
||||
|
||||
#include "globals.h"
|
||||
#include "blocks_tree_widget.h"
|
||||
#include "text_highlighter.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EASY_CONSTEXPR int BlockColorRole = Qt::UserRole + 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace {
|
||||
|
||||
EASY_CONSTEXPR int ColumnBit[COL_COLUMNS_NUMBER] = {
|
||||
-1 // COL_NAME = 0,
|
||||
|
||||
, 0 // COL_BEGIN,
|
||||
|
||||
, 1 // COL_DURATION,
|
||||
, 2 // COL_SELF_DURATION,
|
||||
, 3 // COL_DURATION_SUM_PER_PARENT,
|
||||
, 4 // COL_DURATION_SUM_PER_FRAME,
|
||||
, 5 // COL_DURATION_SUM_PER_THREAD,
|
||||
, 1 // COL_TIME,
|
||||
, 2 // COL_SELF_TIME,
|
||||
, 3 // COL_TOTAL_TIME_PER_PARENT,
|
||||
, 4 // COL_TOTAL_TIME_PER_FRAME,
|
||||
, 5 // COL_TOTAL_TIME_PER_THREAD,
|
||||
|
||||
, -1 // COL_SELF_DURATION_PERCENT,
|
||||
, -1 // COL_SELF_TIME_PERCENT,
|
||||
, -1 // COL_PERCENT_PER_PARENT,
|
||||
, -1 // COL_PERCENT_PER_FRAME,
|
||||
, -1 // COL_PERCENT_SUM_PER_PARENT,
|
||||
@ -90,30 +97,41 @@ EASY_CONSTEXPR int ColumnBit[COL_COLUMNS_NUMBER] = {
|
||||
|
||||
, 7 // COL_MIN_PER_FRAME,
|
||||
, 8 // COL_MAX_PER_FRAME,
|
||||
, 9 // COL_AVERAGE_PER_FRAME,
|
||||
, 9 // COL_AVG_PER_FRAME,
|
||||
, -1 // COL_NCALLS_PER_FRAME,
|
||||
|
||||
, 10 // COL_MIN_PER_THREAD,
|
||||
, 11 // COL_MAX_PER_THREAD,
|
||||
, 12 // COL_AVERAGE_PER_THREAD,
|
||||
, 12 // COL_AVG_PER_THREAD,
|
||||
, -1 // COL_NCALLS_PER_THREAD,
|
||||
|
||||
, 13 // COL_MIN_PER_PARENT,
|
||||
, 14 // COL_MAX_PER_PARENT,
|
||||
, 15 // COL_AVERAGE_PER_PARENT,
|
||||
, 15 // COL_AVG_PER_PARENT,
|
||||
, -1 // COL_NCALLS_PER_PARENT,
|
||||
|
||||
, 16 // COL_ACTIVE_TIME,
|
||||
, -1 // COL_ACTIVE_PERCENT,
|
||||
|
||||
, -1 // COL_PERCENT_PER_AREA,
|
||||
, 17 // COL_TOTAL_TIME_PER_AREA,
|
||||
, -1 // COL_PERCENT_SUM_PER_AREA,
|
||||
, 18 // COL_MIN_PER_AREA,
|
||||
, 19 // COL_MAX_PER_AREA,
|
||||
, 20 // COL_AVG_PER_AREA,
|
||||
, -1 // COL_NCALLS_PER_AREA,
|
||||
};
|
||||
|
||||
} // end of namespace <noname>.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TreeWidgetItem::TreeWidgetItem(const profiler::block_index_t _treeBlock, Parent* _parent)
|
||||
TreeWidgetItem::TreeWidgetItem(profiler::block_index_t _treeBlock, Parent* _parent)
|
||||
: Parent(_parent, QTreeWidgetItem::UserType)
|
||||
, m_block(_treeBlock)
|
||||
, m_customBGColor(0)
|
||||
, m_bMain(false)
|
||||
, m_partial(false)
|
||||
{
|
||||
|
||||
}
|
||||
@ -139,16 +157,19 @@ bool TreeWidgetItem::operator < (const Parent& _other) const
|
||||
case COL_NCALLS_PER_THREAD:
|
||||
case COL_NCALLS_PER_PARENT:
|
||||
case COL_NCALLS_PER_FRAME:
|
||||
case COL_NCALLS_PER_AREA:
|
||||
{
|
||||
return data(col, Qt::UserRole).toUInt() < _other.data(col, Qt::UserRole).toUInt();
|
||||
}
|
||||
|
||||
case COL_SELF_DURATION_PERCENT:
|
||||
case COL_SELF_TIME_PERCENT:
|
||||
case COL_PERCENT_PER_PARENT:
|
||||
case COL_PERCENT_PER_FRAME:
|
||||
case COL_PERCENT_SUM_PER_PARENT:
|
||||
case COL_PERCENT_SUM_PER_FRAME:
|
||||
case COL_PERCENT_SUM_PER_THREAD:
|
||||
case COL_PERCENT_PER_AREA:
|
||||
case COL_PERCENT_SUM_PER_AREA:
|
||||
{
|
||||
return data(col, Qt::UserRole).toInt() < _other.data(col, Qt::UserRole).toInt();
|
||||
}
|
||||
@ -166,6 +187,11 @@ bool TreeWidgetItem::operator < (const Parent& _other) const
|
||||
}
|
||||
}
|
||||
|
||||
bool TreeWidgetItem::isPartial() const
|
||||
{
|
||||
return m_partial;
|
||||
}
|
||||
|
||||
bool TreeWidgetItem::hasToolTip(int _column) const
|
||||
{
|
||||
const int bit = ColumnBit[_column];
|
||||
@ -194,16 +220,143 @@ QVariant TreeWidgetItem::data(int _column, int _role) const
|
||||
switch (_role)
|
||||
{
|
||||
case Qt::ForegroundRole:
|
||||
return m_bMain ? QVariant::fromValue(QColor::fromRgb(profiler_gui::SELECTED_THREAD_FOREGROUND)) : QVariant();
|
||||
{
|
||||
if (m_bMain)
|
||||
return QVariant::fromValue(QColor::fromRgb(profiler_gui::SELECTED_THREAD_FOREGROUND));
|
||||
auto fg = Parent::data(_column, _role);
|
||||
if (!fg.isNull())
|
||||
return fg;
|
||||
if (m_partial)
|
||||
return partialForeground();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
return hasToolTip(_column) ?
|
||||
QVariant::fromValue(QString("%1 ns").arg(QTreeWidgetItem::data(_column, Qt::UserRole).toULongLong())) :
|
||||
QVariant();
|
||||
{
|
||||
if (hasToolTip(_column))
|
||||
return QVariant::fromValue(QString("%1 ns").arg(data(_column, Qt::UserRole).toULongLong()));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return QTreeWidgetItem::data(_column, _role);
|
||||
{
|
||||
if (_role != Qt::UserRole && _role != Qt::DisplayRole)
|
||||
return QTreeWidgetItem::data(_column, _role);
|
||||
return relevantData(_column, _role);
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant TreeWidgetItem::relevantData(int _column, int _role) const
|
||||
{
|
||||
switch (_column)
|
||||
{
|
||||
case COL_NAME:
|
||||
case COL_BEGIN:
|
||||
case COL_END:
|
||||
case COL_NCALLS_PER_PARENT:
|
||||
case COL_NCALLS_PER_FRAME:
|
||||
case COL_NCALLS_PER_THREAD:
|
||||
case COL_NCALLS_PER_AREA:
|
||||
case COL_SELF_TIME:
|
||||
case COL_SELF_TIME_PERCENT:
|
||||
case COL_ACTIVE_TIME:
|
||||
case COL_ACTIVE_PERCENT:
|
||||
case COL_PERCENT_PER_PARENT:
|
||||
case COL_PERCENT_PER_FRAME:
|
||||
case COL_PERCENT_PER_AREA:
|
||||
case COL_PERCENT_SUM_PER_THREAD:
|
||||
{
|
||||
return Parent::data(_column, _role);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto var = Parent::data(_column, _role);
|
||||
if (!var.isNull() || (EASY_GLOBALS.display_only_relevant_stats && _role == Qt::DisplayRole))
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
switch (_column)
|
||||
{
|
||||
case COL_TOTAL_TIME_PER_PARENT:
|
||||
case COL_TOTAL_TIME_PER_FRAME:
|
||||
case COL_TOTAL_TIME_PER_THREAD:
|
||||
case COL_TOTAL_TIME_PER_AREA:
|
||||
case COL_MIN_PER_PARENT:
|
||||
case COL_MIN_PER_FRAME:
|
||||
case COL_MIN_PER_THREAD:
|
||||
case COL_MIN_PER_AREA:
|
||||
case COL_MAX_PER_PARENT:
|
||||
case COL_MAX_PER_FRAME:
|
||||
case COL_MAX_PER_THREAD:
|
||||
case COL_MAX_PER_AREA:
|
||||
case COL_AVG_PER_PARENT:
|
||||
case COL_AVG_PER_FRAME:
|
||||
case COL_AVG_PER_THREAD:
|
||||
case COL_AVG_PER_AREA:
|
||||
{
|
||||
return Parent::data(COL_TIME, _role);
|
||||
}
|
||||
|
||||
case COL_PERCENT_SUM_PER_PARENT:
|
||||
{
|
||||
return Parent::data(COL_PERCENT_PER_PARENT, _role);
|
||||
}
|
||||
|
||||
case COL_PERCENT_SUM_PER_FRAME:
|
||||
{
|
||||
return Parent::data(COL_PERCENT_PER_FRAME, _role);
|
||||
}
|
||||
|
||||
case COL_PERCENT_SUM_PER_AREA:
|
||||
{
|
||||
return Parent::data(COL_PERCENT_PER_AREA, _role);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
QVariant TreeWidgetItem::partialForeground() const
|
||||
{
|
||||
const auto mode = static_cast<const BlocksTreeWidget*>(treeWidget())->mode();
|
||||
profiler::calls_number_t ncalls = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case TreeMode::Plain:
|
||||
{
|
||||
ncalls = data(COL_NCALLS_PER_FRAME, Qt::UserRole).toUInt();
|
||||
break;
|
||||
}
|
||||
|
||||
case TreeMode::SelectedArea:
|
||||
{
|
||||
ncalls = data(COL_NCALLS_PER_AREA, Qt::UserRole).toUInt();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ncalls < 3)
|
||||
return QVariant::fromValue(QColor::fromRgb(profiler::colors::Grey500));
|
||||
|
||||
return QVariant::fromValue(QColor::fromRgb(profiler::colors::Grey700));
|
||||
}
|
||||
|
||||
profiler::block_index_t TreeWidgetItem::block_index() const
|
||||
@ -221,16 +374,26 @@ const profiler::BlocksTree& TreeWidgetItem::block() const
|
||||
return easyBlocksTree(m_block);
|
||||
}
|
||||
|
||||
profiler::thread_id_t TreeWidgetItem::threadId() const
|
||||
{
|
||||
const QTreeWidgetItem* parentItem = this;
|
||||
while (parentItem->parent() != nullptr)
|
||||
{
|
||||
parentItem = parent();
|
||||
}
|
||||
return static_cast<profiler::thread_id_t>(parentItem->data(COL_NAME, Qt::UserRole).toULongLong());
|
||||
}
|
||||
|
||||
profiler::timestamp_t TreeWidgetItem::duration() const
|
||||
{
|
||||
if (parent() != nullptr)
|
||||
return block().node->duration();
|
||||
return data(COL_DURATION, Qt::UserRole).toULongLong();
|
||||
return data(COL_TIME, Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
profiler::timestamp_t TreeWidgetItem::selfDuration() const
|
||||
{
|
||||
return data(COL_SELF_DURATION, Qt::UserRole).toULongLong();
|
||||
return data(COL_SELF_TIME, Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
void TreeWidgetItem::setTimeSmart(int _column, profiler_gui::TimeUnits _units, const profiler::timestamp_t& _time, const QString& _prefix)
|
||||
@ -240,23 +403,6 @@ void TreeWidgetItem::setTimeSmart(int _column, profiler_gui::TimeUnits _units, c
|
||||
setData(_column, Qt::UserRole, (quint64)nanosecondsTime);
|
||||
setHasToolTip(_column);
|
||||
setText(_column, QString("%1%2").arg(_prefix).arg(profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3)));
|
||||
|
||||
// if (_time < 1e3)
|
||||
// {
|
||||
// setText(_column, QString("%1%2 ns").arg(_prefix).arg(nanosecondsTime));
|
||||
// }
|
||||
// else if (_time < 1e6)
|
||||
// {
|
||||
// setText(_column, QString("%1%2 us").arg(_prefix).arg(double(nanosecondsTime) * 1e-3, 0, 'f', 3));
|
||||
// }
|
||||
// else if (_time < 1e9)
|
||||
// {
|
||||
// setText(_column, QString("%1%2 ms").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'f', 3));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// setText(_column, QString("%1%2 s").arg(_prefix).arg(double(nanosecondsTime) * 1e-9, 0, 'f', 3));
|
||||
// }
|
||||
}
|
||||
|
||||
void TreeWidgetItem::setTimeSmart(int _column, profiler_gui::TimeUnits _units, const profiler::timestamp_t& _time)
|
||||
@ -294,6 +440,11 @@ void TreeWidgetItem::setMain(bool _main)
|
||||
m_bMain = _main;
|
||||
}
|
||||
|
||||
void TreeWidgetItem::setPartial(bool partial)
|
||||
{
|
||||
m_partial = partial;
|
||||
}
|
||||
|
||||
void TreeWidgetItem::collapseAll()
|
||||
{
|
||||
for (int i = 0, childrenNumber = childCount(); i < childrenNumber; ++i)
|
||||
@ -320,7 +471,9 @@ void TreeWidgetItem::expandAll()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TreeWidgetItemDelegate::TreeWidgetItemDelegate(QTreeWidget* parent) : QStyledItemDelegate(parent), m_treeWidget(parent)
|
||||
TreeWidgetItemDelegate::TreeWidgetItemDelegate(BlocksTreeWidget* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_treeWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
@ -337,9 +490,11 @@ void TreeWidgetItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem
|
||||
{
|
||||
// Draw item as usual
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
highlightMatchingText(painter, option, index);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto padding = px(2);
|
||||
const auto colorBlockSize = option.rect.height() >> 1;
|
||||
const auto currentTreeIndex = m_treeWidget->currentIndex();
|
||||
if (index.parent() == currentTreeIndex.parent() && index.row() == currentTreeIndex.row())
|
||||
@ -348,16 +503,17 @@ void TreeWidgetItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem
|
||||
painter->save();
|
||||
painter->setBrush(m_treeWidget->palette().highlight());
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRect(QRect(option.rect.left(), option.rect.top(), colorBlockSize, option.rect.height()));
|
||||
painter->drawRect(QRect(option.rect.left(), option.rect.top(), colorBlockSize + padding, option.rect.height()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// Adjust rect size for drawing color marker
|
||||
QStyleOptionViewItem opt = option;
|
||||
opt.rect.adjust(colorBlockSize, 0, 0, 0);
|
||||
opt.rect.adjust(colorBlockSize + padding, 0, 0, 0);
|
||||
|
||||
// Draw item as usual
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
highlightMatchingText(painter, opt, index);
|
||||
|
||||
const auto colorBlockRest = option.rect.height() - colorBlockSize;
|
||||
|
||||
@ -374,7 +530,117 @@ void TreeWidgetItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem
|
||||
const auto bottomLeft = opt.rect.bottomLeft();
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->setPen(profiler_gui::SYSTEM_BORDER_COLOR);
|
||||
painter->drawLine(QPoint(bottomLeft.x() - colorBlockSize, bottomLeft.y()), bottomLeft);
|
||||
painter->drawLine(QPoint(bottomLeft.x() - colorBlockSize - padding, bottomLeft.y()), bottomLeft);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void TreeWidgetItemDelegate::highlightMatchingText(
|
||||
QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index
|
||||
) const {
|
||||
if (m_treeWidget->lastFoundItem() != nullptr && !m_treeWidget->searchString().isEmpty())
|
||||
{
|
||||
// Highlight matching word
|
||||
auto displayData = m_treeWidget->model()->data(index);
|
||||
if (displayData.canConvert<QString>())
|
||||
{
|
||||
const auto text = displayData.toString();
|
||||
const auto caseSensitivity = m_treeWidget->caseSensitiveSearch() ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||
if (text.contains(m_treeWidget->searchString(), caseSensitivity))
|
||||
{
|
||||
auto lastFoundIndex = m_treeWidget->indexFromItem(m_treeWidget->lastFoundItem(), index.column());
|
||||
highlightMatchingText(
|
||||
painter,
|
||||
option,
|
||||
text,
|
||||
m_treeWidget->searchString(),
|
||||
caseSensitivity,
|
||||
lastFoundIndex == index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TreeWidgetItemDelegate::highlightMatchingText(
|
||||
QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QString& text,
|
||||
const QString& pattern,
|
||||
Qt::CaseSensitivity caseSensitivity,
|
||||
bool current
|
||||
) const {
|
||||
const auto padding = px(2);
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setDefaultFont(painter->font());
|
||||
doc.setTextWidth(option.rect.width() - padding);
|
||||
|
||||
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, std::max(option.rect.width() - padding, 0));
|
||||
doc.setHtml(elidedText);
|
||||
|
||||
TextHighlighter highlighter(
|
||||
&doc,
|
||||
painter->pen().color(),
|
||||
QColor::fromRgb(profiler::colors::Grey100),
|
||||
pattern,
|
||||
caseSensitivity,
|
||||
current
|
||||
);
|
||||
|
||||
painter->save();
|
||||
|
||||
#ifdef _WIN32
|
||||
EASY_CONSTEXPR int fixed_padding_x = -1;
|
||||
EASY_CONSTEXPR int fixed_padding_y = 0;
|
||||
#else
|
||||
EASY_CONSTEXPR int fixed_padding_x = -1;
|
||||
EASY_CONSTEXPR int fixed_padding_y = -1;
|
||||
#endif
|
||||
|
||||
auto dh = std::max((option.rect.height() - doc.size().height()) * 0.5, 0.);
|
||||
painter->translate(option.rect.left() + fixed_padding_x, option.rect.top() + dh + fixed_padding_y);
|
||||
|
||||
QRect clip(0, 0, option.rect.width(), option.rect.height());
|
||||
painter->setClipRect(clip);
|
||||
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
ctx.clip = clip;
|
||||
ctx.palette.setColor(QPalette::Text, Qt::transparent);
|
||||
doc.documentLayout()->draw(painter, ctx);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize TreeWidgetItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
auto* tree = m_treeWidget;
|
||||
if (tree == nullptr)
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
|
||||
auto* model = tree->model();
|
||||
if (model == nullptr)
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
|
||||
auto displayData = m_treeWidget->model()->data(index);
|
||||
if (!displayData.canConvert<QString>())
|
||||
{
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
}
|
||||
|
||||
// unfortunately, Qt does not take padding into account, so have to add it manually...
|
||||
const auto padding = px(15);
|
||||
auto text = displayData.toString();
|
||||
const auto width = static_cast<int>((m_treeWidget->fontMetrics().width(text) + padding) * 1.05);
|
||||
|
||||
const auto brushData = m_treeWidget->model()->data(index, BlockColorRole);
|
||||
if (brushData.isNull())
|
||||
{
|
||||
return QSize(width, option.rect.height());
|
||||
}
|
||||
|
||||
const auto colorBlockSize = option.rect.height() >> 1;
|
||||
return QSize(width + colorBlockSize + px(2), option.rect.height());
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user