file-browser: fixup ellipses for file types
This commit is contained in:
parent
a5cf4fe540
commit
3a130854e7
@ -60,9 +60,9 @@ static int available_height = 0; /* How much space is available in the main wind
|
|||||||
static int is_desktop_background = 0; /* If we're in desktop background mode */
|
static int is_desktop_background = 0; /* If we're in desktop background mode */
|
||||||
static int menu_bar_height = MENU_BAR_HEIGHT + 36; /* Height of the menu bar, if present - it's not in desktop mode */
|
static int menu_bar_height = MENU_BAR_HEIGHT + 36; /* Height of the menu bar, if present - it's not in desktop mode */
|
||||||
static sprite_t * wallpaper_buffer = NULL; /* Prebaked wallpaper texture */
|
static sprite_t * wallpaper_buffer = NULL; /* Prebaked wallpaper texture */
|
||||||
static sprite_t * wallpaper_old = NULL;
|
static sprite_t * wallpaper_old = NULL; /* Previous wallpaper when transitioning */
|
||||||
static uint64_t timer = 0;
|
static uint64_t timer = 0; /* Timer for wallpaper transition fade */
|
||||||
static int restart = 0;
|
static int restart = 0; /* Signal for desktop wallpaper to kill itself to save memory (this is dumb) */
|
||||||
static char title[512]; /* Application title bar */
|
static char title[512]; /* Application title bar */
|
||||||
static int FILE_HEIGHT = 80; /* Height of one row of icons */
|
static int FILE_HEIGHT = 80; /* Height of one row of icons */
|
||||||
static int FILE_WIDTH = 100; /* Width of one column of icons */
|
static int FILE_WIDTH = 100; /* Width of one column of icons */
|
||||||
@ -76,13 +76,18 @@ static ssize_t file_pointers_len = 0; /* How many files are in the current list
|
|||||||
static uint64_t last_click = 0; /* For double click */
|
static uint64_t last_click = 0; /* For double click */
|
||||||
static int last_click_offset = -1; /* So that clicking two different things quickly doesn't count as a double click */
|
static int last_click_offset = -1; /* So that clicking two different things quickly doesn't count as a double click */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigation input box
|
||||||
|
*/
|
||||||
static char nav_bar[512] = {0};
|
static char nav_bar[512] = {0};
|
||||||
static int nav_bar_cursor = 0;
|
static int nav_bar_cursor = 0;
|
||||||
static int nav_bar_cursor_x = 0;
|
static int nav_bar_cursor_x = 0;
|
||||||
static int nav_bar_focused = 0;
|
static int nav_bar_focused = 0;
|
||||||
|
|
||||||
|
/* Status bar displayed at the bottom of the window */
|
||||||
static char window_status[512] = {0};
|
static char window_status[512] = {0};
|
||||||
|
|
||||||
|
/* Button row visibility statuses */
|
||||||
static int _button_hilights[4] = {3,3,3,3};
|
static int _button_hilights[4] = {3,3,3,3};
|
||||||
static int _button_disabled[4] = {1,1,0,0};
|
static int _button_disabled[4] = {1,1,0,0};
|
||||||
static int _button_hover = -1;
|
static int _button_hover = -1;
|
||||||
@ -98,6 +103,7 @@ static struct menu_bar_entries menu_entries[] = {
|
|||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Right click context menu */
|
||||||
static struct MenuList * context_menu = NULL;
|
static struct MenuList * context_menu = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,6 +196,27 @@ static int print_human_readable_size(char * _out, uint64_t s) {
|
|||||||
#define HILIGHT_GRADIENT_BOTTOM rgb(56,137,220)
|
#define HILIGHT_GRADIENT_BOTTOM rgb(56,137,220)
|
||||||
#define HILIGHT_BORDER_BOTTOM rgb(47,106,167)
|
#define HILIGHT_BORDER_BOTTOM rgb(47,106,167)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clip text and add ellipsis to fit a specified display width.
|
||||||
|
*/
|
||||||
|
static char * ellipsify(char * input, int font_size, int font, int max_width, int * out_width) {
|
||||||
|
int len = strlen(input);
|
||||||
|
char * out = malloc(len + 4);
|
||||||
|
memcpy(out, input, len + 1);
|
||||||
|
int width;
|
||||||
|
while ((width = draw_sdf_string_width(out, font_size, font)) > max_width) {
|
||||||
|
len--;
|
||||||
|
out[len+0] = '.';
|
||||||
|
out[len+1] = '.';
|
||||||
|
out[len+2] = '.';
|
||||||
|
out[len+3] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_width) *out_width = width;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw an icon view entry
|
* Draw an icon view entry
|
||||||
*/
|
*/
|
||||||
@ -206,17 +233,8 @@ static void draw_file(struct File * f, int offset) {
|
|||||||
sprite_t * icon = icon_get_48(f->icon);
|
sprite_t * icon = icon_get_48(f->icon);
|
||||||
|
|
||||||
/* If the display name is too long to fit, cut it with an ellipsis. */
|
/* If the display name is too long to fit, cut it with an ellipsis. */
|
||||||
int len = strlen(f->name);
|
|
||||||
char * name = malloc(len + 4);
|
|
||||||
memcpy(name, f->name, len + 1);
|
|
||||||
int name_width;
|
int name_width;
|
||||||
while ((name_width = draw_sdf_string_width(name, 16, SDF_FONT_THIN)) > FILE_WIDTH - 8 /* Padding */) {
|
char * name = ellipsify(f->name, 16, SDF_FONT_THIN, FILE_WIDTH - 8, &name_width);
|
||||||
len--;
|
|
||||||
name[len+0] = '.';
|
|
||||||
name[len+1] = '.';
|
|
||||||
name[len+2] = '.';
|
|
||||||
name[len+3] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw the icon */
|
/* Draw the icon */
|
||||||
int center_x_icon = (FILE_WIDTH - icon->width) / 2;
|
int center_x_icon = (FILE_WIDTH - icon->width) / 2;
|
||||||
@ -275,21 +293,12 @@ static void draw_file(struct File * f, int offset) {
|
|||||||
draw_sprite_alpha_paint(contents, icon, x + 11, y + 11, 0.3, rgb(255,255,255));
|
draw_sprite_alpha_paint(contents, icon, x + 11, y + 11, 0.3, rgb(255,255,255));
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = strlen(f->name);
|
char * name = ellipsify(f->name, 16, SDF_FONT_BOLD, FILE_WIDTH - 81, NULL);
|
||||||
char * name = malloc(len + 4);
|
char * type = ellipsify(f->filetype, 16, SDF_FONT_THIN, FILE_WIDTH - 81, NULL);
|
||||||
memcpy(name, f->name, len + 1);
|
|
||||||
int name_width;
|
|
||||||
while ((name_width = draw_sdf_string_width(name, 16, SDF_FONT_BOLD)) > FILE_WIDTH - 81) {
|
|
||||||
len--;
|
|
||||||
name[len+0] = '.';
|
|
||||||
name[len+1] = '.';
|
|
||||||
name[len+2] = '.';
|
|
||||||
name[len+3] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f->type == 0) {
|
if (f->type == 0) {
|
||||||
draw_sdf_string(contents, x + 70, y + 8, name, 16, text_color, SDF_FONT_BOLD);
|
draw_sdf_string(contents, x + 70, y + 8, name, 16, text_color, SDF_FONT_BOLD);
|
||||||
draw_sdf_string(contents, x + 70, y + 25, f->filetype, 16, text_color, SDF_FONT_THIN);
|
draw_sdf_string(contents, x + 70, y + 25, type, 16, text_color, SDF_FONT_THIN);
|
||||||
|
|
||||||
char line_three[48] = {0};
|
char line_three[48] = {0};
|
||||||
if (*f->link) {
|
if (*f->link) {
|
||||||
@ -300,10 +309,11 @@ static void draw_file(struct File * f, int offset) {
|
|||||||
draw_sdf_string(contents, x + 70, y + 42, line_three, 16, text_color, SDF_FONT_THIN);
|
draw_sdf_string(contents, x + 70, y + 42, line_three, 16, text_color, SDF_FONT_THIN);
|
||||||
} else {
|
} else {
|
||||||
draw_sdf_string(contents, x + 70, y + 15, name, 16, text_color, SDF_FONT_BOLD);
|
draw_sdf_string(contents, x + 70, y + 15, name, 16, text_color, SDF_FONT_BOLD);
|
||||||
draw_sdf_string(contents, x + 70, y + 32, f->filetype, 16, text_color, SDF_FONT_THIN);
|
draw_sdf_string(contents, x + 70, y + 32, type, 16, text_color, SDF_FONT_THIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
|
free(type);
|
||||||
} else if (view_mode == VIEW_MODE_LIST) {
|
} else if (view_mode == VIEW_MODE_LIST) {
|
||||||
sprite_t * icon = icon_get_16(f->icon);
|
sprite_t * icon = icon_get_16(f->icon);
|
||||||
uint32_t text_color = rgb(0,0,0);
|
uint32_t text_color = rgb(0,0,0);
|
||||||
@ -326,21 +336,12 @@ static void draw_file(struct File * f, int offset) {
|
|||||||
draw_sprite(contents, icon, x + 4, y + 4);
|
draw_sprite(contents, icon, x + 4, y + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * name = ellipsify(f->name, 16, SDF_FONT_THIN, FILE_WIDTH - 26, NULL);
|
||||||
int len = strlen(f->name);
|
|
||||||
char * name = malloc(len + 4);
|
|
||||||
memcpy(name, f->name, len + 1);
|
|
||||||
int name_width;
|
|
||||||
while ((name_width = draw_sdf_string_width(name, 16, SDF_FONT_THIN)) > FILE_WIDTH - 26) {
|
|
||||||
len--;
|
|
||||||
name[len+0] = '.';
|
|
||||||
name[len+1] = '.';
|
|
||||||
name[len+2] = '.';
|
|
||||||
name[len+3] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_sdf_string(contents, x + 24, y + 2, name, 16, text_color, SDF_FONT_THIN);
|
draw_sdf_string(contents, x + 24, y + 2, name, 16, text_color, SDF_FONT_THIN);
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,9 +405,18 @@ static int has_extension(struct File * f, char * extension) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward/backward history; we're always in the middle of these.
|
||||||
|
* When we navigate somewhere new, clear the forward history, but
|
||||||
|
* keep the back history and append the previous location.
|
||||||
|
*/
|
||||||
static list_t * history_back;
|
static list_t * history_back;
|
||||||
static list_t * history_forward;
|
static list_t * history_forward;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status bar text at the bottom of the window
|
||||||
|
* based on the selected items in the file view.
|
||||||
|
*/
|
||||||
static void update_status(void) {
|
static void update_status(void) {
|
||||||
uint64_t total_size = 0;
|
uint64_t total_size = 0;
|
||||||
uint64_t selected_size = 0;
|
uint64_t selected_size = 0;
|
||||||
@ -444,7 +454,11 @@ static void load_directory(const char * path, int modifies_history) {
|
|||||||
DIR * dirp = opendir(path);
|
DIR * dirp = opendir(path);
|
||||||
|
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
/* XXX show a dialog */
|
/*
|
||||||
|
* Display a warning dialog with the appropriate error message for
|
||||||
|
* why this directory failed to load. XXX This uses `showdialog`
|
||||||
|
* but it should use a dialog library like with the buttons.
|
||||||
|
*/
|
||||||
if (!fork()) {
|
if (!fork()) {
|
||||||
char tmp[512];
|
char tmp[512];
|
||||||
sprintf(tmp, "Could not open directory \"%s\": %s", path, strerror(errno));
|
sprintf(tmp, "Could not open directory \"%s\": %s", path, strerror(errno));
|
||||||
@ -455,6 +469,7 @@ static void load_directory(const char * path, int modifies_history) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free the previously loaded directory */
|
||||||
if (file_pointers) {
|
if (file_pointers) {
|
||||||
for (int i = 0; i < file_pointers_len; ++i) {
|
for (int i = 0; i < file_pointers_len; ++i) {
|
||||||
free(file_pointers[i]);
|
free(file_pointers[i]);
|
||||||
@ -478,18 +493,21 @@ static void load_directory(const char * path, int modifies_history) {
|
|||||||
free(current_directory);
|
free(current_directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
_button_disabled[0] = !(history_back->length);
|
/* Set button displays appropriately */
|
||||||
_button_disabled[1] = !(history_forward->length);
|
_button_disabled[0] = !(history_back->length); /* Back */
|
||||||
_button_disabled[2] = 0;
|
_button_disabled[1] = !(history_forward->length); /* Forward */
|
||||||
_button_disabled[3] = 0;
|
_button_disabled[2] = 0; /* Up */
|
||||||
|
_button_disabled[3] = 0; /* Home */
|
||||||
|
|
||||||
char * home = getenv("HOME");
|
char * home = getenv("HOME");
|
||||||
if (home && !strcmp(path, home)) {
|
if (home && !strcmp(path, home)) {
|
||||||
/* If the current directory is the user's homedir, present it that way in the title */
|
/* If the current directory is the user's homedir, present it that way in the title */
|
||||||
set_title("Home");
|
set_title("Home");
|
||||||
|
/* Disable the 'go home' button */
|
||||||
_button_disabled[3] = 1;
|
_button_disabled[3] = 1;
|
||||||
} else if (!strcmp(path, "/")) {
|
} else if (!strcmp(path, "/")) {
|
||||||
set_title("File System");
|
set_title("File System");
|
||||||
|
/* If this is the root of the file system, disable the up button */
|
||||||
_button_disabled[2] = 1;
|
_button_disabled[2] = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise use just the directory base name */
|
/* Otherwise use just the directory base name */
|
||||||
@ -761,14 +779,18 @@ static void reinitialize_contents(void) {
|
|||||||
|
|
||||||
#define BUTTON_SPACE 34
|
#define BUTTON_SPACE 34
|
||||||
#define BUTTON_COUNT 4
|
#define BUTTON_COUNT 4
|
||||||
|
/**
|
||||||
|
* Render toolbar buttons
|
||||||
|
*/
|
||||||
static void _draw_buttons(struct decor_bounds bounds) {
|
static void _draw_buttons(struct decor_bounds bounds) {
|
||||||
|
|
||||||
|
/* Draws the toolbar background as a gradient; XXX hardcoded theme details */
|
||||||
uint32_t gradient_top = rgb(59,59,59);
|
uint32_t gradient_top = rgb(59,59,59);
|
||||||
uint32_t gradient_bot = rgb(40,40,40);
|
uint32_t gradient_bot = rgb(40,40,40);
|
||||||
for (int i = 0; i < 36; ++i) {
|
for (int i = 0; i < 36; ++i) {
|
||||||
uint32_t c = interp_colors(gradient_top, gradient_bot, i * 255 / 36);
|
uint32_t c = interp_colors(gradient_top, gradient_bot, i * 255 / 36);
|
||||||
draw_rectangle(ctx, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT + i,
|
draw_rectangle(ctx, bounds.left_width, bounds.top_height + MENU_BAR_HEIGHT + i,
|
||||||
BUTTON_SPACE * BUTTON_COUNT, 1, c);
|
BUTTON_SPACE * BUTTON_COUNT, 1, c);
|
||||||
//ctx->width - bounds.width, 1, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
@ -778,12 +800,17 @@ static void _draw_buttons(struct decor_bounds bounds) {
|
|||||||
ttk_button_draw(ctx, &_up); \
|
ttk_button_draw(ctx, &_up); \
|
||||||
x += BUTTON_SPACE; i++; } while (0)
|
x += BUTTON_SPACE; i++; } while (0)
|
||||||
|
|
||||||
|
/* Draw actual buttons */
|
||||||
draw_button("back");
|
draw_button("back");
|
||||||
draw_button("forward");
|
draw_button("forward");
|
||||||
draw_button("up");
|
draw_button("up");
|
||||||
draw_button("home");
|
draw_button("home");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine what character offset the cursor should be at for
|
||||||
|
* a given X coordinate.
|
||||||
|
*/
|
||||||
static void _figure_out_navbar_cursor(int x, struct decor_bounds bounds) {
|
static void _figure_out_navbar_cursor(int x, struct decor_bounds bounds) {
|
||||||
x = x - bounds.left_width - 2 - BUTTON_SPACE * BUTTON_COUNT - 5;
|
x = x - bounds.left_width - 2 - BUTTON_SPACE * BUTTON_COUNT - 5;
|
||||||
if (x <= 0) {
|
if (x <= 0) {
|
||||||
@ -801,6 +828,12 @@ static void _figure_out_navbar_cursor(int x, struct decor_bounds bounds) {
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculate the location of the cursor indicator bar
|
||||||
|
* based on the current cursor character offset;
|
||||||
|
* also handles cursor bounds within the text
|
||||||
|
* (eg. to avoid cursor moving beyond the beginning)
|
||||||
|
*/
|
||||||
static void _recalculate_nav_bar_cursor(void) {
|
static void _recalculate_nav_bar_cursor(void) {
|
||||||
if (nav_bar_cursor < 0) {
|
if (nav_bar_cursor < 0) {
|
||||||
nav_bar_cursor = 0;
|
nav_bar_cursor = 0;
|
||||||
@ -814,7 +847,12 @@ static void _recalculate_nav_bar_cursor(void) {
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the navigation input box.
|
||||||
|
*/
|
||||||
static void _draw_nav_bar(struct decor_bounds bounds) {
|
static void _draw_nav_bar(struct decor_bounds bounds) {
|
||||||
|
|
||||||
|
/* Draw toolbar background */
|
||||||
uint32_t gradient_top = rgb(59,59,59);
|
uint32_t gradient_top = rgb(59,59,59);
|
||||||
uint32_t gradient_bot = rgb(40,40,40);
|
uint32_t gradient_bot = rgb(40,40,40);
|
||||||
int x = BUTTON_SPACE * BUTTON_COUNT;
|
int x = BUTTON_SPACE * BUTTON_COUNT;
|
||||||
@ -825,6 +863,7 @@ static void _draw_nav_bar(struct decor_bounds bounds) {
|
|||||||
ctx->width - bounds.width - BUTTON_SPACE * BUTTON_COUNT, 1, c);
|
ctx->width - bounds.width - BUTTON_SPACE * BUTTON_COUNT, 1, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draw input box */
|
||||||
if (nav_bar_focused) {
|
if (nav_bar_focused) {
|
||||||
struct gradient_definition edge = {28, bounds.top_height + MENU_BAR_HEIGHT + 3, rgb(0,120,220), rgb(0,120,220)};
|
struct gradient_definition edge = {28, bounds.top_height + MENU_BAR_HEIGHT + 3, rgb(0,120,220), rgb(0,120,220)};
|
||||||
draw_rounded_rectangle_pattern(ctx, bounds.left_width + 2 + x + 1, bounds.top_height + MENU_BAR_HEIGHT + 4, main_window->width - bounds.width - x - 6, 26, 4, gfx_vertical_gradient_pattern, &edge);
|
draw_rounded_rectangle_pattern(ctx, bounds.left_width + 2 + x + 1, bounds.top_height + MENU_BAR_HEIGHT + 4, main_window->width - bounds.width - x - 6, 26, 4, gfx_vertical_gradient_pattern, &edge);
|
||||||
@ -835,21 +874,11 @@ static void _draw_nav_bar(struct decor_bounds bounds) {
|
|||||||
draw_rounded_rectangle(ctx, bounds.left_width + 2 + x + 2, bounds.top_height + MENU_BAR_HEIGHT + 5, main_window->width - bounds.width - x - 8, 24, 3, rgb(250,250,250));
|
draw_rounded_rectangle(ctx, bounds.left_width + 2 + x + 2, bounds.top_height + MENU_BAR_HEIGHT + 5, main_window->width - bounds.width - x - 8, 24, 3, rgb(250,250,250));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the nav bar text */
|
/* Draw the nav bar text, ellipsified if needed */
|
||||||
int max_width = main_window->width - bounds.width - x - 12;
|
int max_width = main_window->width - bounds.width - x - 12;
|
||||||
int len = strlen(nav_bar);
|
char * name = ellipsify(nav_bar, 16, SDF_FONT_THIN, max_width, NULL);
|
||||||
char * name = malloc(len + 5);
|
|
||||||
memcpy(name, nav_bar, len + 1);
|
|
||||||
int name_width;
|
|
||||||
while ((name_width = draw_sdf_string_width(name, 16, SDF_FONT_THIN)) > max_width) {
|
|
||||||
len--;
|
|
||||||
name[len+0] = '.';
|
|
||||||
name[len+1] = '.';
|
|
||||||
name[len+2] = '.';
|
|
||||||
name[len+3] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_sdf_string(ctx, bounds.left_width + 2 + x + 5, bounds.top_height + MENU_BAR_HEIGHT + 8, name, 16, rgb(0,0,0), SDF_FONT_THIN);
|
draw_sdf_string(ctx, bounds.left_width + 2 + x + 5, bounds.top_height + MENU_BAR_HEIGHT + 8, name, 16, rgb(0,0,0), SDF_FONT_THIN);
|
||||||
|
free(name);
|
||||||
|
|
||||||
if (nav_bar_focused) {
|
if (nav_bar_focused) {
|
||||||
/* Draw cursor indicator at cursor_x */
|
/* Draw cursor indicator at cursor_x */
|
||||||
@ -863,7 +892,12 @@ static void _draw_nav_bar(struct decor_bounds bounds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define STATUS_HEIGHT 24
|
#define STATUS_HEIGHT 24
|
||||||
|
/**
|
||||||
|
* Draw the status bar at the bottom of the window
|
||||||
|
*/
|
||||||
static void _draw_status(struct decor_bounds bounds) {
|
static void _draw_status(struct decor_bounds bounds) {
|
||||||
|
|
||||||
|
/* Background gradient */
|
||||||
uint32_t gradient_top = rgb(80,80,80);
|
uint32_t gradient_top = rgb(80,80,80);
|
||||||
uint32_t gradient_bot = rgb(59,59,59);
|
uint32_t gradient_bot = rgb(59,59,59);
|
||||||
draw_rectangle(ctx, bounds.left_width, ctx->height - bounds.bottom_height - STATUS_HEIGHT,
|
draw_rectangle(ctx, bounds.left_width, ctx->height - bounds.bottom_height - STATUS_HEIGHT,
|
||||||
@ -874,6 +908,8 @@ static void _draw_status(struct decor_bounds bounds) {
|
|||||||
ctx->width - bounds.width, 1, c );
|
ctx->width - bounds.width, 1, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Text with draw shadow */
|
||||||
{
|
{
|
||||||
sprite_t * _tmp_s = create_sprite(ctx->width - bounds.width - 4, STATUS_HEIGHT-3, ALPHA_EMBEDDED);
|
sprite_t * _tmp_s = create_sprite(ctx->width - bounds.width - 4, STATUS_HEIGHT-3, ALPHA_EMBEDDED);
|
||||||
gfx_context_t * _tmp = init_graphics_sprite(_tmp_s);
|
gfx_context_t * _tmp = init_graphics_sprite(_tmp_s);
|
||||||
@ -890,6 +926,9 @@ static void _draw_status(struct decor_bounds bounds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redraw the navigation input box (while typing)
|
||||||
|
*/
|
||||||
static void _redraw_nav_bar(void) {
|
static void _redraw_nav_bar(void) {
|
||||||
struct decor_bounds bounds;
|
struct decor_bounds bounds;
|
||||||
_decor_get_bounds(main_window, &bounds);
|
_decor_get_bounds(main_window, &bounds);
|
||||||
@ -898,6 +937,9 @@ static void _redraw_nav_bar(void) {
|
|||||||
yutani_flip(yctx, main_window);
|
yutani_flip(yctx, main_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navbar: Text editing helpers for ^W, deletes one directory element
|
||||||
|
*/
|
||||||
static void nav_bar_backspace_word(void) {
|
static void nav_bar_backspace_word(void) {
|
||||||
if (!*nav_bar) return;
|
if (!*nav_bar) return;
|
||||||
if (nav_bar_cursor == 0) return;
|
if (nav_bar_cursor == 0) return;
|
||||||
@ -920,6 +962,9 @@ static void nav_bar_backspace_word(void) {
|
|||||||
_redraw_nav_bar();
|
_redraw_nav_bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navbar: Text editing helper for backspace, deletes one character
|
||||||
|
*/
|
||||||
static void nav_bar_backspace(void) {
|
static void nav_bar_backspace(void) {
|
||||||
if (nav_bar_cursor == 0) return;
|
if (nav_bar_cursor == 0) return;
|
||||||
|
|
||||||
@ -935,6 +980,9 @@ static void nav_bar_backspace(void) {
|
|||||||
_redraw_nav_bar();
|
_redraw_nav_bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navbar: Text editing helper for inserting characters
|
||||||
|
*/
|
||||||
static void nav_bar_insert_char(char c) {
|
static void nav_bar_insert_char(char c) {
|
||||||
char * tmp = strdup(nav_bar);
|
char * tmp = strdup(nav_bar);
|
||||||
tmp[nav_bar_cursor] = '\0';
|
tmp[nav_bar_cursor] = '\0';
|
||||||
@ -948,12 +996,18 @@ static void nav_bar_insert_char(char c) {
|
|||||||
_redraw_nav_bar();
|
_redraw_nav_bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navbar: Move editing cursor one character left
|
||||||
|
*/
|
||||||
static void nav_bar_cursor_left(void) {
|
static void nav_bar_cursor_left(void) {
|
||||||
nav_bar_cursor--;
|
nav_bar_cursor--;
|
||||||
_recalculate_nav_bar_cursor();
|
_recalculate_nav_bar_cursor();
|
||||||
_redraw_nav_bar();
|
_redraw_nav_bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navbar: Move editing cursor one character right
|
||||||
|
*/
|
||||||
static void nav_bar_cursor_right(void) {
|
static void nav_bar_cursor_right(void) {
|
||||||
nav_bar_cursor++;
|
nav_bar_cursor++;
|
||||||
_recalculate_nav_bar_cursor();
|
_recalculate_nav_bar_cursor();
|
||||||
@ -1287,7 +1341,7 @@ static void open_file(struct File * f) {
|
|||||||
/* "SELF" launchers are for binaries. */
|
/* "SELF" launchers are for binaries. */
|
||||||
sprintf(tmp, "exec ./%s", f->name);
|
sprintf(tmp, "exec ./%s", f->name);
|
||||||
} else {
|
} else {
|
||||||
/* Other launchers shouuld take file names as arguments.
|
/* Other launchers should take file names as arguments.
|
||||||
* NOTE: If you don't want the file name, you can append # to your launcher.
|
* NOTE: If you don't want the file name, you can append # to your launcher.
|
||||||
* Since it's parsed by the shell, this will yield a comment.
|
* Since it's parsed by the shell, this will yield a comment.
|
||||||
*/
|
*/
|
||||||
@ -1333,6 +1387,14 @@ static void _menu_action_select_all(struct MenuEntry * self) {
|
|||||||
redraw_window();
|
redraw_window();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the view mode for the file view
|
||||||
|
* We support three modes:
|
||||||
|
* - Icons: Standard view, label centered below icon.
|
||||||
|
* - Tiles: Like Windows Explorer, labels left-aligned to the right of
|
||||||
|
* the icon, with extra details also displayed. Bold file name.
|
||||||
|
* - List: One-line-per-file, icon on the left, left aligne file name.
|
||||||
|
*/
|
||||||
static void set_view_mode(int mode) {
|
static void set_view_mode(int mode) {
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@ -1358,6 +1420,10 @@ static void set_view_mode(int mode) {
|
|||||||
redraw_window();
|
redraw_window();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dropdown action handler for view mode entries;
|
||||||
|
* use menuitem action to determine which view mode to set.
|
||||||
|
*/
|
||||||
static void _menu_action_view_mode(struct MenuEntry * entry) {
|
static void _menu_action_view_mode(struct MenuEntry * entry) {
|
||||||
struct MenuEntry_Normal * _entry = (void*)entry;
|
struct MenuEntry_Normal * _entry = (void*)entry;
|
||||||
int mode = VIEW_MODE_ICONS;
|
int mode = VIEW_MODE_ICONS;
|
||||||
@ -1371,6 +1437,17 @@ static void _menu_action_view_mode(struct MenuEntry * entry) {
|
|||||||
set_view_mode(mode);
|
set_view_mode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive pastes, which are presumed to be file names of files
|
||||||
|
* which have been copied and should now be pasted into a new
|
||||||
|
* directory; will not overwrite if pasted into the same directory
|
||||||
|
* or a directory with a file with the same name.
|
||||||
|
*
|
||||||
|
* XXX: Calls `cp` to perform actual copy.
|
||||||
|
*
|
||||||
|
* TODO: Actually check if clipboard contains a file name.
|
||||||
|
* TODO: Handle pastes into the navbar of arbitrary text.
|
||||||
|
*/
|
||||||
static void handle_clipboard(char * contents) {
|
static void handle_clipboard(char * contents) {
|
||||||
fprintf(stderr, "Received clipboard:\n%s\n",contents);
|
fprintf(stderr, "Received clipboard:\n%s\n",contents);
|
||||||
|
|
||||||
@ -1445,6 +1522,9 @@ static void toggle_selected(int hilighted_offset, int modifiers) {
|
|||||||
redraw_window();
|
redraw_window();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle button hover highlights
|
||||||
|
*/
|
||||||
static int _down_button = -1;
|
static int _down_button = -1;
|
||||||
static void _set_hilight(int index, int hilight) {
|
static void _set_hilight(int index, int hilight) {
|
||||||
int _update = 0;
|
int _update = 0;
|
||||||
@ -1464,6 +1544,9 @@ static void _set_hilight(int index, int hilight) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle toolbar button clicking
|
||||||
|
*/
|
||||||
static void _handle_button_press(int index) {
|
static void _handle_button_press(int index) {
|
||||||
if (index != -1 && _button_disabled[index]) return; /* can't click disabled buttons */
|
if (index != -1 && _button_disabled[index]) return; /* can't click disabled buttons */
|
||||||
switch (index) {
|
switch (index) {
|
||||||
@ -1508,6 +1591,9 @@ static void _handle_button_press(int index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll file view up
|
||||||
|
*/
|
||||||
static void _scroll_up(void) {
|
static void _scroll_up(void) {
|
||||||
scroll_offset -= SCROLL_AMOUNT;
|
scroll_offset -= SCROLL_AMOUNT;
|
||||||
if (scroll_offset < 0) {
|
if (scroll_offset < 0) {
|
||||||
@ -1515,6 +1601,9 @@ static void _scroll_up(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll file view down
|
||||||
|
*/
|
||||||
static void _scroll_down(void) {
|
static void _scroll_down(void) {
|
||||||
if (available_height > contents->height) {
|
if (available_height > contents->height) {
|
||||||
scroll_offset = 0;
|
scroll_offset = 0;
|
||||||
@ -1536,11 +1625,21 @@ static void sig_usr2(int sig) {
|
|||||||
signal(SIGUSR2, sig_usr2);
|
signal(SIGUSR2, sig_usr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Desktop mode responds to sig_usr1 by resizing the window
|
||||||
|
* to the current display size.
|
||||||
|
*/
|
||||||
static void sig_usr1(int sig) {
|
static void sig_usr1(int sig) {
|
||||||
yutani_window_resize_offer(yctx, main_window, yctx->display_width, yctx->display_height);
|
yutani_window_resize_offer(yctx, main_window, yctx->display_width, yctx->display_height);
|
||||||
signal(SIGUSR1, sig_usr1);
|
signal(SIGUSR1, sig_usr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept keyboard arrows left/right/up/down and select the appropriate
|
||||||
|
* file in the file view based on the currently selected file; if multiple
|
||||||
|
* files are currently selected, the first one (up/left) is used as the basis
|
||||||
|
* for the new selection.
|
||||||
|
*/
|
||||||
static void arrow_select(int x, int y) {
|
static void arrow_select(int x, int y) {
|
||||||
if (!file_pointers_len) return;
|
if (!file_pointers_len) return;
|
||||||
|
|
||||||
@ -1654,11 +1753,6 @@ int main(int argc, char * argv[]) {
|
|||||||
menu_set_insert(menu_bar.set, "view", m);
|
menu_set_insert(menu_bar.set, "view", m);
|
||||||
|
|
||||||
m = menu_create(); /* Go */
|
m = menu_create(); /* Go */
|
||||||
/* TODO implement input dialog for Path... */
|
|
||||||
#if 0
|
|
||||||
menu_insert(m, menu_create_normal("open",NULL,"Path...", _menu_action_input_path));
|
|
||||||
menu_insert(m, menu_create_separator());
|
|
||||||
#endif
|
|
||||||
menu_insert(m, menu_create_normal("home",getenv("HOME"),"Home",_menu_action_navigate));
|
menu_insert(m, menu_create_normal("home",getenv("HOME"),"Home",_menu_action_navigate));
|
||||||
menu_insert(m, menu_create_normal(NULL,"/","File System",_menu_action_navigate));
|
menu_insert(m, menu_create_normal(NULL,"/","File System",_menu_action_navigate));
|
||||||
menu_insert(m, menu_create_normal("up",NULL,"Up",_menu_action_up));
|
menu_insert(m, menu_create_normal("up",NULL,"Up",_menu_action_up));
|
||||||
|
Loading…
Reference in New Issue
Block a user