mirror of
https://github.com/RGBCube/serenity
synced 2025-05-23 18:25:08 +00:00
LibGUI: Generate nicer icons for symlinked files
Instead of symlinks showing up with the "filetype-symlink" icon, we now generate a new icon by taking the target file's icon and slapping a small arrow emblem on top of it. This looks rather nice. :^)
This commit is contained in:
parent
3d5e30a1e6
commit
c44dbabda1
3 changed files with 38 additions and 2 deletions
|
@ -24,11 +24,14 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/ConfigFile.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/StandardPaths.h>
|
||||
#include <LibGUI/FileIconProvider.h>
|
||||
#include <LibGUI/Icon.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -45,6 +48,8 @@ static Icon s_symlink_icon;
|
|||
static Icon s_socket_icon;
|
||||
static Icon s_executable_icon;
|
||||
static Icon s_filetype_image_icon;
|
||||
static RefPtr<Gfx::Bitmap> s_symlink_emblem;
|
||||
static RefPtr<Gfx::Bitmap> s_symlink_emblem_small;
|
||||
|
||||
static HashMap<String, Icon> s_filetype_icons;
|
||||
static HashMap<String, Vector<String>> s_filetype_patterns;
|
||||
|
@ -57,6 +62,9 @@ static void initialize_if_needed()
|
|||
|
||||
auto config = Core::ConfigFile::open("/etc/FileIconProvider.ini");
|
||||
|
||||
s_symlink_emblem = Gfx::Bitmap::load_from_file("/res/icons/symlink-emblem.png");
|
||||
s_symlink_emblem_small = Gfx::Bitmap::load_from_file("/res/icons/symlink-emblem-small.png");
|
||||
|
||||
s_hard_disk_icon = Icon::default_icon("hard-disk");
|
||||
s_directory_icon = Icon::default_icon("filetype-folder");
|
||||
s_directory_open_icon = Icon::default_icon("filetype-folder-open");
|
||||
|
@ -127,8 +135,36 @@ Icon FileIconProvider::icon_for_path(const String& path, mode_t mode)
|
|||
return s_inaccessible_directory_icon;
|
||||
return s_directory_icon;
|
||||
}
|
||||
if (S_ISLNK(mode))
|
||||
return s_symlink_icon;
|
||||
if (S_ISLNK(mode)) {
|
||||
auto raw_symlink_target = Core::File::read_link(path);
|
||||
if (raw_symlink_target.is_null())
|
||||
return s_symlink_icon;
|
||||
|
||||
String target_path;
|
||||
if (raw_symlink_target.starts_with('/')) {
|
||||
target_path = raw_symlink_target;
|
||||
} else {
|
||||
target_path = Core::File::real_path_for(String::formatted("{}/{}", LexicalPath(path).dirname(), raw_symlink_target));
|
||||
}
|
||||
auto target_icon = icon_for_path(target_path);
|
||||
|
||||
Icon generated_icon;
|
||||
for (auto size : target_icon.sizes()) {
|
||||
auto& emblem = size < 32 ? *s_symlink_emblem_small : *s_symlink_emblem;
|
||||
auto original_bitmap = target_icon.bitmap_for_size(size);
|
||||
ASSERT(original_bitmap);
|
||||
auto generated_bitmap = original_bitmap->clone();
|
||||
if (!generated_bitmap) {
|
||||
dbgln("Failed to clone {}x{} icon for symlink variant", size, size);
|
||||
return s_symlink_icon;
|
||||
}
|
||||
GUI::Painter painter(*generated_bitmap);
|
||||
painter.blit({ size - emblem.width(), size - emblem.height() }, emblem, emblem.rect());
|
||||
|
||||
generated_icon.set_bitmap_for_size(size, move(generated_bitmap));
|
||||
}
|
||||
return generated_icon;
|
||||
}
|
||||
if (S_ISSOCK(mode))
|
||||
return s_socket_icon;
|
||||
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue