diff --git a/Gtkmm3_Mac/CMakeLists.txt b/Gtkmm3_Mac/CMakeLists.txt
index 7d588fb..37ea2f2 100644
--- a/Gtkmm3_Mac/CMakeLists.txt
+++ b/Gtkmm3_Mac/CMakeLists.txt
@@ -44,6 +44,7 @@ set(RESOURCE_LIST
STRIPBLANKS game24.ui
STRIPBLANKS calcapp.ui
STRIPBLANKS text_menu.xml
+ STRIPBLANKS expender.ui
style.css
reset.css
dock_style.css
diff --git a/Gtkmm3_Mac/res/expender.ui b/Gtkmm3_Mac/res/expender.ui
new file mode 100644
index 0000000..ec05028
--- /dev/null
+++ b/Gtkmm3_Mac/res/expender.ui
@@ -0,0 +1,440 @@
+
+
+
+
+
+
diff --git a/Gtkmm3_Mac/src/apps/TextEditor.hh b/Gtkmm3_Mac/src/apps/TextEditor.hh
index 0542277..2238cf0 100644
--- a/Gtkmm3_Mac/src/apps/TextEditor.hh
+++ b/Gtkmm3_Mac/src/apps/TextEditor.hh
@@ -2,18 +2,20 @@
#include
-class TextEditor : public Gtk::ApplicationWindow{
+class TextEditor : public Gtk::ApplicationWindow
+{
public:
TextEditor();
+
private:
- //Header widgets
+ // Header widgets
Gtk::HeaderBar header;
Gtk::MenuButton menubtn;
Gtk::Popover popover;
Gtk::ToggleButton search_button;
- Glib::RefPtr menu_builder;
+ Glib::RefPtr menu_builder, expend_builder;
- //SearchBar
+ // SearchBar
Gtk::SearchBar searchbar;
Gtk::SearchEntry search_entry;
Gtk::Box searchbox;
@@ -21,20 +23,24 @@ private:
Glib::RefPtr search_binding;
Gtk::TextIter curr_iter_up, curr_iter_down;
- //Window widgets
- Gtk::Box vbox,hbox,*infobox;
- Gtk::ScrolledWindow sw1,sw2;
+ // Window widgets
+ Gtk::Box vbox, hbox, *infobox;
+ Gtk::ScrolledWindow sw1;
Glib::RefPtr buffer1;
Gtk::TextView textview1;
Gtk::InfoBar infobar;
Gtk::Label label1;
+ Gtk::Expander *expender;
+ Gtk::Button *btns[26], *btntab, *btnenter;
+ Gtk::ToggleButton *btnshift, *btncaps;
- //File Dialog
+ // File Dialog
Glib::RefPtr dialog;
Glib::ustring curr_filename;
bool file_opened;
- //Signal Handlers
+ // Signal Handlers
+ bool window_delete_event(GdkEventAny *event);
// File Operation functions
void btnopen_clicked();
@@ -55,4 +61,12 @@ private:
void search_entry_changed();
void search_forward();
void search_backward();
+
+ // Keyboard press
+ void key_pressed(Gtk::Button *button);
+ void btntab_clicked();
+ void btnenter_clicked();
+
+ // Other Signal Handlers
+ void about_activated();
};
diff --git a/Gtkmm3_Mac/src/text_app/TextEditor.cc b/Gtkmm3_Mac/src/text_app/TextEditor.cc
index 89e2a22..192fb91 100644
--- a/Gtkmm3_Mac/src/text_app/TextEditor.cc
+++ b/Gtkmm3_Mac/src/text_app/TextEditor.cc
@@ -1,9 +1,11 @@
#include "TextEditor.hh"
#include "text_types.hh"
+#include "../json_nlohmann/json.hpp"
#include
+#include
+#include
-// Only for build in this repository
-// #define text_globs supported_globs
+using json = nlohmann::json;
TextEditor::TextEditor()
: vbox(Gtk::ORIENTATION_VERTICAL, 5),
@@ -11,8 +13,19 @@ TextEditor::TextEditor()
searchbox(Gtk::ORIENTATION_HORIZONTAL, 5),
file_opened(false)
{
+ // Load window config from json file
+ int width = 800, height = 450;
+ std::ifstream json_file("text_config.json");
+ if (json_file.is_open())
+ {
+ json data = json::parse(json_file);
+ width = data["width"];
+ height = data["height"];
+ }
+ json_file.close();
+
// Initalize Window
- set_default_size(800, 450);
+ set_default_size(width, height);
set_icon_name("my_textedit");
// Initalize HeaderBar
@@ -48,6 +61,7 @@ TextEditor::TextEditor()
add_action("text_copy", sigc::mem_fun(*this, &TextEditor::btncopy_clicked));
add_action("text_paste", sigc::mem_fun(*this, &TextEditor::btnpaste_clicked));
add_action("text_close", sigc::mem_fun(*this, &TextEditor::btnclose_clicked));
+ add_action("text_about", sigc::mem_fun(*this, &TextEditor::about_activated));
// Add searchbar and search up and down buttons
search_up.set_image_from_icon_name("up");
@@ -74,14 +88,84 @@ TextEditor::TextEditor()
infobox = dynamic_cast(infobar.get_content_area());
infobox->pack_start(label1);
vbox.pack_start(infobar, Gtk::PACK_SHRINK);
+ vbox.pack_start(hbox);
+
+ // Save config when the window is closed
+ signal_delete_event().connect(sigc::mem_fun(*this, &TextEditor::window_delete_event));
+
+ // Add Intergated keyboard
+ expend_builder = Gtk::Builder::create_from_resource("/org/gtk/daleclack/expender.ui");
+ expend_builder->get_widget("key_expend", expender);
+ expend_builder->get_widget("btnshift", btnshift);
+ expend_builder->get_widget("btn_caps", btncaps);
+ expend_builder->get_widget("btntab", btntab);
+ expend_builder->get_widget("btnenter", btnenter);
+ vbox.pack_start(*expender, Gtk::PACK_SHRINK);
+
+ // Get alphabet buttons
+ for(int i = 0; i < 26; i++){
+ char name[10];
+ sprintf(name, "btn%d", i);
+ expend_builder->get_widget(name, btns[i]);
+ btns[i]->signal_clicked().connect(sigc::bind(
+ sigc::mem_fun(*this, &TextEditor::key_pressed),
+ btns[i]
+ ));
+ }
+ btntab->signal_clicked().connect(sigc::mem_fun(*this, &TextEditor::btntab_clicked));
+ btnenter->signal_clicked().connect(sigc::mem_fun(*this, &TextEditor::btnenter_clicked));
// Show everything
- vbox.pack_start(hbox);
add(vbox);
show_all_children();
infobar.hide();
}
+void TextEditor::key_pressed(Gtk::Button *button){
+ auto label = button->get_label();
+ Glib::ustring::size_type pos = 0,len = 1;
+ char buf[2];
+ if(btncaps->get_active() || btnshift->get_active()){
+ btnshift->set_active(false);
+ }else{
+ sprintf(buf, "%c", label[0] + 32);
+ label.replace(pos, len, buf);
+ }
+ //std::cout << label << std::endl;
+ buffer1->insert_at_cursor(label);
+}
+
+void TextEditor::btntab_clicked(){
+ buffer1->insert_at_cursor("\t");
+}
+
+void TextEditor::btnenter_clicked(){
+ buffer1->insert_at_cursor("\n");
+}
+
+bool TextEditor::window_delete_event(GdkEventAny *event)
+{
+ // Create json raw data
+ json data = json::parse(R"({
+ "width":800,
+ "height":450
+ })");
+
+ // Override config in json file
+ data["width"] = sw1.get_width();
+ data["height"] = sw1.get_height();
+
+ // Output json data to file
+ std::fstream outfile;
+ outfile.open("config.json", std::ios_base::out);
+ if (outfile.is_open())
+ {
+ outfile << data;
+ }
+ outfile.close();
+ return false;
+}
+
void TextEditor::btnopen_clicked()
{
// Create a dialog
@@ -214,12 +298,15 @@ void TextEditor::search_entry_changed()
Gtk::TextIter start, end;
// If get text to search, select the text and storage the position
- if (buffer1->begin().forward_search(text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ if (text.length() != 0)
{
- curr_iter_up = start;
- curr_iter_down = end;
- buffer1->select_range(start, end);
- textview1.scroll_to(start);
+ if (buffer1->begin().forward_search(text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ {
+ curr_iter_up = start;
+ curr_iter_down = end;
+ buffer1->select_range(start, end);
+ textview1.scroll_to(start);
+ }
}
}
@@ -230,12 +317,15 @@ void TextEditor::search_forward()
Gtk::TextIter start, end;
// Get Text to search, down to the end of text
- if (curr_iter_down.forward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ if (search_text.length() != 0)
{
- curr_iter_up = start;
- curr_iter_down = end;
- buffer1->select_range(start, end);
- textview1.scroll_to(start);
+ if (curr_iter_down.forward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ {
+ curr_iter_up = start;
+ curr_iter_down = end;
+ buffer1->select_range(start, end);
+ textview1.scroll_to(start);
+ }
}
}
@@ -246,12 +336,15 @@ void TextEditor::search_backward()
Gtk::TextIter start, end;
// Get Text to search
- if (curr_iter_up.backward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ if (search_text.length() != 0)
{
- curr_iter_up = start;
- curr_iter_down = end;
- buffer1->select_range(start, end);
- textview1.scroll_to(start);
+ if (curr_iter_up.backward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
+ {
+ curr_iter_up = start;
+ curr_iter_down = end;
+ buffer1->select_range(start, end);
+ textview1.scroll_to(start);
+ }
}
}
@@ -311,3 +404,30 @@ void TextEditor::infobar_response(int response)
{
infobar.hide();
}
+
+void TextEditor::about_activated()
+{
+ char *version, *copyright;
+ // The Gtkmm Version
+ version = g_strdup_printf("1.0\nRunning Against Gtkmm %d.%d.%d",
+ GTKMM_MAJOR_VERSION,
+ GTKMM_MINOR_VERSION,
+ GTKMM_MICRO_VERSION);
+ const char *authors[] = {"Dale Clack", NULL};
+ // Copyright Informaion
+ copyright = g_strdup_printf("© 2019—2022 The Xe Project");
+ // Show the about dialog
+ gtk_show_about_dialog(GTK_WINDOW(this->gobj()),
+ "program-name", "Text Editot",
+ "version", version,
+ "copyright", copyright,
+ "comments", "A simple text editor",
+ "authors", authors,
+ "license-type", GTK_LICENSE_GPL_3_0,
+ "logo-icon-name", "org.gtk.daleclack",
+ "title", "About Simple text editor",
+ (char *)NULL);
+ // Free memory
+ g_free(version);
+ g_free(copyright);
+}
diff --git a/json_nlohmann/json.hpp b/json_nlohmann/json.hpp
new file mode 100644
index 0000000..cb27e05
--- /dev/null
+++ b/json_nlohmann/json.hpp
@@ -0,0 +1,22091 @@
+/*
+ __ _____ _____ _____
+ __| | __| | | | JSON for Modern C++
+| | |__ | | | | | | version 3.10.5
+|_____|_____|_____|_|___| https://github.com/nlohmann/json
+
+Licensed under the MIT License .
+SPDX-License-Identifier: MIT
+Copyright (c) 2013-2022 Niels Lohmann .
+
+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.
+*/
+
+/****************************************************************************\
+ * Note on documentation: The source files contain links to the online *
+ * documentation of the public API at https://json.nlohmann.me. This URL *
+ * contains the most recent documentation and should also be applicable to *
+ * previous versions; documentation for deprecated functions is not *
+ * removed, but marked deprecated. See "Generate documentation" section in *
+ * file doc/README.md. *
+\****************************************************************************/
+
+#ifndef INCLUDE_NLOHMANN_JSON_HPP_
+#define INCLUDE_NLOHMANN_JSON_HPP_
+
+#define NLOHMANN_JSON_VERSION_MAJOR 3
+#define NLOHMANN_JSON_VERSION_MINOR 10
+#define NLOHMANN_JSON_VERSION_PATCH 5
+
+#include // all_of, find, for_each
+#include // nullptr_t, ptrdiff_t, size_t
+#include // hash, less
+#include // initializer_list
+#ifndef JSON_NO_IO
+ #include // istream, ostream
+#endif // JSON_NO_IO
+#include // random_access_iterator_tag
+#include // unique_ptr
+#include // accumulate
+#include // string, stoi, to_string
+#include // declval, forward, move, pair, swap
+#include // vector
+
+// #include
+
+
+#include
+#include
+
+// #include
+
+
+#include // transform
+#include // array
+#include // forward_list
+#include // inserter, front_inserter, end
+#include