Update text editor

This commit is contained in:
daleclack 2022-08-07 14:35:31 +08:00
parent 0533c96cfe
commit 88af58a207
5 changed files with 22694 additions and 28 deletions

View File

@ -44,6 +44,7 @@ set(RESOURCE_LIST
STRIPBLANKS game24.ui STRIPBLANKS game24.ui
STRIPBLANKS calcapp.ui STRIPBLANKS calcapp.ui
STRIPBLANKS text_menu.xml STRIPBLANKS text_menu.xml
STRIPBLANKS expender.ui
style.css style.css
reset.css reset.css
dock_style.css dock_style.css

440
Gtkmm3_Mac/res/expender.ui Normal file
View File

@ -0,0 +1,440 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkExpander" id="key_expend">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="resize-toplevel">True</property>
<child>
<!-- n-columns=24 n-rows=3 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-homogeneous">True</property>
<property name="column-homogeneous">True</property>
<child>
<object class="GtkButton" id="btn16">
<property name="label" translatable="yes">Q</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn22">
<property name="label" translatable="yes">W</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">4</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn4">
<property name="label" translatable="yes">E</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">6</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn17">
<property name="label" translatable="yes">R</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">8</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn19">
<property name="label" translatable="yes">T</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">10</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn24">
<property name="label" translatable="yes">Y</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">12</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn20">
<property name="label" translatable="yes">U</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">14</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn8">
<property name="label" translatable="yes">I</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">16</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn14">
<property name="label" translatable="yes">O</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">18</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn15">
<property name="label" translatable="yes">P</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">20</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn0">
<property name="label" translatable="yes">A</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn25">
<property name="label" translatable="yes">Z</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">4</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn18">
<property name="label" translatable="yes">S</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">5</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn3">
<property name="label" translatable="yes">D</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">7</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn5">
<property name="label" translatable="yes">F</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">9</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn6">
<property name="label" translatable="yes">G</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">11</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn7">
<property name="label" translatable="yes">H</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">13</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn9">
<property name="label" translatable="yes">J</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">15</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn10">
<property name="label" translatable="yes">K</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">17</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn11">
<property name="label" translatable="yes">L</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">19</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="btn_caps">
<property name="label" translatable="yes">CapsLK</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn23">
<property name="label" translatable="yes">X</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">6</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn2">
<property name="label" translatable="yes">C</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">8</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn21">
<property name="label" translatable="yes">V</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">10</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn1">
<property name="label" translatable="yes">B</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">12</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn13">
<property name="label" translatable="yes">N</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">14</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn12">
<property name="label" translatable="yes">M</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">16</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="btnshift">
<property name="label" translatable="yes">Shift</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btntab">
<property name="label" translatable="yes">tab</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnenter">
<property name="label" translatable="yes">enter</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="left-attach">21</property>
<property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Keyboard</property>
</object>
</child>
</object>
</interface>

View File

@ -2,18 +2,20 @@
#include <gtkmm.h> #include <gtkmm.h>
class TextEditor : public Gtk::ApplicationWindow{ class TextEditor : public Gtk::ApplicationWindow
{
public: public:
TextEditor(); TextEditor();
private: private:
//Header widgets // Header widgets
Gtk::HeaderBar header; Gtk::HeaderBar header;
Gtk::MenuButton menubtn; Gtk::MenuButton menubtn;
Gtk::Popover popover; Gtk::Popover popover;
Gtk::ToggleButton search_button; Gtk::ToggleButton search_button;
Glib::RefPtr<Gtk::Builder> menu_builder; Glib::RefPtr<Gtk::Builder> menu_builder, expend_builder;
//SearchBar // SearchBar
Gtk::SearchBar searchbar; Gtk::SearchBar searchbar;
Gtk::SearchEntry search_entry; Gtk::SearchEntry search_entry;
Gtk::Box searchbox; Gtk::Box searchbox;
@ -21,20 +23,24 @@ private:
Glib::RefPtr<Glib::Binding> search_binding; Glib::RefPtr<Glib::Binding> search_binding;
Gtk::TextIter curr_iter_up, curr_iter_down; Gtk::TextIter curr_iter_up, curr_iter_down;
//Window widgets // Window widgets
Gtk::Box vbox,hbox,*infobox; Gtk::Box vbox, hbox, *infobox;
Gtk::ScrolledWindow sw1,sw2; Gtk::ScrolledWindow sw1;
Glib::RefPtr<Gtk::TextBuffer> buffer1; Glib::RefPtr<Gtk::TextBuffer> buffer1;
Gtk::TextView textview1; Gtk::TextView textview1;
Gtk::InfoBar infobar; Gtk::InfoBar infobar;
Gtk::Label label1; Gtk::Label label1;
Gtk::Expander *expender;
Gtk::Button *btns[26], *btntab, *btnenter;
Gtk::ToggleButton *btnshift, *btncaps;
//File Dialog // File Dialog
Glib::RefPtr<Gtk::FileChooserNative> dialog; Glib::RefPtr<Gtk::FileChooserNative> dialog;
Glib::ustring curr_filename; Glib::ustring curr_filename;
bool file_opened; bool file_opened;
//Signal Handlers // Signal Handlers
bool window_delete_event(GdkEventAny *event);
// File Operation functions // File Operation functions
void btnopen_clicked(); void btnopen_clicked();
@ -55,4 +61,12 @@ private:
void search_entry_changed(); void search_entry_changed();
void search_forward(); void search_forward();
void search_backward(); void search_backward();
// Keyboard press
void key_pressed(Gtk::Button *button);
void btntab_clicked();
void btnenter_clicked();
// Other Signal Handlers
void about_activated();
}; };

View File

@ -1,9 +1,11 @@
#include "TextEditor.hh" #include "TextEditor.hh"
#include "text_types.hh" #include "text_types.hh"
#include "../json_nlohmann/json.hpp"
#include <fstream> #include <fstream>
#include <iostream>
#include <string>
// Only for build in this repository using json = nlohmann::json;
// #define text_globs supported_globs
TextEditor::TextEditor() TextEditor::TextEditor()
: vbox(Gtk::ORIENTATION_VERTICAL, 5), : vbox(Gtk::ORIENTATION_VERTICAL, 5),
@ -11,8 +13,19 @@ TextEditor::TextEditor()
searchbox(Gtk::ORIENTATION_HORIZONTAL, 5), searchbox(Gtk::ORIENTATION_HORIZONTAL, 5),
file_opened(false) 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 // Initalize Window
set_default_size(800, 450); set_default_size(width, height);
set_icon_name("my_textedit"); set_icon_name("my_textedit");
// Initalize HeaderBar // Initalize HeaderBar
@ -48,6 +61,7 @@ TextEditor::TextEditor()
add_action("text_copy", sigc::mem_fun(*this, &TextEditor::btncopy_clicked)); 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_paste", sigc::mem_fun(*this, &TextEditor::btnpaste_clicked));
add_action("text_close", sigc::mem_fun(*this, &TextEditor::btnclose_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 // Add searchbar and search up and down buttons
search_up.set_image_from_icon_name("up"); search_up.set_image_from_icon_name("up");
@ -74,14 +88,84 @@ TextEditor::TextEditor()
infobox = dynamic_cast<Gtk::Box *>(infobar.get_content_area()); infobox = dynamic_cast<Gtk::Box *>(infobar.get_content_area());
infobox->pack_start(label1); infobox->pack_start(label1);
vbox.pack_start(infobar, Gtk::PACK_SHRINK); 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 // Show everything
vbox.pack_start(hbox);
add(vbox); add(vbox);
show_all_children(); show_all_children();
infobar.hide(); 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() void TextEditor::btnopen_clicked()
{ {
// Create a dialog // Create a dialog
@ -214,6 +298,8 @@ void TextEditor::search_entry_changed()
Gtk::TextIter start, end; Gtk::TextIter start, end;
// If get text to search, select the text and storage the position // If get text to search, select the text and storage the position
if (text.length() != 0)
{
if (buffer1->begin().forward_search(text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end)) if (buffer1->begin().forward_search(text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
{ {
curr_iter_up = start; curr_iter_up = start;
@ -221,6 +307,7 @@ void TextEditor::search_entry_changed()
buffer1->select_range(start, end); buffer1->select_range(start, end);
textview1.scroll_to(start); textview1.scroll_to(start);
} }
}
} }
void TextEditor::search_forward() void TextEditor::search_forward()
@ -230,6 +317,8 @@ void TextEditor::search_forward()
Gtk::TextIter start, end; Gtk::TextIter start, end;
// Get Text to search, down to the end of text // Get Text to search, down to the end of text
if (search_text.length() != 0)
{
if (curr_iter_down.forward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end)) if (curr_iter_down.forward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
{ {
curr_iter_up = start; curr_iter_up = start;
@ -237,6 +326,7 @@ void TextEditor::search_forward()
buffer1->select_range(start, end); buffer1->select_range(start, end);
textview1.scroll_to(start); textview1.scroll_to(start);
} }
}
} }
void TextEditor::search_backward() void TextEditor::search_backward()
@ -246,6 +336,8 @@ void TextEditor::search_backward()
Gtk::TextIter start, end; Gtk::TextIter start, end;
// Get Text to search // Get Text to search
if (search_text.length() != 0)
{
if (curr_iter_up.backward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end)) if (curr_iter_up.backward_search(search_text, Gtk::TEXT_SEARCH_CASE_INSENSITIVE, start, end))
{ {
curr_iter_up = start; curr_iter_up = start;
@ -253,6 +345,7 @@ void TextEditor::search_backward()
buffer1->select_range(start, end); buffer1->select_range(start, end);
textview1.scroll_to(start); textview1.scroll_to(start);
} }
}
} }
void TextEditor::btncopy_clicked() void TextEditor::btncopy_clicked()
@ -311,3 +404,30 @@ void TextEditor::infobar_response(int response)
{ {
infobar.hide(); 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);
}

22091
json_nlohmann/json.hpp Normal file

File diff suppressed because it is too large Load Diff