Browse Source

Fikxed Popup Bugs and started working on terminal

master
oyvang 11 years ago
parent
commit
bc0a24ec77
  1. 3
      juci/config.json
  2. 1
      juci/menu.xml
  3. 193
      juci/notebook.cc
  4. 25
      juci/notebook.h
  5. 65
      juci/terminal.cc
  6. 21
      juci/terminal.h
  7. 53
      juci/window.cc
  8. 7
      juci/window.h

3
juci/config.json

@ -23,7 +23,8 @@
"new_h_file": "<control><alt>h", "new_h_file": "<control><alt>h",
"new_cc_file": "<alt>c", "new_cc_file": "<alt>c",
"close_tab": "<control>w", "close_tab": "<control>w",
"open_folder": "<control><alt>o" "open_folder": "<control><alt>o",
"save_as": "<control><shift>s"
}, },
"directoryfilter": { "directoryfilter": {
"ignore": [ "ignore": [

1
juci/menu.xml

@ -8,6 +8,7 @@
</menu> </menu>
<menuitem action='FileOpenFile'/> <menuitem action='FileOpenFile'/>
<menuitem action='FileOpenFolder'/> <menuitem action='FileOpenFolder'/>
<menuitem action='FileSaveAs'/>
<separator/> <separator/>
<menuitem action='FileQuit'/> <menuitem action='FileQuit'/>
</menu> </menu>

193
juci/notebook.cc

@ -1,4 +1,6 @@
#include "notebook.h" #include "notebook.h"
#include <fstream>
Notebook::Model::Model() { Notebook::Model::Model() {
cc_extension_ = ".cc"; cc_extension_ = ".cc";
@ -18,9 +20,9 @@ Notebook::Controller::Controller(Keybindings::Controller& keybindings,
directories_(dir_cfg) { directories_(dir_cfg) {
OnNewPage("juCi++"); OnNewPage("juCi++");
refClipboard_ = Gtk::Clipboard::get(); refClipboard_ = Gtk::Clipboard::get();
ispopup = false;
view().pack1(directories_.widget(),true,true); view().pack1(directories_.widget(),true,true);
CreateKeybindings(keybindings); CreateKeybindings(keybindings);
}// Constructor }// Constructor
void Notebook::Controller::CreateKeybindings(Keybindings::Controller void Notebook::Controller::CreateKeybindings(Keybindings::Controller
@ -94,12 +96,6 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
[this]() { [this]() {
OnEditPaste(); OnEditPaste();
}); });
keybindings.action_group_hidden()->
add(Gtk::Action::create("EditPaste",
Gtk::Stock::PASTE),
[this]() {
OnEditPaste();
});
entry_.view_.entry().signal_activate(). entry_.view_.entry().signal_activate().
connect( connect(
[this]() { [this]() {
@ -133,53 +129,57 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
}); });
} }
void Notebook::Controller::GeneratePopup(std::vector<string> items){ bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button){
if(button->button == 1 && ispopup){
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
return true;
}
return false;
}
bool Notebook::Controller::GeneratePopup(Gtk::Window* window){
// Get function to fill popup with suggests item vector under is for testing
std::vector<std::string> items;
items.push_back("toString(std::string& string) -> void");
items.push_back("toLower(std::string& string) -> void");
items.push_back("toUpper(std::string& string) -> void");
items.push_back("fuckOFF(const std::string string) -> bool");
items.push_back("fuckOFF(const std::string string) -> bool");
items.push_back("toString(std::string& string) -> void");
items.push_back("toLower(std::string& string) -> void");
items.push_back("toUpper(std::string& string) -> void");
items.push_back("fuckOFF(const std::string string) -> bool");
items.push_back("fuckOFF(const std::string string) -> bool");
// Replace over with get suggestions from zalox! OVER IS JUST FOR TESTING
Gtk::ScrolledWindow popup_scroll_; Gtk::ScrolledWindow popup_scroll_;
Gtk::ListViewText listview_(1,false,Gtk::SelectionMode::SELECTION_SINGLE); Gtk::ListViewText listview_(1,false,Gtk::SelectionMode::SELECTION_SINGLE);
Gtk::Dialog popup_("",true);
popup_scroll_.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_NEVER);
listview_.set_enable_search(false); listview_.set_enable_search(false);
listview_.set_headers_visible(false);
listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
listview_.set_activate_on_single_click(true); listview_.set_activate_on_single_click(true);
listview_.signal_row_activated().
connect([this, &listview_, &popup_](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string t = listview_.get_text(listview_.get_selected()[0]);
CurrentTextView().get_buffer()->insert_at_cursor(t);
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
});
for (auto &i : items) listview_.append(i); for (auto &i : items) listview_.append(i);
listview_.set_headers_visible(false);
popup_scroll_.add(listview_); popup_scroll_.add(listview_);
popup_.get_vbox()->pack_start(popup_scroll_); popup_.get_vbox()->pack_start(popup_scroll_);
popup_.set_size_request(80,80); popup_.set_transient_for(*window);
popup_.show_all(); popup_.show_all();
Gdk::Rectangle temp1, temp2;
CurrentTextView().
get_cursor_locations(
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1, temp2);
int x = temp1.get_x(); int popup_x = popup_.get_width();
int y = temp1.get_y(); int popup_y = items.size()*20;
text_vec_.at(CurrentPage())-> PopupSetSize(popup_scroll_,popup_x,popup_y);
view().buffer_to_window_coords( int x,y;
Gtk::TextWindowType::TEXT_WINDOW_WIDGET, FindPopupPosition(CurrentTextView(),popup_x,popup_y,x,y);
temp2.get_x(), popup_.move(x, y+15);
temp2.get_y(), PopupSelectHandler(popup_, listview_);
x, y); ispopup = true;
int widht = Notebook().get_width()-88;
int height = Notebook().get_height()-180;
if(x>widht){
x = widht; }
if(y>height){
y =height;
}
popup_.move(x, y+88);
popup_.run(); popup_.run();
popup_.hide();
ispopup = false;
return true;
} }
bool Notebook::Controller::ScrollEventCallback(GdkEventScroll* scroll_event) { bool Notebook::Controller::ScrollEventCallback(GdkEventScroll* scroll_event) {
@ -235,6 +235,7 @@ void Notebook::Controller::OnOpenFile(std::string path) {
OnBufferChange(); OnBufferChange();
} }
void Notebook::Controller::OnCreatePage(){ void Notebook::Controller::OnCreatePage(){
text_vec_.push_back(new Source::Controller(source_config())); text_vec_.push_back(new Source::Controller(source_config()));
linenumbers_vec_.push_back(new Source::Controller(source_config())); linenumbers_vec_.push_back(new Source::Controller(source_config()));
@ -252,13 +253,13 @@ void Notebook::Controller::OnCreatePage(){
linenumbers_vec_.back()->view().set_sensitive(false); linenumbers_vec_.back()->view().set_sensitive(false);
editor_vec_.back()->pack_start(*scrolledline_vec_.back(),false,false); editor_vec_.back()->pack_start(*scrolledline_vec_.back(),false,false);
editor_vec_.back()->pack_start(*scrolledtext_vec_.back(), true, true); editor_vec_.back()->pack_start(*scrolledtext_vec_.back(), true, true);
BufferChangeHandler(text_vec_.back()->view().get_buffer()); TextViewHandlers(text_vec_.back()->view());
} }
void Notebook::Controller::OnCloseCurrentPage() { void Notebook::Controller::OnCloseCurrentPage() {
//TODO (oyvang, zalox, forgi) Save a temp file, in case you close one you dont want to close? //TODO (oyvang, zalox, forgi) Save a temp file, in case you close one you dont want to close?
if(Pages()!=0){ if(Pages()!=0){
int page = CurrentPage(); int page = CurrentPage(); //(Zalox)Have to call your destructors to kill / join threads
Notebook().remove_page(page); Notebook().remove_page(page);
delete text_vec_.at(page); delete text_vec_.at(page);
delete linenumbers_vec_.at(page); delete linenumbers_vec_.at(page);
@ -365,7 +366,8 @@ void Notebook::Controller::OnBufferChange() {
"\n"+std::to_string(line_nr)+" "); "\n"+std::to_string(line_nr)+" ");
} }
while (line_nr > text_nr ){ while (line_nr > text_nr ){
Gtk::TextIter iter = Buffer(linenumbers_vec_.at(page))->get_iter_at_line(line_nr); Gtk::TextIter iter =
Buffer(linenumbers_vec_.at(page))->get_iter_at_line(line_nr);
iter.backward_char(); iter.backward_char();
line_nr--; line_nr--;
Buffer(linenumbers_vec_.at(page))-> Buffer(linenumbers_vec_.at(page))->
@ -382,22 +384,6 @@ void Notebook::Controller::OnBufferChange() {
ScrollEventCallback(scroll); ScrollEventCallback(scroll);
delete scroll; delete scroll;
} }
Gtk::TextIter start,end;
std::string word;
start = Buffer(text_vec_.at(page))->get_insert()->get_iter();
end = Buffer(text_vec_.at(page))->get_insert()->get_iter();
start.backward_char();
word = Buffer(text_vec_.at(page))->get_text(start,end);
if( word == "."){
//TODO(Oyvang,Zalox,Forgie) Remove TEST
std::vector<std::string> TEST;
TEST.push_back("toString()");
TEST.push_back("toLower()");
TEST.push_back("toUpper()");
TEST.push_back("fuckOFF()");
TEST.push_back("fuckOFF()");
GeneratePopup(TEST);
}
} }
void Notebook::Controller void Notebook::Controller
::OnDirectoryNavigation(const Gtk::TreeModel::Path& path, ::OnDirectoryNavigation(const Gtk::TreeModel::Path& path,
@ -439,11 +425,88 @@ Gtk::Notebook& Notebook::Controller::Notebook() {
return view_.notebook(); return view_.notebook();
} }
void Notebook::Controller::BufferChangeHandler(Glib::RefPtr<Gtk::TextBuffer> void Notebook::Controller::TextViewHandlers(Gtk::TextView& textview) {
buffer) { textview.get_buffer()->signal_changed().connect(
buffer->signal_changed().connect(
[this]() { [this]() {
OnBufferChange(); OnBufferChange();
}); });
textview.signal_button_release_event().
connect(sigc::mem_fun(*this,&Notebook::Controller::OnMouseRelease),false);
} }
void Notebook::Controller::PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview){
listview.signal_row_activated().
connect([this, &listview, &popup](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string selected =
listview.get_text(listview.get_selected()[0]);
CurrentTextView().get_buffer()->insert_at_cursor(selected);
popup.response(Gtk::RESPONSE_DELETE_EVENT);
});
}
void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll,
int &current_x,
int &current_y) {
int textview_x = CurrentTextView().get_width();
int textview_y = 150;
bool is_never_scroll_x = true;
bool is_never_scroll_y = true;
if (current_x > textview_x) {
current_x = textview_x;
is_never_scroll_x = false;
}
if (current_y > textview_y) {
current_y = textview_y;
is_never_scroll_y = false;
}
scroll.set_size_request(current_x,current_y);
if (!is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_AUTOMATIC);
} else if (!is_never_scroll_x && is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_NEVER);
} else if (is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_AUTOMATIC);
}
}
void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y){
Gdk::Rectangle temp1, temp2;
textview.get_cursor_locations(
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1,temp2);
int textview_edge_x = 0;
int textview_edge_y = 0;
textview.buffer_to_window_coords(
Gtk::TextWindowType::TEXT_WINDOW_WIDGET,
temp1.get_x(),
temp1.get_y(),
x, y);
Glib::RefPtr<Gdk::Window> gdkw =
CurrentTextView().get_window(Gtk::TextWindowType::TEXT_WINDOW_WIDGET);
gdkw->get_origin(textview_edge_x, textview_edge_y);
x+=textview_edge_x;
y+=textview_edge_y;
if ((textview_edge_x-x)*-1 > textview.get_width()-popup_x) {
x -= popup_x;
}
if ((textview_edge_y-y)*-1 > textview.get_height()-popup_y) {
y -= (popup_y+14) + 15;
}
}
void Notebook::Controller:: OnSaveFile(std::string path){
std::ofstream file;
file.open (path);
file << CurrentTextView().get_buffer()->get_text();
file.close();
}

25
juci/notebook.h

@ -6,6 +6,7 @@
#include "entry.h" #include "entry.h"
#include "source.h" #include "source.h"
#include "directories.h" #include "directories.h"
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
@ -33,7 +34,6 @@ namespace Notebook {
}; };
class Controller { class Controller {
public: public:
Controller(Keybindings::Controller& keybindings, Controller(Keybindings::Controller& keybindings,
Source::Config& config, Source::Config& config,
Directories::Config& dir_cfg); Directories::Config& dir_cfg);
@ -54,6 +54,7 @@ namespace Notebook {
void OnFileNewEmptyfile(); void OnFileNewEmptyfile();
void OnFileNewHeaderFile(); void OnFileNewHeaderFile();
void OnFileOpenFolder(); void OnFileOpenFolder();
void OnSaveFile(std::string path);
void OnDirectoryNavigation(const Gtk::TreeModel::Path& path, void OnDirectoryNavigation(const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn* column); Gtk::TreeViewColumn* column);
void OnNewPage(std::string name); void OnNewPage(std::string name);
@ -61,19 +62,27 @@ namespace Notebook {
void OnCreatePage(); void OnCreatePage();
bool ScrollEventCallback(GdkEventScroll* scroll_event); bool ScrollEventCallback(GdkEventScroll* scroll_event);
int Pages(); int Pages();
Directories::Controller& directories() { return directories_; } Directories::Controller& directories() { return directories_; }
Gtk::Paned& view(); Gtk::Paned& view();
bool GeneratePopup(Gtk::Window* window);
void GeneratePopup(std::vector<string> items);
// Gtk::HBox& view();
void Search(bool forward); void Search(bool forward);
const Source::Config& source_config() { return source_config_; } const Source::Config& source_config() { return source_config_; }
bool OnMouseRelease(GdkEventButton* button);
protected: protected:
void BufferChangeHandler(Glib::RefPtr<Gtk::TextBuffer> buffer); void TextViewHandlers(Gtk::TextView& textview);//Glib::RefPtr<Gtk::TextBuffer> buffer);
void PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview);
private: private:
void CreateKeybindings(Keybindings::Controller& keybindings); void CreateKeybindings(Keybindings::Controller& keybindings);
void FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y);
void PopupSetSize(Gtk::ScrolledWindow& scroll,
int &current_x,
int &current_y);
Glib::RefPtr<Gtk::Builder> m_refBuilder; Glib::RefPtr<Gtk::Builder> m_refBuilder;
Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup; Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup;
Source::Config source_config_; Source::Config source_config_;
@ -89,6 +98,8 @@ namespace Notebook {
Gtk::TextIter search_match_end_; Gtk::TextIter search_match_end_;
Gtk::TextIter search_match_start_; Gtk::TextIter search_match_start_;
Glib::RefPtr<Gtk::Clipboard> refClipboard_; Glib::RefPtr<Gtk::Clipboard> refClipboard_;
bool ispopup;
Gtk::Dialog popup_;
}; // class controller }; // class controller
} // namespace Notebook } // namespace Notebook

65
juci/terminal.cc

@ -1,9 +1,70 @@
#include "terminal.h" #include "terminal.h"
#include <iostream>
Terminal::View::View(){ Terminal::View::View(){
textview_.add(buffer_); scrolledwindow_.add(textview_);
view_.add(textview_); scrolledwindow_.set_size_request(-1,150);
view_.add(scrolledwindow_);
} }
Terminal::Controller::Controller() {
root = "";
Terminal().signal_key_release_event().
connect(sigc::mem_fun(*this,&Terminal::Controller::OnButtonRealeaseEvenet),false);
}
bool Terminal::Controller::OnButtonRealeaseEvenet(GdkEventKey *key) {
if(key->keyval == 65421 || key->keyval == 65293){
ExecuteCommand();
}
return false;
}
void Terminal::Controller::ExecuteCommand() {
std::cout << "EXECUTE COMMAND ALGORITHM "<< std::endl;
std::string temp = getCommand();
if(temp != ""){
std::cout << "EXECUTE COMMAND: "<<temp << std::endl;
FILE* p = popen(temp.c_str(), "r");
if (p == NULL)
{
Terminal().get_buffer()->insert(Terminal().get_buffer()->end(),"Command Failed\n");
} else{
char buffer[1028];
while (fgets(buffer, 1028, p) != NULL)
{
Terminal().get_buffer()->insert(Terminal().get_buffer()->end(),buffer);
}
pclose(p);
}
Terminal().get_buffer()->insert(Terminal().get_buffer()->end(),"Command Executed\n");
}else{
std::cout << "NO COMMAND TO RUN"<< std::endl;
}
}
std::string Terminal::Controller::getCommand(){
std::string command = "";
Gtk::TextIter start,end;
int a = Terminal().get_buffer()->get_insert()->get_iter().get_line()-1;
if(a==-1)a=0;
start = Terminal().get_buffer()->get_iter_at_line(a);
end =Terminal().get_buffer()->get_iter_at_line(a);
while(!end.ends_line()) {
end++;
}
while(!start.starts_line()) {
start--;
}
command = Terminal().get_buffer()->get_text(start,end);
return command;
}

21
juci/terminal.h

@ -1,8 +1,6 @@
#ifndef JUCI_TERMINAL_H_
#define JUCI_TERMINAL_H_
#ifndef JUCI_NOTEBOOK_H_
#define JUCI_NOTEBOOK_H_
#include <iostream>
#include "gtkmm.h" #include "gtkmm.h"
namespace Terminal { namespace Terminal {
@ -11,18 +9,27 @@ namespace Terminal {
public: public:
View(); View();
Gtk::HBox& view() {return view_;} Gtk::HBox& view() {return view_;}
Gtk::TextView& textview() {return textview_;}
private: private:
Gtk::HBox view_; Gtk::HBox view_;
Glib::RefPtr<Gtk::TextBuffer> buffer_;
Gtk::TextView textview_; Gtk::TextView textview_;
Gtk::ScrolledWindow scrolledwindow_;
}; // class view }; // class view
class Controller { class Controller {
public: public:
Controller();
Gtk::HBox& view() {return view_.view();}
Gtk::TextView& Terminal(){return view_.textview();}
private:
void ExecuteCommand();
std::string getCommand();
bool OnButtonRealeaseEvenet(GdkEventKey* key);
Terminal::View view_;
std::string root;
}; // class controller }; // class controller
} // namespace Terminal } // namespace Terminal
#endif // JUCI_NOTEBOOK_H_ #endif // JUCI_TERMINAL_H_

53
juci/window.cc

@ -26,6 +26,22 @@ Window::Window() :
[this]() { [this]() {
OnFileOpenFolder(); OnFileOpenFolder();
}); });
keybindings_.action_group_menu()->add(Gtk::Action::create("FileSaveAs",
"Save as"),
Gtk::AccelKey(keybindings_.config_
.key_map()["save_as"]),
[this]() {
OnSaveFileAs();
});
notebook_.CurrentTextView().signal_key_release_event().
connect(sigc::mem_fun(*this,&Window::OnKeyRelease),false);
this->signal_button_release_event().
connect(sigc::mem_fun(*this,&Window::OnMouseRelease),false);
terminal_.Terminal().signal_button_release_event().
connect(sigc::mem_fun(*this,&Window::OnMouseRelease),false);
PluginApi::menu_ = &menu_; PluginApi::menu_ = &menu_;
PluginApi::notebook_ = &notebook_; PluginApi::notebook_ = &notebook_;
PluginApi::InitPlugins(); PluginApi::InitPlugins();
@ -37,6 +53,7 @@ Window::Window() :
window_box_.pack_start(menu_.view(), Gtk::PACK_SHRINK); window_box_.pack_start(menu_.view(), Gtk::PACK_SHRINK);
window_box_.pack_start(notebook_.entry_view(), Gtk::PACK_SHRINK); window_box_.pack_start(notebook_.entry_view(), Gtk::PACK_SHRINK);
window_box_.pack_start(notebook_.view()); window_box_.pack_start(notebook_.view());
window_box_.pack_end(terminal_.view(),Gtk::PACK_SHRINK);
show_all_children(); show_all_children();
} // Window constructor } // Window constructor
@ -112,6 +129,7 @@ void Window::OnOpenFile() {
case(Gtk::RESPONSE_OK): { case(Gtk::RESPONSE_OK): {
std::cout << "Open clicked." << std::endl; std::cout << "Open clicked." << std::endl;
std::string path = dialog.get_filename(); std::string path = dialog.get_filename();
std::cout << "File selected: " << path << std::endl; std::cout << "File selected: " << path << std::endl;
notebook_.OnOpenFile(path); notebook_.OnOpenFile(path);
break; break;
@ -126,3 +144,38 @@ void Window::OnOpenFile() {
} }
} }
} }
void Window::OnSaveFileAs(){
Gtk::FileChooserDialog dialog("Please choose a file",
Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("_Save", Gtk::RESPONSE_OK);
int result = dialog.run();
switch (result) {
case(Gtk::RESPONSE_OK): {
std::string path = dialog.get_filename();
unsigned pos = path.find_last_of("/\\");
std::cout << path<< std::endl;
notebook_.OnSaveFile(path);
break;
}
case(Gtk::RESPONSE_CANCEL): {
break;
}
default: {
std::cout << "Unexpected button clicked." << std::endl;
break;
}
}
}
bool Window::OnKeyRelease(GdkEventKey* key){
if(key->keyval==46){
return notebook_.GeneratePopup(this);
}
return false;
}
bool Window::OnMouseRelease(GdkEventButton *button){
return notebook_.OnMouseRelease(button);
}

7
juci/window.h

@ -3,6 +3,7 @@
#include "api.h" #include "api.h"
#include "config.h" #include "config.h"
#include "terminal.h"
#include <cstddef> #include <cstddef>
@ -19,8 +20,7 @@ public:
Keybindings::Controller keybindings_; Keybindings::Controller keybindings_;
Menu::Controller menu_; Menu::Controller menu_;
Notebook::Controller notebook_; Notebook::Controller notebook_;
Terminal::Controller terminal_;
Keybindings::Controller& keybindings() { return keybindings_; } Keybindings::Controller& keybindings() { return keybindings_; }
private: private:
@ -28,6 +28,9 @@ public:
void OnWindowHide(); void OnWindowHide();
void OnOpenFile(); void OnOpenFile();
void OnFileOpenFolder(); void OnFileOpenFolder();
void OnSaveFileAs();
bool OnKeyRelease(GdkEventKey* key);
bool OnMouseRelease(GdkEventButton* button);
}; };

Loading…
Cancel
Save