From 130ac7cc2b8e3a89b6a442d184dd54641387902d Mon Sep 17 00:00:00 2001 From: daleclack Date: Wed, 7 Feb 2024 17:57:17 +0800 Subject: [PATCH] Add file browser from My GtkUI 4.4 --- Gtk4_Reset/CMakeLists.txt | 10 +- Gtk4_Reset/res/dialog-error.png | Bin 0 -> 2383 bytes .../icons/scalable/status/filewin-delete.svg | 3 + .../icons/scalable/status/filewin-go-home.svg | 10 + .../icons/scalable/status/filewin-go-up.svg | 3 + .../res/icons/scalable/status/filewin-new.svg | 6 + .../scalable/status/filewin-view-grid.svg | 3 + .../scalable/status/filewin-view-list.svg | 3 + Gtk4_Reset/src/apps/FileWindow.h | 15 + Gtk4_Reset/src/apps/FileWindow.hh | 71 ---- Gtk4_Reset/src/file_app/FileColumnView.cpp | 165 ++++++++ Gtk4_Reset/src/file_app/FileColumnView.h | 6 + Gtk4_Reset/src/file_app/FileGridView.cpp | 99 +++++ Gtk4_Reset/src/file_app/FileGridView.h | 5 + Gtk4_Reset/src/file_app/FileWindow.cc | 331 ---------------- Gtk4_Reset/src/file_app/FileWindow.cpp | 368 ++++++++++++++++++ Gtk4_Reset/src/file_app/GetFileType.h | 27 ++ Gtk4_Reset/src/ui/MyDock.cpp | 59 ++- 18 files changed, 775 insertions(+), 409 deletions(-) create mode 100644 Gtk4_Reset/res/dialog-error.png create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-delete.svg create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-go-home.svg create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-go-up.svg create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-new.svg create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-view-grid.svg create mode 100644 Gtk4_Reset/res/icons/scalable/status/filewin-view-list.svg create mode 100644 Gtk4_Reset/src/apps/FileWindow.h delete mode 100644 Gtk4_Reset/src/apps/FileWindow.hh create mode 100644 Gtk4_Reset/src/file_app/FileColumnView.cpp create mode 100644 Gtk4_Reset/src/file_app/FileColumnView.h create mode 100644 Gtk4_Reset/src/file_app/FileGridView.cpp create mode 100644 Gtk4_Reset/src/file_app/FileGridView.h delete mode 100644 Gtk4_Reset/src/file_app/FileWindow.cc create mode 100644 Gtk4_Reset/src/file_app/FileWindow.cpp create mode 100644 Gtk4_Reset/src/file_app/GetFileType.h diff --git a/Gtk4_Reset/CMakeLists.txt b/Gtk4_Reset/CMakeLists.txt index c4025f0..f2827ea 100644 --- a/Gtk4_Reset/CMakeLists.txt +++ b/Gtk4_Reset/CMakeLists.txt @@ -25,7 +25,8 @@ link_directories (${GTK_LIBRARY_DIRS}) set(SOURCES src/core/main.cpp src/core/MainWin.cpp src/core/MyStack.cpp src/core/MyItem.cpp src/ui/MyDock.cpp src/ui/MyFinder.cpp src/ui/MyPrefs.cpp - src/ui/AppView.cpp) + src/ui/AppView.cpp src/file_app/FileColumnView.cpp src/file_app/FileGridView.cpp + src/file_app/FileWindow.cpp) #Compile resources with GCR_CMake @@ -51,6 +52,7 @@ set(RESOURCE_LIST folder-images.svg image_file.svg gnome-fs-regular.svg + dialog-error.png icons/16x16/actions/finder_audio.svg icons/16x16/actions/finder-battery.svg icons/16x16/actions/finder-computer.svg @@ -94,6 +96,12 @@ set(RESOURCE_LIST icons/scalable/status/finder-find-dark.svg icons/scalable/status/file-app.svg icons/scalable/status/file-app_running.svg + icons/scalable/status/filewin-delete.svg + icons/scalable/status/filewin-go-home.svg + icons/scalable/status/filewin-go-up.svg + icons/scalable/status/filewin-new.svg + icons/scalable/status/filewin-view-grid.svg + icons/scalable/status/filewin-view-list.svg icons/scalable/status/display_prefs.svg icons/scalable/status/myrunner.svg icons/scalable/status/image_app.svg diff --git a/Gtk4_Reset/res/dialog-error.png b/Gtk4_Reset/res/dialog-error.png new file mode 100644 index 0000000000000000000000000000000000000000..49ed530368b4d517321e0d3c1d28b3248129d604 GIT binary patch literal 2383 zcmV-V39$BwP)e#& z+t{Av&YgSD$HR=Bn^`>Lr70Zg(>cEP`kw#)Th96JcSeZ_|If|Z&X+x@)U^ieQ;=1V z1%?zD8b$>s4VVbv!hIqaw`)$dRSP_&)Iou-n{ZrN)4lkBS7?DIG5{bucl%iZL z`sG5Q>=p_^X?fY!mCBsJ(;7~F6Hc=Q5Su3OTcz$Y;c+JxOZN^9MSF&ZtYm*b;`@l_ zA)bdWmq7$05(StW=BVh<$S&*@cnnVZ%$-}hp9|V;7v_|)}YiHz$^N2Tb(O3r`_L=vuhW*3l}*5=9>kt zSbVVz_dY1%ZX1ComFltK#q>4T+<4s`cf@oqhc`M3K~M$S3HVkdL{Nr-JvfNj*T?zS zUUTQh#?A+D=e;6RTPAQqsRI`LIeY!}J-ZJbvdZVq5iBn^2VB>y5D{qtyuLS*Numc1 zF!kPh!G(9E3Ccp{U{UO#y7py`f`v|nAevx(r2jL>((4QAh-J=gm1>?2AU z9TPaI)Yl^M_*aLI9ErLgd~jLw>%~i}dz;*6q*B2>dzQV24@ctZ^zFm&U`H|Vs#4Yz ze0bpY+Xv&0gEuzT;ODAM@NPDU*PaVqv$I($j>EgJyfW{>VEyviV1WsEDAnEFy<>0? zZ+yIkQl&#rkTvP_`TACwnj)Ub&@(U)i^9X}THpnxB8xD6)6t`8t60RJnQ5=xX8S<9 zjjY8=)XGX`CWG3!lQS>8kheqzkBKZbwZH=0nM|k6csh+gJ-wlzYYDI&_zqeyKaU-a z(%sjG2VZIFLJIELnaw8sTyFD0SPwMp(_467Fh5W4;9$~(`9i57tXv7M*@Ww9eN~gKq)xNpYc#tTy6@-n zBvPq_f}0vXDHUXG+l~gFM>{W7VQqUA6ZSR`Fkqh( zjhcjaU8SloQ;N)8cd_fS$F52y@y_sYBS8@Y*TqRDkq`kRq}4rEG)myQSD0_BDZ!@F zh!*o{*Tsp)QE+XuszgiyTI)s^`WQ+t%}9vWC_qEB8G$jcSUeo->RNM~uzv@xi$6Da zm6B1pa#dO-;y9G^c?_6pARutQQYwkcWK@Ipm15z!=U9CH`SnwVjpY8V_Ko^|A-s6l zHeN1=z-R*j4dZ3cD~nQ5sb5_}no)I@Sqt`hAnkIYPBypjxKcqE3V4Nr2%K+bfpNE3 z^!%lzXnA}bOcP}oDATNtO%r8VSB#ZuHn>_Vu(A;=gcPPrC4%K;bg6`y$>6$fQQ*S{ z0ulI2VPz#Mj)NEm;(49bWmd`9cGDii=*S8ZTI;pzqRVA;sf76c+B{||MegibBY>A0 z2pkhxdRnQs@{5a~iF9>QX%VpX(@PLk%PTFum)9(3SylHl43uG1Ev7Z1b@d%uBb7>Z z++VtDiT4ZQY_8QRe)z&61ZDr60LtXKQrUm{r#JoY%2s?{f|8` zz~an|ANc;C?iD%Lt}5}vg~i1{nS*336P9)47@wlN~m%w$=9VUNkzUw#`u^47NPN7(o`IQxaTI=_J4Zk@DV|AKe z9WO}TNoLCvnwk}wN#Zsbz8fCsGmQPoXw*tXB8F{Q=yJJw%o+sM^8~G{nPw<8SGJ82 zi4X(<#d2AeN+oY02qsU#Q?J80piq;1NLFg#{S6&4DWz;64J2w35B2e*@QEYv`Q7j- z+c2UD$1x(7Wf_KnSrdRjgg|Sw)|7oeD0rS91c5&a@B9^Be+k|LN + + diff --git a/Gtk4_Reset/res/icons/scalable/status/filewin-go-home.svg b/Gtk4_Reset/res/icons/scalable/status/filewin-go-home.svg new file mode 100644 index 0000000..c079d38 --- /dev/null +++ b/Gtk4_Reset/res/icons/scalable/status/filewin-go-home.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Gtk4_Reset/res/icons/scalable/status/filewin-go-up.svg b/Gtk4_Reset/res/icons/scalable/status/filewin-go-up.svg new file mode 100644 index 0000000..ad1260c --- /dev/null +++ b/Gtk4_Reset/res/icons/scalable/status/filewin-go-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/Gtk4_Reset/res/icons/scalable/status/filewin-new.svg b/Gtk4_Reset/res/icons/scalable/status/filewin-new.svg new file mode 100644 index 0000000..f7958da --- /dev/null +++ b/Gtk4_Reset/res/icons/scalable/status/filewin-new.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/Gtk4_Reset/res/icons/scalable/status/filewin-view-grid.svg b/Gtk4_Reset/res/icons/scalable/status/filewin-view-grid.svg new file mode 100644 index 0000000..5dba932 --- /dev/null +++ b/Gtk4_Reset/res/icons/scalable/status/filewin-view-grid.svg @@ -0,0 +1,3 @@ + + + diff --git a/Gtk4_Reset/res/icons/scalable/status/filewin-view-list.svg b/Gtk4_Reset/res/icons/scalable/status/filewin-view-list.svg new file mode 100644 index 0000000..7a5546e --- /dev/null +++ b/Gtk4_Reset/res/icons/scalable/status/filewin-view-list.svg @@ -0,0 +1,3 @@ + + + diff --git a/Gtk4_Reset/src/apps/FileWindow.h b/Gtk4_Reset/src/apps/FileWindow.h new file mode 100644 index 0000000..8785a29 --- /dev/null +++ b/Gtk4_Reset/src/apps/FileWindow.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +G_DECLARE_FINAL_TYPE(FileWindow, file_window, FILE, WINDOW, GtkApplicationWindow) + +FileWindow *file_window_new(GtkWindow *win); + +void home_clicked(GtkWidget *widget, FileWindow *win); + +GListModel *file_window_get_grid_model(FileWindow *self); + +GListModel *file_window_get_column_model(FileWindow *self); + +GtkWidget *file_window_get_folder_entry(FileWindow *self); diff --git a/Gtk4_Reset/src/apps/FileWindow.hh b/Gtk4_Reset/src/apps/FileWindow.hh deleted file mode 100644 index 511427e..0000000 --- a/Gtk4_Reset/src/apps/FileWindow.hh +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include - -enum class ViewMode{ - MODE_ICON, - MODE_LIST -}; - -class FileWindow : public Gtk::Window{ -public: - FileWindow(); - ~FileWindow(); - void go_home(); -private: - //List Model - class ModelColumns : public Gtk::TreeModelColumnRecord{ - public: - ModelColumns(){ - add(m_col_path);add(m_col_display_name);add(m_col_pixbuf);add(m_col_is_dir); - } - Gtk::TreeModelColumn m_col_path; - Gtk::TreeModelColumn m_col_display_name; - Gtk::TreeModelColumn> m_col_pixbuf; - Gtk::TreeModelColumn m_col_is_dir; - }; - - ModelColumns columns; - Gtk::TreeView m_treeview; - Gtk::IconView m_iconview; - Glib::RefPtr m_selection; - Glib::RefPtr m_liststore; - - //File Proprties - Glib::RefPtr file_pixbuf; - Glib::RefPtr folder_pixbuf; - Glib::ustring parent_str,tmp_str; - ViewMode view_mode; - - //Child Widgets - Gtk::Box vbox,btnbox,menubox; - Gtk::Toolbar m_toolbar,m_viewbar; - Gtk::ToolButton up_button,home_button,new_button,delete_button; - Gtk::ToolItem view_item,menu_item; - Gtk::ScrolledWindow m_sw; - Gtk::Button view_button; - Gtk::MenuButton menubtn; - Gtk::Stack stack; - Gtk::Popover popover; - Gtk::CheckButton show_hidden; - Gtk::InfoBar m_infobar; - Gtk::Label info_label; - Gtk::Entry entry_file; - - //Initalize Functions - void fill_store(); - void initalize_views(); - int sort_func(const Gtk::TreeModel::iterator &a,const Gtk::TreeModel::iterator &b); - - //Signal Handlers - void item_activated(const Gtk::TreePath &path); - void row_activated(const Gtk::TreePath &path,Gtk::TreeViewColumn * sel_column); - void btnup_clicked(); - void btnhome_clicked(); - void btnnew_clicked(); - void btndel_clicked(); - void btnview_clicked(); - void infobar_response(int response_id); - void dialog_response(int response_id,Gtk::Dialog * dialog); - void btnhide_clicked(); -}; \ No newline at end of file diff --git a/Gtk4_Reset/src/file_app/FileColumnView.cpp b/Gtk4_Reset/src/file_app/FileColumnView.cpp new file mode 100644 index 0000000..b835069 --- /dev/null +++ b/Gtk4_Reset/src/file_app/FileColumnView.cpp @@ -0,0 +1,165 @@ +#include "FileColumnView.h" +#include "GetFileType.h" + +static void setup_fileicon_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Create Image for icon + GtkWidget *image; + image = gtk_image_new(); + gtk_image_set_pixel_size(GTK_IMAGE(image), 24); + gtk_list_item_set_child(item, image); +} + +static void bind_fileicon_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Get the image widget + GtkWidget *image; + image = gtk_list_item_get_child(item); + + // Set image for column + GFileInfo *info = G_FILE_INFO(gtk_list_item_get_item(item)); + gtk_image_set_from_gicon(GTK_IMAGE(image), g_file_info_get_icon(info)); +} + +static void setup_filename_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Create label to show list item + GtkWidget *label; + label = gtk_label_new(" "); + + // Set the mode for ellipsize + gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); + gtk_label_set_width_chars(GTK_LABEL(label), 20); + + // Add the label to the item + gtk_widget_set_halign(label, GTK_ALIGN_START); + gtk_list_item_set_child(item, label); +} + +static void bind_filename_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Get child for list item + GtkWidget *label; + label = gtk_list_item_get_child(item); + + // Get string and add the string to the label + GFileInfo *info = G_FILE_INFO(gtk_list_item_get_item(item)); + const char *display_name = g_file_info_get_display_name(info); + gtk_label_set_label(GTK_LABEL(label), display_name); +} + +static void setup_filetype_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Create label to show list item + GtkWidget *label; + label = gtk_label_new(" "); + + // Set the mode for ellipsize + gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); + gtk_label_set_width_chars(GTK_LABEL(label), 10); + + // Add the label to the item + gtk_widget_set_halign(label, GTK_ALIGN_START); + gtk_list_item_set_child(item, label); +} + +static void bind_filetype_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Get child for list item + GtkWidget *label; + label = gtk_list_item_get_child(item); + + // Get string and set it to the label + GFileInfo *info = G_FILE_INFO(gtk_list_item_get_item(item)); + const char *type_str = g_file_info_get_content_type(info); + gtk_label_set_label(GTK_LABEL(label), type_str); +} + +static void setup_filesize_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Create label to show list item + GtkWidget *label; + label = gtk_label_new(" "); + gtk_widget_set_halign(label, GTK_ALIGN_START); + gtk_list_item_set_child(item, label); +} + +static void bind_filesize_item(GtkListItemFactory *factory, GtkListItem *item) +{ + // Get child for list item + GtkWidget *label; + label = gtk_list_item_get_child(item); + + // Get string and set it to the label + GFileInfo *info = G_FILE_INFO(gtk_list_item_get_item(item)); + const char *size_str = g_format_size(g_file_info_get_size(info)); + gtk_label_set_label(GTK_LABEL(label), size_str); +} + +static void listview_activated(GtkColumnView *view, guint position, FileWindow *win) +{ + // Get the model + GtkSelectionModel *model = gtk_column_view_get_model(view); + GFileInfo *info = G_FILE_INFO(g_list_model_get_item(G_LIST_MODEL(model), position)); + GtkDirectoryList *list = GTK_DIRECTORY_LIST(file_window_get_column_model(win)); + + // if the file type is directory, open the directory + if (check_directory(info)) + { + // Get the file and set it to the GtkDirectoryList + GFile *file = G_FILE(g_file_info_get_attribute_object(info, "standard::file")); + gtk_directory_list_set_file(list, file); + + // Update string in the entry for path + char *path = g_file_get_path(file); + gtk_editable_set_text(GTK_EDITABLE(file_window_get_folder_entry(win)), path); + // g_print("%s\n", path); + g_free(path); + } + g_object_unref(info); +} + +GtkWidget *create_column_view(FileWindow *win) +{ + // Create view + GListModel *model = file_window_get_column_model(win); + GtkSingleSelection *selection = gtk_single_selection_new(model); + GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection)); + + // Create Factory for file icon + GtkListItemFactory *factory = gtk_signal_list_item_factory_new(); + g_signal_connect(factory, "setup", G_CALLBACK(setup_fileicon_item), NULL); + g_signal_connect(factory, "bind", G_CALLBACK(bind_fileicon_item), NULL); + GtkColumnViewColumn *column = gtk_column_view_column_new(" ", factory); + gtk_column_view_append_column(GTK_COLUMN_VIEW(view), column); + g_object_unref(column); + + // Create Factory for file name + factory = gtk_signal_list_item_factory_new(); + g_signal_connect(factory, "setup", G_CALLBACK(setup_filename_item), NULL); + g_signal_connect(factory, "bind", G_CALLBACK(bind_filename_item), NULL); + column = gtk_column_view_column_new("Name", factory); + gtk_column_view_append_column(GTK_COLUMN_VIEW(view), column); + g_object_unref(column); + + // Create Factory for file type + factory = gtk_signal_list_item_factory_new(); + g_signal_connect(factory, "setup", G_CALLBACK(setup_filetype_item), NULL); + g_signal_connect(factory, "bind", G_CALLBACK(bind_filetype_item), NULL); + column = gtk_column_view_column_new("Type", factory); + gtk_column_view_append_column(GTK_COLUMN_VIEW(view), column); + g_object_unref(column); + + // Create Factory for file size + factory = gtk_signal_list_item_factory_new(); + g_signal_connect(factory, "setup", G_CALLBACK(setup_filesize_item), NULL); + g_signal_connect(factory, "bind", G_CALLBACK(bind_filesize_item), NULL); + column = gtk_column_view_column_new("Size", factory); + gtk_column_view_append_column(GTK_COLUMN_VIEW(view), column); + g_object_unref(column); + + // Link signals + g_signal_connect(view, "activate", G_CALLBACK(listview_activated), win); + + return view; +} diff --git a/Gtk4_Reset/src/file_app/FileColumnView.h b/Gtk4_Reset/src/file_app/FileColumnView.h new file mode 100644 index 0000000..afaa63c --- /dev/null +++ b/Gtk4_Reset/src/file_app/FileColumnView.h @@ -0,0 +1,6 @@ +#pragma once + +#include "FileWindow.h" + +// Create column view widget +GtkWidget *create_column_view(FileWindow *win); diff --git a/Gtk4_Reset/src/file_app/FileGridView.cpp b/Gtk4_Reset/src/file_app/FileGridView.cpp new file mode 100644 index 0000000..1f88429 --- /dev/null +++ b/Gtk4_Reset/src/file_app/FileGridView.cpp @@ -0,0 +1,99 @@ +#include "FileGridView.h" +#include "GetFileType.h" + +static void setup_grid_item(GtkListItemFactory *factory, GtkListItem *item) +{ + GtkWidget *under_box, *info_box; + GtkWidget *image; + GtkWidget *label_filename, *label_filetype, *label_filesize; + // Create box for file icon and file info + under_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + image = gtk_image_new(); + label_filename = gtk_label_new(" "); + label_filetype = gtk_label_new(" "); + label_filesize = gtk_label_new(" "); + + // Make labels support ellipsize + gtk_label_set_ellipsize(GTK_LABEL(label_filename), PANGO_ELLIPSIZE_END); + gtk_label_set_ellipsize(GTK_LABEL(label_filetype), PANGO_ELLIPSIZE_END); + gtk_label_set_ellipsize(GTK_LABEL(label_filesize), PANGO_ELLIPSIZE_END); + gtk_label_set_width_chars(GTK_LABEL(label_filename), 20); + + // Pack widgets + gtk_image_set_pixel_size(GTK_IMAGE(image), 48); + gtk_box_append(GTK_BOX(under_box), image); + gtk_box_append(GTK_BOX(info_box), label_filename); + gtk_box_append(GTK_BOX(info_box), label_filetype); + gtk_box_append(GTK_BOX(info_box), label_filesize); + gtk_box_append(GTK_BOX(under_box), info_box); + + gtk_list_item_set_child(item, under_box); +} + +static void bind_grid_item(GtkListItemFactory *factory, GtkListItem *item) +{ + GtkWidget *under_box, *info_box; + GtkWidget *image; + GtkWidget *label_filename, *label_filetype, *label_filesize; + // Get Widgets + under_box = gtk_list_item_get_child(item); + image = gtk_widget_get_first_child(under_box); + info_box = gtk_widget_get_next_sibling(image); + label_filename = gtk_widget_get_first_child(info_box); + label_filetype = gtk_widget_get_next_sibling(label_filename); + label_filesize = gtk_widget_get_next_sibling(label_filetype); + + // Get GFileInfo + GFileInfo *info = G_FILE_INFO(gtk_list_item_get_item(item)); + + // The icon for file or folders + gtk_image_set_from_gicon(GTK_IMAGE(image), g_file_info_get_icon(info)); + + // File name, content type and size + gtk_label_set_label(GTK_LABEL(label_filename), g_file_info_get_display_name(info)); + gtk_label_set_label(GTK_LABEL(label_filetype), g_file_info_get_content_type(info)); + gtk_label_set_label(GTK_LABEL(label_filesize), g_format_size(g_file_info_get_size(info))); +} + +static void gridview_activate(GtkGridView *view, guint position, FileWindow *win) +{ + // Get the model + GtkSelectionModel *model = gtk_grid_view_get_model(view); + GFileInfo *info = G_FILE_INFO(g_list_model_get_item(G_LIST_MODEL(model), position)); + GtkDirectoryList *list = GTK_DIRECTORY_LIST(file_window_get_grid_model(win)); + + // if the file type is directory, open the directory + if (check_directory(info)) + { + // Get the file and set it to the GtkDirectoryList + GFile *file = G_FILE(g_file_info_get_attribute_object(info, "standard::file")); + gtk_directory_list_set_file(list, file); + + // Update string in the entry for path + char *path = g_file_get_path(file); + gtk_editable_set_text(GTK_EDITABLE(file_window_get_folder_entry(win)), path); + g_free(path); + } + g_object_unref(info); +} + +GtkWidget *create_grid_view(FileWindow *win) +{ + // Get model for grid view + GListModel *model = file_window_get_grid_model(win); + + // Create factory + GtkListItemFactory *factory = gtk_signal_list_item_factory_new(); + g_signal_connect(factory, "setup", G_CALLBACK(setup_grid_item), NULL); + g_signal_connect(factory, "bind", G_CALLBACK(bind_grid_item), NULL); + + // Create view + GtkSingleSelection *selection = gtk_single_selection_new(model); + GtkWidget *grid_view = gtk_grid_view_new(GTK_SELECTION_MODEL(selection), factory); + + // Link Signal + g_signal_connect(grid_view, "activate", G_CALLBACK(gridview_activate), win); + + return grid_view; +} diff --git a/Gtk4_Reset/src/file_app/FileGridView.h b/Gtk4_Reset/src/file_app/FileGridView.h new file mode 100644 index 0000000..b55e42d --- /dev/null +++ b/Gtk4_Reset/src/file_app/FileGridView.h @@ -0,0 +1,5 @@ +#pragma once + +#include "FileWindow.h" + +GtkWidget *create_grid_view(FileWindow *win); diff --git a/Gtk4_Reset/src/file_app/FileWindow.cc b/Gtk4_Reset/src/file_app/FileWindow.cc deleted file mode 100644 index e320500..0000000 --- a/Gtk4_Reset/src/file_app/FileWindow.cc +++ /dev/null @@ -1,331 +0,0 @@ -#include "FileWindow.hh" -#include - -FileWindow::FileWindow() -:parent_str("/"), -vbox(Gtk::Orientation::VERTICAL,5), -btnbox(Gtk::Orientation::HORIZONTAL,5), -menubox(Gtk::Orientation::VERTICAL,5), -show_hidden("Show hidden files") -{ - //Initalize Window - set_default_size(650,400); - set_icon_name("file-app"); - set_title("File Manager"); - - //Load Pixbufs - auto pixbuf1 = Gdk::Pixbuf::create_from_resource("/org/gtk/daleclack/gnome-fs-regular.svg"); - file_pixbuf = pixbuf1->scale_simple(48,48,Gdk::InterpType::BILINEAR); - pixbuf1.reset(); - pixbuf1 = Gdk::Pixbuf::create_from_resource("/org/gtk/daleclack/folder.svg"); - folder_pixbuf = pixbuf1->scale_simple(48,48,Gdk::InterpType::BILINEAR); - pixbuf1.reset(); - - //Create Child Widgets - vbox.append(btnbox,Gtk::PACK_SHRINK); - add(vbox); - - m_toolbar.set_toolbar_style(Gtk::TOOLBAR_ICONS); - btnbox.append(m_toolbar,Gtk::PACK_SHRINK); - btnbox.prepend(m_viewbar,Gtk::PACK_SHRINK); - - //"Up" Button - up_button.set_icon_name("go-up"); - up_button.set_is_important(); - up_button.set_sensitive(false); - up_button.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btnup_clicked)); - m_toolbar.insert(up_button,-1); - - //"Home" Button - home_button.set_icon_name("go-home"); - home_button.set_is_important(); - home_button.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btnhome_clicked)); - m_toolbar.insert(home_button,-1); - - //"New Folder" Button - new_button.set_icon_name("folder-new"); - new_button.set_is_important(); - new_button.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btnnew_clicked)); - m_toolbar.insert(new_button,-1); - - //"Delete" Button - delete_button.set_icon_name("edit-delete"); - delete_button.set_is_important(); - delete_button.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btndel_clicked)); - m_toolbar.insert(delete_button,-1); - - //"View Mode" Button - view_item.add(view_button); - view_mode=ViewMode::MODE_ICON; - view_button.set_has_frame(false); - view_button.set_image_from_icon_name("view-grid-symbolic",Gtk::ICON_SIZE_LARGE_TOOLBAR); - view_button.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btnview_clicked)); - m_viewbar.insert(view_item,-1); - - //Menu Button - menu_item.add(menubtn); - menubtn.set_has_frame(false); - m_viewbar.insert(menu_item,-1); - m_viewbar.set_toolbar_style(Gtk::TOOLBAR_ICONS); - show_hidden.set_active(false); - show_hidden.signal_clicked().connect(sigc::mem_fun(*this,&FileWindow::btnhide_clicked)); - menubox.append(show_hidden,Gtk::PACK_SHRINK); - popover.add(menubox); - menubtn.set_popover(popover); - popover.show_all_children(); - - //Info Bar - m_infobar.add_button("OK",Gtk::RESPONSE_OK); - auto pbox = dynamic_cast(m_infobar.get_content_area()); - pbox->add(info_label); - vbox.append(m_infobar,Gtk::PACK_SHRINK); - m_infobar.signal_response().connect(sigc::mem_fun(*this,&FileWindow::infobar_response)); - - //Create Store - m_liststore = Gtk::ListStore::create(columns); - m_liststore->set_default_sort_func(sigc::mem_fun(*this,&FileWindow::sort_func)); - m_liststore->set_sort_column(-1,Gtk::SORT_ASCENDING); - fill_store(); - - initalize_views(); - m_sw.add(stack); - vbox.append(m_sw); - - show_all_children(); - m_infobar.hide(); -} - -void FileWindow::go_home(){ - btnhome_clicked(); -} - -int FileWindow::sort_func(const Gtk::TreeModel::iterator &a,const Gtk::TreeModel::iterator &b){ - bool is_dir_a,is_dir_b; - Glib::ustring name_a,name_b; - - auto row_a= *a,row_b= *b; - is_dir_a = row_a[columns.m_col_is_dir]; - is_dir_b = row_b[columns.m_col_is_dir]; - name_a = row_a[columns.m_col_display_name]; - name_b = row_b[columns.m_col_display_name]; - - if(!is_dir_a && is_dir_b){ - return 1; - } - if(is_dir_a && !is_dir_b){ - return -1; - } - if(name_a[0] != '.' && name_b[0] == '.'){ - return 1; - } - if(name_a[0] == '.' && name_b[0] != '.'){ - return -1; - }else{ - return g_utf8_collate(name_a.c_str(),name_b.c_str()); - } -} - -void FileWindow::fill_store(){ - Gtk::TreeModel::iterator iter; - - //Clear the store - m_liststore->clear(); - - //Go through the directory and get information - try{ - Glib::Dir dir1(parent_str); - bool is_dir; - Glib::ustring display_name; - std::string dir_name; - /* Ignore the files start with '.' when the button is not toggled */ - do{ - dir_name = dir1.read_name(); - //std::cout<append()); - row[columns.m_col_display_name] = display_name; - row[columns.m_col_is_dir] = is_dir; - row[columns.m_col_path] = Glib::ustring(path); - row[columns.m_col_pixbuf] = is_dir ? folder_pixbuf : file_pixbuf; - } - - g_free(path); - - }while(dir_name != ""); - } - catch(const Glib::Error &ex){ - std::cout << ex.what() << std::endl; - parent_str = tmp_str; - fill_store(); - } -} - -void FileWindow::initalize_views(){ - //Initalize IconView - m_iconview.set_model(m_liststore); - m_iconview.set_text_column(columns.m_col_display_name); - m_iconview.set_pixbuf_column(columns.m_col_pixbuf); - m_iconview.set_selection_mode(Gtk::SELECTION_MULTIPLE); - m_iconview.signal_item_activated().connect(sigc::mem_fun(*this,&FileWindow::item_activated)); - m_iconview.set_row_spacing(0); - - //Initalize TreeView - m_treeview.set_model(m_liststore); - m_treeview.append_column("",columns.m_col_pixbuf); - m_treeview.append_column("Name",columns.m_col_display_name); - m_treeview.signal_row_activated().connect(sigc::mem_fun(*this,&FileWindow::row_activated)); - - stack.add(m_iconview); - stack.add(m_treeview); -} - -void FileWindow::item_activated(const Gtk::TreePath &path){ - auto row = *(m_liststore->get_iter(path)); - bool is_dir; - Glib::ustring path_name; - - //Backup current parent dir - tmp_str = parent_str; - - //Get Path Name and read - path_name = row[columns.m_col_path]; - is_dir = row[columns.m_col_is_dir]; - - if(!is_dir){return ;} - - parent_str = path_name; - - fill_store(); - up_button.set_sensitive(); -} - -void FileWindow::row_activated(const Gtk::TreePath &path,Gtk::TreeViewColumn * sel_column){ - auto row = *(m_liststore->get_iter(path)); - bool is_dir; - Glib::ustring path_name; - - //Backup current parent dir - tmp_str = parent_str; - - //Get Path Name and read - path_name = row[columns.m_col_path]; - is_dir = row[columns.m_col_is_dir]; - - if(!is_dir){return ;} - - parent_str = path_name; - - fill_store(); - up_button.set_sensitive(); -} - -void FileWindow::btnup_clicked(){ - //Go to upper dir - Glib::ustring dir_name; - dir_name = Glib::path_get_dirname(parent_str); - parent_str = dir_name; - fill_store(); -} - -void FileWindow::btnhome_clicked(){ - //Go to home dir - parent_str = Glib::ustring(Glib::get_home_dir()); - fill_store(); -} - -void FileWindow::btnnew_clicked(){ - //Create Dialog - Gtk::Dialog * dialog = new Gtk::Dialog("Create a folder",*this,Gtk::DIALOG_USE_HEADER_BAR); - dialog->add_button("OK",Gtk::RESPONSE_OK); - dialog->set_default_response(Gtk::RESPONSE_OK); - - //Add Entry - Gtk::Box * pbox = dialog->get_content_area(); - pbox->add(entry_file); - entry_file.set_activates_default(); - - dialog->signal_response().connect(sigc::bind(sigc::mem_fun(*this,&FileWindow::dialog_response),dialog)); - dialog->show_all(); -} - -void FileWindow::btndel_clicked(){ - Glib::ustring tmp; - switch(view_mode){ - case ViewMode::MODE_ICON: - { - auto selected_items = m_iconview.get_selected_items(); - for(auto it = selected_items.begin();it != selected_items.end(); it++){ - auto row = *(m_liststore->get_iter(*it)); - tmp = row[columns.m_col_path] + " delete failed!"; - info_label.set_text(tmp); - m_infobar.show(); - } - selected_items.clear(); - } - break; - case ViewMode::MODE_LIST: - { - auto selected_item = m_treeview.get_selection(); - auto row = *(selected_item->get_selected()); - tmp = row[columns.m_col_path] + " delete failed!"; - info_label.set_text(tmp); - m_infobar.show(); - selected_item.reset(); - } - break; - } -} - -void FileWindow::btnview_clicked(){ - switch(view_mode){ - case ViewMode::MODE_ICON: - stack.set_visible_child(m_treeview); - view_button.set_image_from_icon_name("view-list-symbolic",Gtk::ICON_SIZE_LARGE_TOOLBAR); - view_mode = ViewMode::MODE_LIST; - break; - case ViewMode::MODE_LIST: - stack.set_visible_child(m_iconview); - view_button.set_image_from_icon_name("view-grid-symbolic",Gtk::ICON_SIZE_LARGE_TOOLBAR); - view_mode = ViewMode::MODE_ICON; - break; - } -} - -void FileWindow::infobar_response(int response_id){ - m_infobar.hide(); -} - -void FileWindow::dialog_response(int response_id,Gtk::Dialog * dialog){ - if(response_id == Gtk::RESPONSE_OK){ - Glib::ustring folder_name = entry_file.get_text(); - if(parent_str.length() == 1 && parent_str[0] == '/'){ - folder_name = parent_str + folder_name; - }else{ - folder_name = parent_str + "/" + folder_name; - } - if(g_mkdir_with_parents(folder_name.c_str(),0755) == -1){ - std::cout<<"Error Occured"<view_mode == ViewMode::MODE_LIST) + { + // In list view mode, get current directory from the model1 + file = gtk_directory_list_get_file(GTK_DIRECTORY_LIST(win->model_column)); + } + else + { + // In list view mode, get current directory from the model2 + file = gtk_directory_list_get_file(GTK_DIRECTORY_LIST(win->model_grid)); + } + return file; +} + +static void sync_models(gpointer model1, gpointer model2, SyncMode mode) +{ + if (mode == SyncMode::MODEL_COLUMN_TO_GRID) + { + // Set the file from model1 + GFile *file = gtk_directory_list_get_file(GTK_DIRECTORY_LIST(model1)); + if (file) + { + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(model2), file); + } + // g_object_unref(file); + } + else + { + // Set the file from model2 + GFile *file = gtk_directory_list_get_file(GTK_DIRECTORY_LIST(model2)); + if (file) + { + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(model1), file); + } + // g_object_unref(file); + } +} + +static void btnview_clicked(GtkButton *button, FileWindow *win) +{ + if (win->view_mode == ViewMode::MODE_LIST) + { + // Sync the models + sync_models(win->model_column, win->model_grid, SyncMode::MODEL_COLUMN_TO_GRID); + + // Change view mode from list to grid + gtk_stack_set_visible_child(GTK_STACK(win->stack), win->scrolled_window_grid); + gtk_button_set_icon_name(button, "filewin-view-grid"); + win->view_mode = ViewMode::MODE_GRID; + } + else + { + // Sync the models + sync_models(win->model_column, win->model_grid, SyncMode::MODEL_GRID_TO_COLUMN); + + // Change view mode from grid to list + gtk_stack_set_visible_child(GTK_STACK(win->stack), win->scrolled_window_column); + gtk_button_set_icon_name(button, "filewin-view-list"); + win->view_mode = ViewMode::MODE_LIST; + } +} + +static void btnup_clicked(GtkWidget *widget, FileWindow *win) +{ + // Get current directory and set to the new list + GFile *file = file_window_get_file(win); + char *path_str = g_file_get_path(file); + if (!(g_str_equal(path_str, "/") || (path_str[2] = '\\' && strlen(path_str) == 3))) + { + GFile *file1 = g_file_get_parent(file); + + // Set the directory of models + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_column), file1); + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_grid), file1); + + // Update string in the entry for path + char *path = g_file_get_path(file1); + gtk_editable_set_text(GTK_EDITABLE(win->folder_entry), path); + g_free(path); + + g_object_unref(file1); + } + else + { + GFile *file1 = g_file_new_for_path("/"); + + // Set the directory of models + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_column), file1); + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_grid), file1); + + // Update string in the entry for path + char *path = g_file_get_path(file1); + gtk_editable_set_text(GTK_EDITABLE(win->folder_entry), path); + g_free(path); + + g_object_unref(file1); + } +} + +static void btnok_clicked(GtkWidget *widget, GtkWidget *dialog) +{ + // Get entry widget and the content of entry + GtkWidget *entry_new = gtk_widget_get_first_child(dialog); + const char *file_name = gtk_editable_get_text(GTK_EDITABLE(entry_new)); + + // Get the parent dir of file + FileWindow *win = FILE_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(dialog))); + GFile *file = file_window_get_file(win); + char *parent_dir = g_file_get_path(file); + char *path = NULL; + + // Create a new folder + if (parent_dir[strlen(parent_dir) - 1] != '/') + { + path = g_strdup_printf("%s/%s", parent_dir, file_name); + } + else + { + path = g_strdup_printf("%s%s", parent_dir, file_name); + } + if (g_mkdir_with_parents(path, 0755) == -1) + { + g_print("Error Occured!"); + } + // g_print("%s\n", path); + + g_free(parent_dir); + g_free(path); + gtk_window_destroy(GTK_WINDOW(dialog)); +} + +static void btnnew_clicked(GtkWidget *widget, FileWindow *win) +{ + GtkWidget *dialog_new; + + // Create the window + dialog_new = gtk_window_new(); + gtk_window_set_title(GTK_WINDOW(dialog_new), "Create Folder"); + gtk_window_set_transient_for(GTK_WINDOW(dialog_new), GTK_WINDOW(win)); + + // Add the entry and the "OK" button + GtkWidget *header, *btn_ok, *entry_new; + header = gtk_header_bar_new(); + btn_ok = gtk_button_new_with_label("OK"); + entry_new = gtk_entry_new(); + + // Link signal for "OK" button + g_signal_connect(entry_new, "activate", G_CALLBACK(btnok_clicked), dialog_new); + g_signal_connect(btn_ok, "clicked", G_CALLBACK(btnok_clicked), dialog_new); + + // Add widgets to window + gtk_header_bar_pack_end(GTK_HEADER_BAR(header), btn_ok); + gtk_window_set_titlebar(GTK_WINDOW(dialog_new), header); + gtk_window_set_child(GTK_WINDOW(dialog_new), entry_new); + + gtk_window_present(GTK_WINDOW(dialog_new)); +} + +void home_clicked(GtkWidget *widget, FileWindow *win) +{ + // Set Current dir to home dir + GFile *file = g_file_new_for_path(g_get_home_dir()); + + // Update string in the entry for path + char *path = g_file_get_path(file); + gtk_editable_set_text(GTK_EDITABLE(win->folder_entry), path); + g_free(path); + + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_column), file); + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_grid), file); + g_object_unref(file); +} + +static void btndel_clicked(GtkWidget *widget, FileWindow *win) +{ + GtkWidget *error_dialog; + + // Create dialog + error_dialog = gtk_window_new(); + gtk_window_set_title(GTK_WINDOW(error_dialog), "Error"); + gtk_window_set_transient_for(GTK_WINDOW(error_dialog), GTK_WINDOW(win)); + + // Add a header bar + GtkWidget *header = gtk_header_bar_new(); + GtkWidget *btn_ok = gtk_button_new_with_label("OK"); + gtk_header_bar_pack_end(GTK_HEADER_BAR(header), btn_ok); + gtk_window_set_titlebar(GTK_WINDOW(error_dialog), header); + g_signal_connect_swapped(btn_ok, "clicked", G_CALLBACK(gtk_window_destroy), error_dialog); + + // Add a label and a icon to show error + GtkWidget *dialog_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + GtkWidget *image = gtk_image_new_from_resource("/org/gtk/daleclack/dialog-error.png"); + GtkWidget *label = gtk_label_new("Failed to delete file"); + gtk_image_set_pixel_size(GTK_IMAGE(image), 48); + + // Add widgets to the dialog + gtk_widget_set_margin_bottom(dialog_box, 20); + gtk_widget_set_margin_end(dialog_box, 20); + gtk_widget_set_margin_start(dialog_box, 20); + gtk_widget_set_margin_top(dialog_box, 20); + gtk_box_append(GTK_BOX(dialog_box), image); + gtk_box_append(GTK_BOX(dialog_box), label); + gtk_window_set_child(GTK_WINDOW(error_dialog), dialog_box); + + gtk_window_present(GTK_WINDOW(error_dialog)); +} + +static void folder_entry_activated(GtkWidget *widget, FileWindow *win) +{ + // Get Path and create a associated file + const char *path = gtk_editable_get_text(GTK_EDITABLE(widget)); + GFile *file = g_file_new_for_path(path); + + // Set the directory of models + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_column), file); + gtk_directory_list_set_file(GTK_DIRECTORY_LIST(win->model_grid), file); +} + +GListModel *file_window_get_grid_model(FileWindow *self) +{ + // Get Model for grid view + return self->model_grid; +} + +GListModel *file_window_get_column_model(FileWindow *self) +{ + // Get Model for list column view + return self->model_column; +} + +GtkWidget *file_window_get_folder_entry(FileWindow *self) +{ + // Get the entry widget + return self->folder_entry; +} + +static void file_window_dispose(GObject *object) +{ + // Clear List Model + G_OBJECT_CLASS(file_window_parent_class)->dispose(object); +} + +static void file_window_init(FileWindow *self) +{ + GtkColumnViewColumn *column; + // Initalize window + gtk_window_set_title(GTK_WINDOW(self), "My Finder"); + gtk_window_set_icon_name(GTK_WINDOW(self), "file-manager1"); + gtk_window_set_default_size(GTK_WINDOW(self), 640, 400); + + // Create list model + GFile *file = g_file_new_for_path(g_get_home_dir()); + self->model_column = G_LIST_MODEL(gtk_directory_list_new( + "standard::name,standard::display-name,standard::icon,standard::size,standard::content-type", file)); + + self->model_grid = G_LIST_MODEL(gtk_directory_list_new( + "standard::name,standard::display-name,standard::icon,standard::size,standard::content-type", file)); + + // Create column view widget + self->column_view = create_column_view(self); + + // Create grid view widget + self->grid_view = create_grid_view(self); + + // Create buttons + self->btn_up = gtk_button_new_from_icon_name("filewin-go-up"); + self->btn_home = gtk_button_new_from_icon_name("filewin-go-home"); + self->btn_new = gtk_button_new_from_icon_name("filewin-new"); + self->btn_del = gtk_button_new_from_icon_name("filewin-delete"); + self->btn_view = gtk_button_new_from_icon_name("filewin-view-list"); + + // Create entry for show and change the current folder + self->folder_entry = gtk_entry_new(); + gtk_editable_set_text(GTK_EDITABLE(self->folder_entry), g_get_home_dir()); + + // Create widgets for layout + self->scrolled_window_column = gtk_scrolled_window_new(); + self->scrolled_window_grid = gtk_scrolled_window_new(); + self->main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + self->btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + self->stack = gtk_stack_new(); + self->separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); + + // Add buttons to the btn_box + gtk_widget_set_hexpand(self->btn_box, TRUE); + gtk_box_append(GTK_BOX(self->btn_box), self->btn_up); + gtk_box_append(GTK_BOX(self->btn_box), self->btn_home); + gtk_box_append(GTK_BOX(self->btn_box), self->btn_new); + gtk_box_append(GTK_BOX(self->btn_box), self->btn_del); + gtk_widget_set_hexpand(self->separator, TRUE); + // gtk_widget_set_halign(self->btn_view, GTK_ALIGN_END); + gtk_box_append(GTK_BOX(self->btn_box), self->separator); + gtk_box_append(GTK_BOX(self->btn_box), self->btn_view); + + // Link signals + g_signal_connect(self->btn_view, "clicked", G_CALLBACK(btnview_clicked), self); + g_signal_connect(self->btn_up, "clicked", G_CALLBACK(btnup_clicked), self); + g_signal_connect(self->btn_home, "clicked", G_CALLBACK(home_clicked), self); + g_signal_connect(self->btn_del, "clicked", G_CALLBACK(btndel_clicked), self); + g_signal_connect(self->btn_new, "clicked", G_CALLBACK(btnnew_clicked), self); + g_signal_connect(self->folder_entry, "activate", G_CALLBACK(folder_entry_activated), self); + + // Add scrolled window for columns view + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->scrolled_window_column), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_widget_set_hexpand(self->scrolled_window_column, TRUE); + gtk_widget_set_vexpand(self->scrolled_window_column, TRUE); + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(self->scrolled_window_column), self->column_view); + gtk_stack_add_named(GTK_STACK(self->stack), self->scrolled_window_column, "Column View"); + + // Add scrolled window for grid view + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->scrolled_window_grid), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_widget_set_hexpand(self->scrolled_window_grid, TRUE); + gtk_widget_set_vexpand(self->scrolled_window_grid, TRUE); + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(self->scrolled_window_grid), self->grid_view); + gtk_stack_add_named(GTK_STACK(self->stack), self->scrolled_window_grid, "Grid View"); + + gtk_box_append(GTK_BOX(self->main_box), self->btn_box); // Box for control buttons + gtk_box_append(GTK_BOX(self->main_box), self->folder_entry); // Box for folder switcher + gtk_box_append(GTK_BOX(self->main_box), self->stack); // Box for main area + // gtk_stack_set_visible_child(GTK_STACK(self->stack), self->scrolled_window_grid); + gtk_window_set_child(GTK_WINDOW(self), self->main_box); +} + +static void file_window_class_init(FileWindowClass *klass) +{ + G_OBJECT_CLASS(klass)->dispose = file_window_dispose; +} + +FileWindow *file_window_new(GtkWindow *win) +{ + return FILE_WINDOW(g_object_new(file_window_get_type(), "transient-for", win, NULL)); +} diff --git a/Gtk4_Reset/src/file_app/GetFileType.h b/Gtk4_Reset/src/file_app/GetFileType.h new file mode 100644 index 0000000..6529a18 --- /dev/null +++ b/Gtk4_Reset/src/file_app/GetFileType.h @@ -0,0 +1,27 @@ +/* +Patch for Microsoft Windows +*/ +#pragma once + +#include +#include + +// Check the whether the selected file is directory +static inline gboolean check_directory(GFileInfo *info) +{ +#ifdef _WIN32 + // Since all files for windows will be "unknown" type, + // use content type to check file. + const char *file_type = g_file_info_get_content_type(info); + if(strncmp(file_type, "inode/directory", strlen("inode/directory")) == 0) + { + return TRUE; + } +#else + if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY){ + return TRUE; + } +#endif + // Not a directory, return FALSE + return FALSE; +} diff --git a/Gtk4_Reset/src/ui/MyDock.cpp b/Gtk4_Reset/src/ui/MyDock.cpp index 039d265..e97da6e 100644 --- a/Gtk4_Reset/src/ui/MyDock.cpp +++ b/Gtk4_Reset/src/ui/MyDock.cpp @@ -1,6 +1,7 @@ #include "MyDock.h" #include "MyFinder.h" #include "AppView.h" +#include "FileWindow.h" enum PadPage { @@ -32,6 +33,7 @@ struct _MyDock GtkGesture *gesture; GtkWidget *context_menu; // Context menu MyPrefs *prefs_win; // Prefs window + FileWindow *file_win; // File Broswer window }; G_DEFINE_TYPE(MyDock, my_dock, GTK_TYPE_BOX) @@ -140,14 +142,54 @@ static void btnset_clicked(GtkWidget *widget, MyDock *dock) gtk_image_set_from_icon_name(GTK_IMAGE(dock->image_set), "my_prefs_running"); } -static gboolean prefs_win_closed(GtkWindow *window, MyDock *dock) +static gboolean prefs_win_closed(GtkWidget *window, MyDock *dock) { // For the preferences window, hide it - gtk_widget_set_visible(GTK_WIDGET(dock->prefs_win), FALSE); + gtk_widget_set_visible(window, FALSE); gtk_image_set_from_icon_name(GTK_IMAGE(dock->image_set), "my_prefs"); return TRUE; } +static void btnfiles_clicked(GtkWindow *window, MyDock *dock) +{ + // When the window visible, unminimize it + if (gtk_widget_get_visible(GTK_WIDGET((dock->file_win)))) + { + gtk_window_unminimize(GTK_WINDOW(dock->file_win)); + } + else + { + // Show the window + gtk_window_set_transient_for(GTK_WINDOW(dock->file_win), dock->parent_win); + gtk_window_present(GTK_WINDOW(dock->file_win)); + } + gtk_image_set_from_icon_name(GTK_IMAGE(dock->image_file), "file-app_running"); +} + +static void padfiles_clicked(GtkWindow *window, MyDock *dock) +{ + // When the window visible, control window state + if (gtk_widget_get_visible(GTK_WIDGET((dock->file_win)))) + { + window_ctrl(GTK_WINDOW(dock->file_win), dock->parent_win); + } + else + { + // Show the window + gtk_window_set_transient_for(GTK_WINDOW(dock->file_win), dock->parent_win); + gtk_window_present(GTK_WINDOW(dock->file_win)); + } + gtk_image_set_from_icon_name(GTK_IMAGE(dock->image_file), "file-app_running"); +} + +static gboolean file_window_closed(GtkWidget *window, MyDock *dock) +{ + // Hide the window + gtk_widget_set_visible(window, FALSE); + gtk_image_set_from_icon_name(GTK_IMAGE(dock->image_file), "file-app"); + return TRUE; +} + static void my_dock_get_widgets(MyDock *self) { // Get widgets @@ -242,6 +284,15 @@ static void my_dock_init(MyDock *self) // Create prefs window self->prefs_win = my_prefs_new(); my_prefs_set_background(self->prefs_win, self->main_pic); + g_signal_connect(self->btnset, "clicked", G_CALLBACK(btnset_clicked), self); + g_signal_connect(self->padset, "clicked", G_CALLBACK(padset_clicked), self); + g_signal_connect(self->prefs_win, "close-request", G_CALLBACK(prefs_win_closed), self); + + // Create File Browser Window + self->file_win = file_window_new(self->parent_win); + g_signal_connect(self->btnfiles, "clicked", G_CALLBACK(btnfiles_clicked), self); + g_signal_connect(self->padfile, "clicked", G_CALLBACK(padfiles_clicked), self); + g_signal_connect(self->file_win, "close-request", G_CALLBACK(file_window_closed), self); // Add finder self->finder = my_finder_new(GTK_ORIENTATION_HORIZONTAL, 5); @@ -286,9 +337,6 @@ static void my_dock_init(MyDock *self) // Link Signals g_signal_connect(self->btnlaunch, "clicked", G_CALLBACK(btnlaunch_clicked), self); - g_signal_connect(self->btnset, "clicked", G_CALLBACK(btnset_clicked), self); - g_signal_connect(self->padset, "clicked", G_CALLBACK(padset_clicked), self); - g_signal_connect(self->prefs_win, "close-request", G_CALLBACK(prefs_win_closed), self); // Create Css Provider for styling GtkCssProvider *provider = gtk_css_provider_new(); @@ -304,7 +352,6 @@ static void my_dock_init(MyDock *self) my_finder_add_style(MY_FINDER(self->finder), provider); // Add Apps grid - // To make the default view layout same as the addon apps view self->appgrid_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); self->appgrid_label = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);