@@ -48,7 +48,9 @@ static void settings_save(const AppSettings& s, const std::string& path) {
4848 f << " \" show_status_bar\" : " << (s.show_status_bar ? " true" : " false" ) << " ,\n " ;
4949 f << " \" word_wrap\" : " << (s.word_wrap ? " true" : " false" ) << " ,\n " ;
5050 f << " \" show_line_numbers\" : " << (s.show_line_numbers ? " true" : " false" ) << " ,\n " ;
51+ f << " \" tab_size\" : " << s.tab_size << " ,\n " ;
5152 f << " \" font_size\" : " << s.font_size << " ,\n " ;
53+ f << " \" font_name\" : \" " << json_escape (s.font_name ) << " \" ,\n " ;
5254 f << " \" last_open_dir\" : \" " << json_escape (s.last_open_dir ) << " \" ,\n " ;
5355 f << " \" recent_files\" : [" ;
5456 for (size_t i = 0 ; i < s.recent_files .size (); i++) {
@@ -96,7 +98,9 @@ static void settings_load(AppSettings& s, const std::string& path) {
9698 s.show_status_bar = get_bool (" show_status_bar" , true );
9799 s.word_wrap = get_bool (" word_wrap" , false );
98100 s.show_line_numbers = get_bool (" show_line_numbers" , true );
101+ s.tab_size = get_int (" tab_size" , 4 );
99102 s.font_size = get_int (" font_size" , 16 );
103+ s.font_name = get_str (" font_name" );
100104 s.last_open_dir = get_str (" last_open_dir" );
101105
102106 // Parse recent files array
@@ -122,6 +126,8 @@ static void settings_load(AppSettings& s, const std::string& path) {
122126// ============================================================================
123127EditorApp::EditorApp () {
124128 new_tab (); // Start with one untitled tab
129+ font_size_temp_ = settings_.font_size ;
130+ tab_size_temp_ = settings_.tab_size ;
125131}
126132
127133EditorApp::~EditorApp () {
@@ -195,7 +201,10 @@ void EditorApp::init() {
195201 ImGuiIO& io = ImGui::GetIO ();
196202 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
197203 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
204+
205+ // Apply initial font settings
198206 io.FontGlobalScale = settings_.font_size / 16 .0f ;
207+ font_size_temp_ = settings_.font_size ;
199208
200209 apply_theme (settings_.dark_theme );
201210
@@ -205,10 +214,16 @@ void EditorApp::init() {
205214 // Apply initial settings to first tab
206215 if (!tabs_.empty ()) {
207216 TextEditor* ed = tabs_[0 ].editor ;
217+ int tab_idx = 0 ;
208218
209219 if (settings_.word_wrap ) {
210220 ed->SetImGuiChildIgnored (true );
211221 }
222+
223+ ed->SetTabSize (settings_.tab_size );
224+ ed->SetShowWhitespaces (false );
225+
226+ apply_zoom (tab_idx);
212227 }
213228}
214229
@@ -266,7 +281,8 @@ void EditorApp::new_tab() {
266281 tab.display_name = " untitled" ;
267282 tab.editor = new TextEditor ();
268283 tab.editor ->SetLanguageDefinition (TextEditor::LanguageDefinition::CPlusPlus ());
269-
284+ tab.editor ->SetTabSize (settings_.tab_size );
285+
270286 tab.editor ->SetText (" " );
271287 tabs_.push_back (std::move (tab));
272288 active_tab_ = (int )tabs_.size () - 1 ;
@@ -326,6 +342,7 @@ void EditorApp::open_file(const std::string& path) {
326342 tab.display_name = std::filesystem::path (selected_path).filename ().string ();
327343 tab.dirty = false ;
328344 tab.editor ->SetText (content);
345+ tab.editor ->SetTabSize (settings_.tab_size );
329346
330347 // Auto-detect language
331348 auto ext = std::filesystem::path (selected_path).extension ().string ();
@@ -341,6 +358,9 @@ void EditorApp::open_file(const std::string& path) {
341358
342359 settings_.last_open_dir = std::filesystem::path (selected_path).parent_path ().string ();
343360 add_recent_file (selected_path);
361+
362+ // Give focus to the editor
363+ ImGui::SetWindowFocus (" Editor" );
344364}
345365
346366bool EditorApp::save_tab (int idx) {
@@ -608,19 +628,51 @@ void EditorApp::toggle_status_bar() {
608628
609629void EditorApp::toggle_word_wrap () {
610630 settings_.word_wrap = !settings_.word_wrap ;
611- if (active_tab_ >= 0 && active_tab_ < (int )tabs_.size ()) {
612- tabs_[active_tab_].editor ->SetImGuiChildIgnored (settings_.word_wrap );
631+ // Apply to all tabs
632+ for (auto & tab : tabs_) {
633+ tab.editor ->SetImGuiChildIgnored (settings_.word_wrap );
613634 }
614635}
615636
616637void EditorApp::toggle_line_numbers () {
617638 settings_.show_line_numbers = !settings_.show_line_numbers ;
618- // TextEditor always shows line numbers — no toggle API available
639+ // Apply to all tabs - TextEditor always shows line numbers, but we can note the setting
640+ // The actual rendering will be controlled by our wrapper in render_editor_area
619641}
620642
621643void EditorApp::toggle_theme () {
622644 settings_.dark_theme = !settings_.dark_theme ;
623645 apply_theme (settings_.dark_theme );
646+
647+ // Apply theme to all tabs immediately
648+ for (auto & tab : tabs_) {
649+ if (settings_.dark_theme ) {
650+ tab.editor ->SetPalette (TextEditor::GetDarkPalette ());
651+ } else {
652+ tab.editor ->SetPalette (TextEditor::GetLightPalette ());
653+ }
654+ }
655+ }
656+
657+ void EditorApp::set_tab_size (int size) {
658+ if (size < 1 || size > 16 ) return ;
659+ settings_.tab_size = size;
660+
661+ // Apply to all tabs
662+ for (auto & tab : tabs_) {
663+ tab.editor ->SetTabSize (size);
664+ }
665+ }
666+
667+ void EditorApp::rebuild_fonts () {
668+ // For now, we just update the global font scale
669+ // In a full implementation, you would reload fonts from ImGui
670+ ImGui::GetIO ().FontGlobalScale = settings_.font_size / 16 .0f ;
671+
672+ // Apply to all tabs via zoom
673+ for (int i = 0 ; i < (int )tabs_.size (); i++) {
674+ apply_zoom (i);
675+ }
624676}
625677
626678// ============================================================================
@@ -723,6 +775,7 @@ void EditorApp::render() {
723775 if (show_replace_) render_replace_dialog ();
724776 if (show_goto_) render_goto_dialog ();
725777 if (show_font_) render_font_dialog ();
778+ if (show_spaces_dialog_) render_spaces_dialog ();
726779 if (show_cmd_palette_) render_command_palette ();
727780
728781 ImGui::End ();
@@ -822,6 +875,14 @@ void EditorApp::render_menu_view() {
822875 bool ln = settings_.show_line_numbers ;
823876 if (ImGui::MenuItem (" Line Numbers" , nullptr , &ln)) toggle_line_numbers ();
824877 ImGui::Separator ();
878+ if (ImGui::BeginMenu (" Spaces" )) {
879+ if (ImGui::MenuItem (" 2 Spaces" , nullptr , settings_.tab_size == 2 )) set_tab_size (2 );
880+ if (ImGui::MenuItem (" 4 Spaces" , nullptr , settings_.tab_size == 4 )) set_tab_size (4 );
881+ if (ImGui::MenuItem (" 8 Spaces" , nullptr , settings_.tab_size == 8 )) set_tab_size (8 );
882+ if (ImGui::MenuItem (" Custom..." )) { show_spaces_dialog_ = true ; tab_size_temp_ = settings_.tab_size ; }
883+ ImGui::EndMenu ();
884+ }
885+ ImGui::Separator ();
825886 if (ImGui::MenuItem (settings_.dark_theme ? " Light Theme" : " Dark Theme" )) toggle_theme ();
826887 ImGui::EndMenu ();
827888 }
@@ -1028,24 +1089,28 @@ void EditorApp::render_goto_dialog() {
10281089}
10291090
10301091void EditorApp::render_font_dialog () {
1031- ImGui::OpenPopup (" Font" );
1092+ ImGui::OpenPopup (" Font Settings " );
10321093 ImVec2 center = ImGui::GetMainViewport ()->GetCenter ();
10331094 ImGui::SetNextWindowPos (center, ImGuiCond_Appearing, ImVec2 (0 .5f , 0 .5f ));
10341095
1035- if (ImGui::BeginPopupModal (" Font" , &show_font_, ImGuiWindowFlags_AlwaysAutoResize)) {
1036- ImGui::Text (" Font size :" );
1096+ if (ImGui::BeginPopupModal (" Font Settings " , &show_font_, ImGuiWindowFlags_AlwaysAutoResize)) {
1097+ ImGui::Text (" Font Size (8-48) :" );
10371098 ImGui::SetNextItemWidth (100 );
10381099 ImGui::InputInt (" ##fontsize" , &font_size_temp_);
10391100 font_size_temp_ = std::max (8 , std::min (48 , font_size_temp_));
1101+
1102+ ImGui::Separator ();
1103+ ImGui::TextUnformatted (" Note: Font size changes apply to all tabs." );
1104+ ImGui::TextUnformatted (" Changing font family requires application restart." );
10401105
10411106 if (ImGui::Button (" Apply" )) {
10421107 settings_.font_size = font_size_temp_;
1043- ImGui::GetIO (). FontGlobalScale = font_size_temp_ / 16 . 0f ;
1108+ rebuild_fonts () ;
10441109 }
10451110 ImGui::SameLine ();
10461111 if (ImGui::Button (" OK" )) {
10471112 settings_.font_size = font_size_temp_;
1048- ImGui::GetIO (). FontGlobalScale = font_size_temp_ / 16 . 0f ;
1113+ rebuild_fonts () ;
10491114 show_font_ = false ;
10501115 }
10511116 ImGui::SameLine ();
@@ -1122,3 +1187,29 @@ void EditorApp::render_command_palette() {
11221187 ImGui::EndPopup ();
11231188 }
11241189}
1190+
1191+ void EditorApp::render_spaces_dialog () {
1192+ ImGui::OpenPopup (" Tab Size" );
1193+ ImVec2 center = ImGui::GetMainViewport ()->GetCenter ();
1194+ ImGui::SetNextWindowPos (center, ImGuiCond_Appearing, ImVec2 (0 .5f , 0 .5f ));
1195+
1196+ if (ImGui::BeginPopupModal (" Tab Size" , &show_spaces_dialog_, ImGuiWindowFlags_AlwaysAutoResize)) {
1197+ ImGui::Text (" Tab size (1-16):" );
1198+ ImGui::SetNextItemWidth (100 );
1199+ ImGui::InputInt (" ##tabsize" , &tab_size_temp_);
1200+ tab_size_temp_ = std::max (1 , std::min (16 , tab_size_temp_));
1201+
1202+ if (ImGui::Button (" Apply" )) {
1203+ set_tab_size (tab_size_temp_);
1204+ }
1205+ ImGui::SameLine ();
1206+ if (ImGui::Button (" OK" )) {
1207+ set_tab_size (tab_size_temp_);
1208+ show_spaces_dialog_ = false ;
1209+ }
1210+ ImGui::SameLine ();
1211+ if (ImGui::Button (" Cancel" )) show_spaces_dialog_ = false ;
1212+
1213+ ImGui::EndPopup ();
1214+ }
1215+ }
0 commit comments