1
+ /* *
2
+ * @file search_bar.cpp
3
+ * @author Sebastian Lievano
4
+ * @brief Contains search/auto-complete related functions
5
+ * @version 0.1
6
+ * @date 2022-07-20
7
+ *
8
+ * This file essentially follows the whole search process, from searching, finding the match,
9
+ * and finally highlighting the searched for item. Additionally, auto-complete related stuff is found
10
+ * here.
11
+ *
12
+ * @copyright Copyright (c) 2022
13
+ *
14
+ */
15
+
1
16
#ifndef NO_GRAPHICS
2
17
# include < cstdio>
3
18
# include < sstream>
@@ -94,20 +109,25 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) {
94
109
}
95
110
96
111
else if (search_type == " Block Name" ) {
112
+ /* If the block exists in atom netlist, proceeding with highlighting process.
113
+ * if highlight atom block fn returns false, that means that the block can't be highlighted
114
+ * We've already confirmed the block exists in the netlist, so that means that at this zoom lvl,
115
+ * the subblock is not shown. Therefore highlight the clb mapping.
116
+ *
117
+ * If the block does not exist in the atom netlist, we will check the CLB netlist to see if
118
+ * they searched for a cluster block*/
97
119
std::string block_name = " " ;
98
120
ss >> block_name;
99
121
100
- AtomBlockId atom_blk_id = AtomBlockId::INVALID ();
101
- atom_blk_id = atom_ctx.nlist .find_block (block_name);
102
- // If block is found, the CLB containing it is highlighted
122
+ AtomBlockId atom_blk_id = atom_ctx.nlist .find_block (block_name);
103
123
if (atom_blk_id != AtomBlockId::INVALID ()) {
104
124
ClusterBlockId block_id = atom_ctx.lookup .atom_clb (atom_blk_id);
105
- // Highlighting atom block. IF function returns false, highlighting clb that contains
106
125
if (!highlight_atom_block (atom_blk_id, block_id, app)) {
107
126
highlight_cluster_block (block_id);
108
127
}
109
128
return ;
110
129
}
130
+
111
131
// Continues if atom block not found (Checking if user searched a clb)
112
132
ClusterBlockId block_id = ClusterBlockId::INVALID ();
113
133
block_id = cluster_ctx.clb_nlist .find_block (block_name);
@@ -134,10 +154,11 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) {
134
154
}
135
155
136
156
else if (search_type == " Net Name" ) {
157
+ // in this case, all nets (clb and non-clb) are contained in the atom netlist
158
+ // So we only need to search this one
137
159
std::string net_name = " " ;
138
160
ss >> net_name;
139
- AtomNetId atom_net_id = AtomNetId::INVALID ();
140
- atom_net_id = atom_ctx.nlist .find_net (net_name);
161
+ AtomNetId atom_net_id = atom_ctx.nlist .find_net (net_name);
141
162
142
163
if (atom_net_id == AtomNetId::INVALID ()) {
143
164
warning_dialog_box (" Invalid Net Name" );
@@ -314,7 +335,7 @@ bool highlight_atom_block(AtomBlockId atom_blk, ClusterBlockId cl_blk, ezgl::app
314
335
*
315
336
* @param name name of block being searched for
316
337
* @param pb current node to be examined
317
- * @return t_pb* t_pb ptr of block w. name "name"
338
+ * @return t_pb* t_pb ptr of block w. name "name". Returns nullptr if nothing found
318
339
*/
319
340
t_pb* find_atom_block_in_pb (std::string name, t_pb* pb) {
320
341
// Checking if block is one being searched for
@@ -350,6 +371,7 @@ void highlight_nets(ClusterNetId net_id) {
350
371
351
372
t_draw_state* draw_state = get_draw_state_vars ();
352
373
374
+ // If routing does not exist return
353
375
if (int (route_ctx.trace .size ()) == 0 ) return ;
354
376
355
377
for (tptr = route_ctx.trace [net_id].head ; tptr != nullptr ; tptr = tptr->next ) {
@@ -422,8 +444,8 @@ void search_type_changed(GtkComboBox* self, ezgl::application* app) {
422
444
}
423
445
424
446
/* *
425
- * @brief A new matching function used for the wildcard search options
426
- * Will be slower
447
+ * @brief A non-default matching function. As opposed to simply searching for a prefix(default),
448
+ * searches string for presence of a substring. Ignores cases.
427
449
*
428
450
* @param completer the GtkEntryCompletion being used
429
451
* @param key a normalized and case-folded key representing the text
@@ -448,46 +470,76 @@ gboolean customMatchingFunction(
448
470
return (cppText.find (key, 0 ) != std::string::npos);
449
471
}
450
472
451
- void enable_autocomplete (ezgl::application* app){
473
+ /* *
474
+ * @brief Creates a GdkEvent that simulates user pressing key "key"
475
+ *
476
+ * @param key character value
477
+ * @param window GdkWindow
478
+ * @return GdkEvent Keypress event
479
+ */
480
+ GdkEvent simulate_keypress (char key, GdkWindow* window) {
481
+ int charVal = (int )key;
482
+ // Creating event and adding properties
483
+ GdkEvent new_event;
484
+ new_event.key .type = GDK_KEY_PRESS;
485
+ new_event.key .window = window;
486
+ new_event.key .send_event = TRUE ;
487
+ new_event.key .time = GDK_CURRENT_TIME;
488
+ new_event.key .keyval = gdk_unicode_to_keyval (charVal);
489
+ new_event.key .state = GDK_KEY_PRESS_MASK;
490
+ new_event.key .length = 0 ;
491
+ new_event.key .string = 0 ;
492
+ new_event.key .hardware_keycode = 0 ;
493
+ new_event.key .group = 0 ;
494
+ return new_event;
495
+ }
496
+
497
+ /* *
498
+ * @brief Turns on autocomplete
499
+ *
500
+ * This function enables the auto-complete fuctionality for the search bar.
501
+ * Normally, this is pretty simple, but the idea is to have auto-complete appear as soon
502
+ * as the user hits the "Enter" key. To accomplish this, a fake Gdk event is created
503
+ * to simulate the user hitting a key.
504
+ *
505
+ * @param app ezgl app
506
+ */
507
+ void enable_autocomplete (ezgl::application* app) {
452
508
std::cout << " enabling autocomplete" << std::endl;
453
509
GtkEntryCompletion* completion = GTK_ENTRY_COMPLETION (app->get_object (" Completion" ));
454
510
GtkEntry* searchBar = GTK_ENTRY (app->get_object (" TextInput" ));
511
+
455
512
std::string searchType = get_search_type (app);
456
- if (gtk_entry_completion_get_model (completion) == NULL ){
513
+ // Checking to make sure that we are on a mode that uses auto-complete
514
+ if (gtk_entry_completion_get_model (completion) == NULL ) {
457
515
std::cout << " NO MODEL SELECTED" << std::endl;
458
516
return ;
459
517
}
518
+
519
+ // Getting input text
460
520
std::string oldText (gtk_entry_get_text (searchBar));
521
+
522
+ // Turning on completion
461
523
gtk_entry_set_completion (searchBar, completion);
462
- gtk_entry_completion_set_minimum_key_length (completion, std::max (0 , (int )(oldText.length ()-1 )));
463
524
gtk_entry_completion_complete (completion);
464
525
465
- if (oldText.length () == 0 ) return ;
526
+ // Setting min key length to either 0 or 1 less than key length (max option)
527
+ gtk_entry_completion_set_minimum_key_length (completion, std::max (0 , (int )(oldText.length () - 1 )));
466
528
529
+ // If string len is 0, reutrning
530
+ if (oldText.length () == 0 ) return ;
467
531
468
- std::cout << " Added text" << std::endl;
469
532
gtk_widget_grab_focus (GTK_WIDGET (searchBar));
470
- std::string newText = (oldText.length () > 1 )? oldText.substr (0 , oldText.length ()- 1 ) : " " ;
533
+ std::string newText = (oldText.length () > 1 ) ? oldText.substr (0 , oldText.length () - 1 ) : " " ;
471
534
gtk_entry_set_text (searchBar, newText.c_str ());
472
- // for(int i = 0; i < oldText.length(); ++i){
473
-
474
- GdkEvent new_event;
475
- new_event.key .type = GDK_KEY_PRESS;
476
- new_event.key .window = gtk_widget_get_parent_window (GTK_WIDGET (searchBar));
477
- new_event.key .send_event = TRUE ;
478
- new_event.key .time = GDK_CURRENT_TIME;
479
- new_event.key .keyval = gdk_unicode_to_keyval ((int )oldText[oldText.length ()-1 ]);
480
- new_event.key .state = GDK_KEY_PRESS_MASK;
481
- new_event.key .length = 0 ;
482
- new_event.key .string = 0 ;
483
- new_event.key .hardware_keycode = 0 ;
484
- new_event.key .group = 0 ;
485
- gdk_event_put (&new_event);
486
- // }
487
- }
488
535
536
+ // Creating a false event to insert the last character into the string
537
+ auto window = gtk_widget_get_parent_window (GTK_WIDGET (searchBar));
538
+ GdkEvent new_event = simulate_keypress (oldText.back (), window);
539
+ gdk_event_put (&new_event);
540
+ }
489
541
490
- std::string get_search_type (ezgl::application* app){
542
+ std::string get_search_type (ezgl::application* app) {
491
543
GObject* combo_box = (GObject*)app->get_object (" SearchType" );
492
544
gchar* type = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo_box));
493
545
// Checking that a type is selected
0 commit comments