1
- use egui:: { Align , Color32 , RichText , Ui } ;
1
+ use eframe:: emath:: Vec2 ;
2
+ use egui:: {
3
+ include_image, Align , Button , Color32 , CursorIcon , ImageSource , Response , RichText , Ui ,
4
+ } ;
2
5
use egui_extras:: { Column , TableBuilder , TableRow } ;
6
+ use egui_toast:: ToastKind ;
3
7
4
8
use crate :: app:: log_view:: { ColumnTextColor , LogViewerState } ;
5
9
6
10
use super :: log_file_reader:: { LineNumber , LogFileReader } ;
7
11
8
- #[ derive( Default ) ]
9
- pub struct LogEntriesResponse {
10
- pub selected_line_num : Option < LineNumber > ,
11
- }
12
-
13
12
pub struct LogEntriesTable < ' a > {
14
13
filtered_lines : Option < & ' a [ LineNumber ] > ,
15
14
selected_line : Option < usize > ,
16
15
scroll_to_selected : bool ,
17
16
}
18
17
19
18
impl < ' a > LogEntriesTable < ' a > {
19
+ fn add_tool_button (
20
+ ui : & mut egui:: Ui ,
21
+ image_source : ImageSource < ' _ > ,
22
+ hover_text : & str ,
23
+ ) -> Response {
24
+ ui. add_sized (
25
+ Vec2 :: new ( 14.0 , 14.0 ) ,
26
+ Button :: image ( image_source) . frame ( false ) ,
27
+ )
28
+ . on_hover_cursor ( CursorIcon :: PointingHand )
29
+ . on_hover_text ( hover_text)
30
+ }
31
+
20
32
pub fn new ( ) -> Self {
21
33
Self {
22
34
filtered_lines : None ,
@@ -45,9 +57,7 @@ impl<'a> LogEntriesTable<'a> {
45
57
ui : & mut Ui ,
46
58
log_file_reader : & mut LogFileReader ,
47
59
viewer_state : & mut LogViewerState ,
48
- ) -> LogEntriesResponse {
49
- let mut response: LogEntriesResponse = Default :: default ( ) ;
50
-
60
+ ) {
51
61
let total_rows = match self . filtered_lines {
52
62
Some ( lines) => lines. len ( ) ,
53
63
None => log_file_reader. line_count ( ) as usize ,
@@ -56,6 +66,7 @@ impl<'a> LogEntriesTable<'a> {
56
66
let mut table_builder = TableBuilder :: new ( ui)
57
67
. max_scroll_height ( f32:: INFINITY )
58
68
. cell_layout ( egui:: Layout :: left_to_right ( egui:: Align :: Center ) )
69
+ . striped ( true )
59
70
. sense ( egui:: Sense :: click ( ) ) ;
60
71
61
72
let mut col_iter = viewer_state. displayed_columns . iter ( ) . peekable ( ) ;
@@ -81,15 +92,32 @@ impl<'a> LogEntriesTable<'a> {
81
92
table_builder = table_builder. scroll_to_row ( selected_row, Some ( Align :: Center ) ) ;
82
93
}
83
94
}
95
+ self . scroll_to_selected = false ;
84
96
}
85
97
86
98
table_builder
87
99
. header ( 18.0 , |mut row| {
100
+ let columns_displayed_count = viewer_state. displayed_columns . len ( ) ;
101
+ let mut columns_to_remove: Vec < String > = vec ! [ ] ;
88
102
for displayed_column in & viewer_state. displayed_columns {
89
103
row. col ( |ui| {
90
104
ui. label ( RichText :: new ( displayed_column) . strong ( ) ) ;
105
+ if columns_displayed_count > 1 {
106
+ let rm_icon = include_image ! ( "../../assets/icons8-minus-48-white.png" ) ;
107
+ if Self :: add_tool_button ( ui, rm_icon, "Remove Column" ) . clicked ( ) {
108
+ columns_to_remove. push ( displayed_column. clone ( ) ) ;
109
+ }
110
+ }
91
111
} ) ;
92
112
}
113
+
114
+ if !columns_to_remove. is_empty ( ) {
115
+ viewer_state
116
+ . displayed_columns
117
+ . retain ( |c| !columns_to_remove. contains ( c) ) ;
118
+
119
+ viewer_state. add_toast ( ToastKind :: Info , "Removed column." . into ( ) , 2.0 ) ;
120
+ }
93
121
} )
94
122
. body ( |body| {
95
123
body. rows ( 16.0 , total_rows, |mut row| {
@@ -101,18 +129,14 @@ impl<'a> LogEntriesTable<'a> {
101
129
102
130
row. set_selected ( self . selected_line == Some ( line_number) ) ;
103
131
104
- if let Some ( logline_response) =
105
- Self :: ui_logline ( log_file_reader, viewer_state, & mut row, line_number)
106
- {
107
- if let Some ( selected_line_num) = logline_response. selected_line_num {
108
- viewer_state. selected_line_num = Some ( selected_line_num) ;
109
- response. selected_line_num = Some ( selected_line_num) ;
110
- }
132
+ Self :: ui_logline ( log_file_reader, viewer_state, & mut row, line_number) ;
133
+
134
+ if row. response ( ) . clicked ( ) {
135
+ self . selected_line = Some ( line_number) ;
136
+ viewer_state. selected_line_num = self . selected_line ;
111
137
}
112
138
} ) ;
113
139
} ) ;
114
-
115
- response
116
140
}
117
141
118
142
/// Maps a line number to a table row.
@@ -130,16 +154,19 @@ impl<'a> LogEntriesTable<'a> {
130
154
viewer_state : & mut LogViewerState ,
131
155
row : & mut TableRow < ' _ , ' _ > ,
132
156
line_num : LineNumber ,
133
- ) -> Option < LogEntriesResponse > {
134
- let mut response: LogEntriesResponse = Default :: default ( ) ;
157
+ ) -> Option < ( ) > {
135
158
let log_line = log_file_reader. read_line ( line_num) ?;
136
159
137
160
match LogFileReader :: parse_logline ( & log_line) {
138
161
Some ( log_entry) => {
139
162
for column_str in & viewer_state. displayed_columns {
140
163
row. col ( |ui| {
141
164
let column_value = & log_entry. object [ column_str] ;
142
- let full_col_text = if column_value. is_empty ( ) { String :: new ( ) } else { column_value. to_string ( ) } ;
165
+ let full_col_text = if column_value. is_empty ( ) {
166
+ String :: new ( )
167
+ } else {
168
+ column_value. to_string ( )
169
+ } ;
143
170
let mut column_text = if let Some ( split) = full_col_text. split_once ( '\n' ) {
144
171
split. 0
145
172
} else {
@@ -179,13 +206,7 @@ impl<'a> LogEntriesTable<'a> {
179
206
}
180
207
}
181
208
182
- if row. response ( ) . clicked ( ) {
183
- response = LogEntriesResponse {
184
- selected_line_num : Some ( line_num) ,
185
- } ;
186
- }
187
-
188
- Some ( response)
209
+ Some ( ( ) )
189
210
}
190
211
}
191
212
0 commit comments