Improve and add colour to possible hint matches

Changed URL hinting to be a lot smarter and to colour hints when
possible matches are found.

- Add active_foreground and active_background config options
- Add a new char* to hold entry text for checking against when redrawing

Signed-off-by: numeral <numerical@gmail.com>
Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com>
This commit is contained in:
numerical 2013-02-28 02:36:38 -05:00 committed by Simon Gomizelj
parent 224c76ea37
commit 63f52cea8b
1 changed files with 35 additions and 21 deletions

View File

@ -76,11 +76,12 @@ struct search_panel_info {
GtkWidget *da; GtkWidget *da;
overlay_mode mode; overlay_mode mode;
std::vector<url_data> url_list; std::vector<url_data> url_list;
char *fulltext;
}; };
struct hint_info { struct hint_info {
PangoFontDescription *font; PangoFontDescription *font;
cairo_pattern_t *fg, *bg, *border; cairo_pattern_t *fg, *bg, *af, *ab, *border;
double padding, border_width, roundness; double padding, border_width, roundness;
}; };
@ -203,17 +204,15 @@ static void draw_rectangle(cairo_t *cr, double x, double y, double height,
} }
static void draw_marker(cairo_t *cr, const PangoFontDescription *desc, static void draw_marker(cairo_t *cr, const PangoFontDescription *desc,
const hint_info *hints, long x, long y, unsigned id) { const hint_info *hints, long x, long y, const char *msg,
char buffer[std::numeric_limits<unsigned>::digits10 + 1]; bool active) {
cairo_text_extents_t ext; cairo_text_extents_t ext;
int width, height; int width, height;
snprintf(buffer, sizeof(buffer), "%u", id); cairo_text_extents(cr, msg, &ext);
cairo_text_extents(cr, buffer, &ext);
PangoLayout *layout = pango_cairo_create_layout(cr); PangoLayout *layout = pango_cairo_create_layout(cr);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, buffer, -1); pango_layout_set_text(layout, msg, -1);
pango_layout_get_size(layout, &width, &height); pango_layout_get_size(layout, &width, &height);
draw_rectangle(cr, static_cast<double>(x), static_cast<double>(y), draw_rectangle(cr, static_cast<double>(x), static_cast<double>(y),
@ -223,14 +222,14 @@ static void draw_marker(cairo_t *cr, const PangoFontDescription *desc,
cairo_set_source(cr, hints->border); cairo_set_source(cr, hints->border);
cairo_set_line_width(cr, hints->border_width); cairo_set_line_width(cr, hints->border_width);
cairo_stroke_preserve(cr); cairo_stroke_preserve(cr);
cairo_set_source(cr, hints->bg); cairo_set_source(cr, active ? hints->ab : hints->bg);
cairo_fill(cr); cairo_fill(cr);
cairo_new_path(cr); cairo_new_path(cr);
cairo_move_to(cr, static_cast<double>(x) + hints->padding, cairo_move_to(cr, static_cast<double>(x) + hints->padding,
static_cast<double>(y) + hints->padding); static_cast<double>(y) + hints->padding);
cairo_set_source(cr, hints->fg); cairo_set_source(cr, active ? hints->af : hints->fg);
pango_cairo_update_layout(cr, layout); pango_cairo_update_layout(cr, layout);
pango_cairo_layout_path(cr, layout); pango_cairo_layout_path(cr, layout);
cairo_fill(cr); cairo_fill(cr);
@ -240,10 +239,14 @@ static void draw_marker(cairo_t *cr, const PangoFontDescription *desc,
static gboolean draw_cb(const draw_cb_info *info, cairo_t *cr) { static gboolean draw_cb(const draw_cb_info *info, cairo_t *cr) {
if (!info->panel->url_list.empty()) { if (!info->panel->url_list.empty()) {
char buffer[std::numeric_limits<unsigned>::digits10 + 1];
const long cw = vte_terminal_get_char_width(info->panel->vte); const long cw = vte_terminal_get_char_width(info->panel->vte);
const long ch = vte_terminal_get_char_height(info->panel->vte); const long ch = vte_terminal_get_char_height(info->panel->vte);
const PangoFontDescription *desc = info->hints->font ? const PangoFontDescription *desc = info->hints->font ?
info->hints->font : vte_terminal_get_font(info->panel->vte); info->hints->font : vte_terminal_get_font(info->panel->vte);
size_t len = info->panel->fulltext == NULL ?
0 : strlen(info->panel->fulltext);
cairo_set_line_width(cr, 1); cairo_set_line_width(cr, 1);
cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_source_rgb(cr, 0, 0, 0);
@ -253,7 +256,13 @@ static gboolean draw_cb(const draw_cb_info *info, cairo_t *cr) {
const url_data &data = info->panel->url_list[i]; const url_data &data = info->panel->url_list[i];
const long x = data.col * cw; const long x = data.col * cw;
const long y = data.row * ch; const long y = data.row * ch;
draw_marker(cr, desc, info->hints, x, y, i + 1); bool active = false;
snprintf(buffer, sizeof(buffer), "%u", i + 1);
if(len)
active = strncmp(buffer, info->panel->fulltext, len) == 0;
draw_marker(cr, desc, info->hints, x, y, buffer, active);
} }
} }
@ -756,6 +765,7 @@ gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, keybind_info *i
gboolean ret = FALSE; gboolean ret = FALSE;
switch (event->keyval) { switch (event->keyval) {
case GDK_KEY_BackSpace:
case GDK_KEY_0: case GDK_KEY_0:
case GDK_KEY_1: case GDK_KEY_1:
case GDK_KEY_2: case GDK_KEY_2:
@ -768,10 +778,10 @@ gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, keybind_info *i
case GDK_KEY_9: case GDK_KEY_9:
if (info->panel.mode == overlay_mode::urlselect) { if (info->panel.mode == overlay_mode::urlselect) {
const char *const text = gtk_entry_get_text(entry); const char *const text = gtk_entry_get_text(entry);
char *fulltext = g_strndup(text, strlen(text) + 1); info->panel.fulltext = g_strndup(text, strlen(text) + 1);
fulltext[strlen(text)] = (char)event->keyval; info->panel.fulltext[strlen(text)] = (char)event->keyval;
size_t urld = static_cast<size_t>(info->panel.url_list.size()); size_t urld = static_cast<size_t>(info->panel.url_list.size());
size_t textd = strtoul(fulltext, NULL, 10); size_t textd = strtoul(info->panel.fulltext, NULL, 10);
size_t url_dig = static_cast<size_t>( size_t url_dig = static_cast<size_t>(
log10(static_cast<double>(info->panel.url_list.size())) + 1); log10(static_cast<double>(info->panel.url_list.size())) + 1);
size_t text_dig = static_cast<size_t>( size_t text_dig = static_cast<size_t>(
@ -779,12 +789,11 @@ gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, keybind_info *i
if (url_dig == text_dig || if (url_dig == text_dig ||
textd > static_cast<size_t>(static_cast<double>(urld)/10)) { textd > static_cast<size_t>(static_cast<double>(urld)/10)) {
launch_url(info->config.browser, info->panel.fulltext, &info->panel);
launch_url(info->config.browser, fulltext, &info->panel);
ret = TRUE; ret = TRUE;
} else {
gtk_widget_queue_draw(info->panel.da);
} }
free(fulltext);
} }
break; break;
case GDK_KEY_Tab: case GDK_KEY_Tab:
@ -827,6 +836,8 @@ gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event, keybind_info *i
if (info->panel.mode == overlay_mode::urlselect) { if (info->panel.mode == overlay_mode::urlselect) {
gtk_widget_hide(info->panel.da); gtk_widget_hide(info->panel.da);
info->panel.url_list.clear(); info->panel.url_list.clear();
free(info->panel.fulltext);
info->panel.fulltext = nullptr;
} }
info->panel.mode = overlay_mode::hidden; info->panel.mode = overlay_mode::hidden;
gtk_widget_hide(info->panel.panel); gtk_widget_hide(info->panel.panel);
@ -1068,6 +1079,8 @@ static void load_theme(VteTerminal *vte, GKeyFile *config, hint_info &hints) {
hints.fg = get_config_cairo_color(config, "hints", "foreground").get_value_or(cairo_pattern_create_rgb(1, 1, 1)); hints.fg = get_config_cairo_color(config, "hints", "foreground").get_value_or(cairo_pattern_create_rgb(1, 1, 1));
hints.bg = get_config_cairo_color(config, "hints", "background").get_value_or(cairo_pattern_create_rgb(0, 0, 0)); hints.bg = get_config_cairo_color(config, "hints", "background").get_value_or(cairo_pattern_create_rgb(0, 0, 0));
hints.af = get_config_cairo_color(config, "hints", "active_foreground").get_value_or(cairo_pattern_create_rgb(0.9, 0.5, 0.5));
hints.ab = get_config_cairo_color(config, "hints", "active_background").get_value_or(cairo_pattern_create_rgb(0, 0, 0));
hints.border = get_config_cairo_color(config, "hints", "border").get_value_or(hints.fg); hints.border = get_config_cairo_color(config, "hints", "border").get_value_or(hints.fg);
hints.padding = get_config_double(config, "hints", "padding", 5).get_value_or(2.0); hints.padding = get_config_double(config, "hints", "padding", 5).get_value_or(2.0);
hints.border_width = get_config_double(config, "hints", "border_width").get_value_or(1.0); hints.border_width = get_config_double(config, "hints", "border_width").get_value_or(1.0);
@ -1306,9 +1319,10 @@ int main(int argc, char **argv) {
gtk_alignment_new(0, 0, 1, 1), gtk_alignment_new(0, 0, 1, 1),
gtk_drawing_area_new(), gtk_drawing_area_new(),
overlay_mode::hidden, overlay_mode::hidden,
std::vector<url_data>()}, std::vector<url_data>(),
nullptr},
{vi_mode::insert, 0, 0, 0, 0}, {vi_mode::insert, 0, 0, 0, 0},
{{nullptr, nullptr, nullptr, nullptr, 0, 0, 0}, {{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0, 0, 0},
nullptr, FALSE, FALSE, FALSE, -1, config_file} nullptr, FALSE, FALSE, FALSE, -1, config_file}
}; };