@@ -59,6 +59,60 @@ int32_t ConsoleWindow::ClearCommand(std::shared_ptr<Console> console, const std:
59
59
return 0 ;
60
60
}
61
61
62
+ int32_t ConsoleWindow::UnbindCommand (std::shared_ptr<Console> console, const std::vector<std::string>& args,
63
+ std::string* output) {
64
+ if (args.size () > 1 ) {
65
+ auto window = std::static_pointer_cast<ConsoleWindow>(
66
+ Context::GetInstance ()->GetWindow ()->GetGui ()->GetGuiWindow (" Console" ));
67
+ if (!window) {
68
+ if (output) {
69
+ *output += " A console window is necessary for Unbind" ;
70
+ }
71
+
72
+ return 1 ;
73
+ }
74
+
75
+ for (int k = ImGuiKey_NamedKey_BEGIN; k < ImGuiKey_NamedKey_END; k++) {
76
+ std::string key (ImGui::GetKeyName ((ImGuiKey)k));
77
+ bool unbound = false ;
78
+
79
+ if (toLowerCase (args[1 ]) == toLowerCase (key)) {
80
+ if (window->mBindings .contains ((ImGuiKey)k)) {
81
+ if (output) {
82
+ *output += " Unbound '" + args[1 ] + " from " + window->mBindings [(ImGuiKey)k];
83
+ }
84
+ window->mBindings .erase ((ImGuiKey)k);
85
+ unbound = true ;
86
+ }
87
+ if (window->mBindingToggle .contains ((ImGuiKey)k)) {
88
+ if (output) {
89
+ if (unbound) {
90
+ *output += " \n " ;
91
+ }
92
+ *output += " Unbound toggle '" + args[1 ] + " from " + window->mBindingToggle [(ImGuiKey)k];
93
+ }
94
+ window->mBindingToggle .erase ((ImGuiKey)k);
95
+ unbound = true ;
96
+ }
97
+
98
+ if (!unbound) {
99
+ if (output) {
100
+ *output += " Nothing bound to '" + args[1 ];
101
+ }
102
+ }
103
+ break ;
104
+ }
105
+ }
106
+ } else {
107
+ if (output) {
108
+ *output += " Not enough arguments" ;
109
+ }
110
+ return 1 ;
111
+ }
112
+
113
+ return 0 ;
114
+ }
115
+
62
116
int32_t ConsoleWindow::BindCommand (std::shared_ptr<Console> console, const std::vector<std::string>& args,
63
117
std::string* output) {
64
118
if (args.size () > 2 ) {
@@ -72,9 +126,7 @@ int32_t ConsoleWindow::BindCommand(std::shared_ptr<Console> console, const std::
72
126
return 1 ;
73
127
}
74
128
75
- const ImGuiIO* io = &ImGui::GetIO ();
76
-
77
- for (size_t k = 0 ; k < std::size (io->KeysData ); k++) {
129
+ for (int k = ImGuiKey_NamedKey_BEGIN; k < ImGuiKey_NamedKey_END; k++) {
78
130
std::string key (ImGui::GetKeyName ((ImGuiKey)k));
79
131
80
132
if (toLowerCase (args[1 ]) == toLowerCase (key)) {
@@ -112,9 +164,7 @@ int32_t ConsoleWindow::BindToggleCommand(std::shared_ptr<Console> console, const
112
164
return 1 ;
113
165
}
114
166
115
- const ImGuiIO* io = &ImGui::GetIO ();
116
-
117
- for (size_t k = 0 ; k < std::size (io->KeysData ); k++) {
167
+ for (int k = ImGuiKey_NamedKey_BEGIN; k < ImGuiKey_NamedKey_END; k++) {
118
168
std::string key (ImGui::GetKeyName ((ImGuiKey)k));
119
169
120
170
if (toLowerCase (args[1 ]) == toLowerCase (key)) {
@@ -254,9 +304,11 @@ void ConsoleWindow::InitElement() {
254
304
" Sets a console variable." ,
255
305
{ { " varName" , ArgumentType::TEXT }, { " varValue" , ArgumentType::TEXT } } });
256
306
Context::GetInstance ()->GetConsole ()->AddCommand (
257
- " get" , { GetCommand, " Bind key as a bool toggle " , { { " varName" , ArgumentType::TEXT } } });
307
+ " get" , { GetCommand, " Gets a console variable " , { { " varName" , ArgumentType::TEXT } } });
258
308
Context::GetInstance ()->GetConsole ()->AddCommand (" help" , { HelpCommand, " Shows all the commands" });
259
309
Context::GetInstance ()->GetConsole ()->AddCommand (" clear" , { ClearCommand, " Clear the console history" });
310
+ Context::GetInstance ()->GetConsole ()->AddCommand (
311
+ " unbind" , { UnbindCommand, " Unbinds a key" , { { " key" , ArgumentType::TEXT } } });
260
312
Context::GetInstance ()->GetConsole ()->AddCommand (
261
313
" bind" ,
262
314
{ BindCommand, " Binds key to commands" , { { " key" , ArgumentType::TEXT }, { " cmd" , ArgumentType::TEXT } } });
@@ -311,7 +363,7 @@ void ConsoleWindow::DrawElement() {
311
363
}
312
364
ImGui::EndTable ();
313
365
}
314
- if (ImGui::IsKeyPressed (ImGuiKey_Escape)) {
366
+ if (ImGui::IsKeyPressed (ImGuiKey_Escape, false )) {
315
367
mOpenAutocomplete = false ;
316
368
}
317
369
ImGui::PopStyleColor ();
@@ -333,7 +385,7 @@ void ConsoleWindow::DrawElement() {
333
385
334
386
// Renders top bar filters
335
387
if (ImGui::Button (" Clear" )) {
336
- mLog [ mCurrentChannel ]. clear ( );
388
+ ClearLogs ( mCurrentChannel );
337
389
}
338
390
339
391
if (CVarGetInteger (" gSinkEnabled" , 0 )) {
@@ -386,19 +438,20 @@ void ConsoleWindow::DrawElement() {
386
438
ImGuiWindowFlags_HorizontalScrollbar);
387
439
ImGui::PushStyleColor (ImGuiCol_FrameBgActive, ImVec4 (.3f , .3f , .3f , 1 .0f ));
388
440
if (ImGui::BeginTable (" History" , 1 )) {
441
+ bool focused = ImGui::IsWindowFocused (ImGuiFocusedFlags_ChildWindows);
442
+ const std::vector<ConsoleLine> channel = mLog [mCurrentChannel ];
389
443
390
- if (ImGui::IsKeyPressed (ImGuiKey_DownArrow)) {
391
- if (mSelectedId < (int32_t )mLog .size () - 1 ) {
444
+ if (focused && ImGui::IsKeyPressed (ImGuiKey_DownArrow)) {
445
+ if (mSelectedId < (int32_t )channel .size () - 1 ) {
392
446
++mSelectedId ;
393
447
}
394
448
}
395
- if (ImGui::IsKeyPressed (ImGuiKey_UpArrow)) {
449
+ if (focused && ImGui::IsKeyPressed (ImGuiKey_UpArrow)) {
396
450
if (mSelectedId > 0 ) {
397
451
--mSelectedId ;
398
452
}
399
453
}
400
454
401
- const std::vector<ConsoleLine> channel = mLog [mCurrentChannel ];
402
455
for (size_t i = 0 ; i < channel.size (); i++) {
403
456
ConsoleLine line = channel[i];
404
457
if (!mFilter .empty () && line.Text .find (mFilter ) == std::string::npos) {
@@ -442,6 +495,9 @@ void ConsoleWindow::DrawElement() {
442
495
ImGuiInputTextFlags_CallbackCompletion |
443
496
ImGuiInputTextFlags_CallbackHistory;
444
497
ImGui::PushItemWidth (-53 .0f );
498
+
499
+ float yBeforeInput = ImGui::GetCursorPosY ();
500
+
445
501
if (ImGui::InputTextWithHint (" ##CMDInput" , " >" , mInputBuffer , gMaxBufferSize , flags,
446
502
&ConsoleWindow::CallbackStub, this )) {
447
503
inputFocus = true ;
@@ -453,7 +509,8 @@ void ConsoleWindow::DrawElement() {
453
509
454
510
if (mCmdHint != " None" ) {
455
511
if (ImGui::IsItemFocused ()) {
456
- ImGui::SetNextWindowPos (ImVec2 (pos.x , pos.y + size.y ));
512
+ // Place the tooltip above the console input field
513
+ ImGui::SetNextWindowPos (ImVec2 (pos.x , pos.y + size.y - ((size.y - yBeforeInput) * 2 )));
457
514
ImGui::SameLine ();
458
515
ImGui::BeginTooltip ();
459
516
ImGui::PushTextWrapPos (ImGui::GetFontSize () * 35 .0f );
@@ -481,6 +538,7 @@ void ConsoleWindow::DrawElement() {
481
538
482
539
void ConsoleWindow::Dispatch (const std::string& line) {
483
540
mCmdHint = " None" ;
541
+ mHistoryIndex = -1 ;
484
542
mHistory .push_back (line);
485
543
SendInfoMessage (" > " + line);
486
544
auto console = Context::GetInstance ()->GetConsole ();
@@ -514,7 +572,6 @@ void ConsoleWindow::Dispatch(const std::string& line) {
514
572
int ConsoleWindow::CallbackStub (ImGuiInputTextCallbackData* data) {
515
573
const auto instance = static_cast <ConsoleWindow*>(data->UserData );
516
574
const bool emptyHistory = instance->mHistory .empty ();
517
- const int historyIndex = instance->mHistoryIndex ;
518
575
auto console = Context::GetInstance ()->GetConsole ();
519
576
std::string history;
520
577
@@ -533,23 +590,30 @@ int ConsoleWindow::CallbackStub(ImGuiInputTextCallbackData* data) {
533
590
if (emptyHistory) {
534
591
break ;
535
592
}
536
- if (historyIndex < static_cast <int >(instance->mHistory .size ()) - 1 ) {
537
- instance->mHistoryIndex += 1 ;
593
+ if (instance->mHistoryIndex > 0 ) {
594
+ instance->mHistoryIndex -= 1 ;
595
+ } else if (instance->mHistoryIndex < 0 ) {
596
+ instance->mHistoryIndex = static_cast <int >(instance->mHistory .size ()) - 1 ;
538
597
}
539
598
data->DeleteChars (0 , data->BufTextLen );
540
- data->InsertChars (0 , instance->mHistory [instance->mHistoryIndex ].c_str ());
599
+ if (instance->mHistoryIndex >= 0 ) {
600
+ data->InsertChars (0 , instance->mHistory [instance->mHistoryIndex ].c_str ());
601
+ }
541
602
instance->mCmdHint = " None" ;
542
603
break ;
543
604
case ImGuiKey_DownArrow:
544
605
if (emptyHistory) {
545
606
break ;
546
607
}
547
- if (historyIndex > -1 ) {
548
- instance->mHistoryIndex -= 1 ;
608
+ if (instance->mHistoryIndex >= 0 &&
609
+ instance->mHistoryIndex < static_cast <int >(instance->mHistory .size ()) - 1 ) {
610
+ instance->mHistoryIndex += 1 ;
611
+ } else {
612
+ instance->mHistoryIndex = -1 ;
549
613
}
550
614
data->DeleteChars (0 , data->BufTextLen );
551
- if (historyIndex >= 0 ) {
552
- data->InsertChars (0 , instance->mHistory [historyIndex ].c_str ());
615
+ if (instance-> mHistoryIndex >= 0 ) {
616
+ data->InsertChars (0 , instance->mHistory [instance-> mHistoryIndex ].c_str ());
553
617
}
554
618
instance->mCmdHint = " None" ;
555
619
break ;
@@ -591,7 +655,8 @@ void ConsoleWindow::Append(const std::string& channel, spdlog::level::level_enum
591
655
vsnprintf (buf.data (), buf.size (), fmt, args);
592
656
593
657
buf[buf.size () - 1 ] = 0 ;
594
- mLog [channel].push_back ({ std::string (buf.begin (), buf.end ()), priority });
658
+ // Do not copy the null terminator into the std::string
659
+ mLog [channel].push_back ({ std::string (buf.begin (), buf.end () - 1 ), priority });
595
660
}
596
661
597
662
void ConsoleWindow::Append (const std::string& channel, spdlog::level::level_enum priority, const char * fmt, ...) {
@@ -625,12 +690,16 @@ void ConsoleWindow::SendErrorMessage(const std::string& str) {
625
690
626
691
void ConsoleWindow::ClearLogs (std::string channel) {
627
692
mLog [channel].clear ();
693
+ mSelectedEntries .clear ();
694
+ mSelectedId = -1 ;
628
695
}
629
696
630
697
void ConsoleWindow::ClearLogs () {
631
698
for (auto [key, var] : mLog ) {
632
699
var.clear ();
633
700
}
701
+ mSelectedEntries .clear ();
702
+ mSelectedId = -1 ;
634
703
}
635
704
636
705
std::string ConsoleWindow::GetCurrentChannel () {
0 commit comments