when_filled_callback *whenfilled; /**< @brief called when filled or 0 */
void *wfu; /**< @brief passed to @c whenfilled */
+ int ymin; /**< @brief least Y value */
+ int ymax; /**< @brief greatest Y value */
};
/** @brief One item in the popup menu */
/* Variables */
static GtkWidget *chooselayout;
+static GtkAdjustment *vadjust;
static GtkWidget *searchentry; /**< @brief search terms */
static struct choosenode *root;
static GtkWidget *track_menu; /**< @brief track popup menu */
/* Maintaining the data structure ------------------------------------------ */
-static char *flags(const struct choosenode *cn) {
+static char *cnflags(const struct choosenode *cn) {
unsigned f = cn->flags, n;
struct dynstr d[1];
struct choosenode *cn = cbd->u.choosenode;
int n;
- D(("got_files %d files for %s %s", nvec, cn->path, flags(cn)));
+ D(("got_files %d files for %s %s", nvec, cn->path, cnflags(cn)));
/* Complicated by the need to resolve aliases. We can save a bit of effort
* by re-using cbd though. */
cn->flags &= ~CN_GETTING_FILES;
struct callbackdata *cbd = v;
struct choosenode *cn = cbd->u.choosenode, *file_cn;
- D(("resolved %s %s %d left", cn->path, flags(cn), cn->pending - 1));
+ D(("resolved %s %s %d left", cn->path, cnflags(cn), cn->pending - 1));
/* TODO as below */
file_cn = newnode(cn, track,
trackname_transform("track", track, "display"),
struct choosenode *cn = cbd->u.choosenode;
int n;
- D(("got_dirs %d dirs for %s %s", nvec, cn->path, flags(cn)));
+ D(("got_dirs %d dirs for %s %s", nvec, cn->path, cnflags(cn)));
/* TODO this depends on local configuration for trackname_transform().
* This will work, since the defaults are now built-in, but it'll be
* (potentially) different to the server's configured settings.
/** @brief Expand a node */
static void expand_node(struct choosenode *cn, int contingent) {
- D(("expand_node %s %d %s", cn->path, contingent, flags(cn)));
+ D(("expand_node %s %d %s", cn->path, contingent, cnflags(cn)));
assert(cn->flags & CN_EXPANDABLE);
/* If node is already expanded do nothing. */
if(cn->flags & CN_EXPANDED) return;
/* This is an actual search result */
++nsearchvisible;
progress_window_progress(spw, nsearchvisible, nsearchresults);
+ if(nsearchvisible == nsearchresults)
+ /* This is the last track to become visible, we'll make sure it's in
+ * range so that at least one is. */
+ gtk_adjustment_clamp_page(vadjust, cn->ymax, cn->ymin);
}
}
expand_from(root);
} else {
searchhash = 0; /* for the gc */
+ redisplay_tree(); /* remove search markers */
}
}
}
gtk_widget_size_request(cn->container, &req);
d.width = x + req.width;
d.height = y + req.height;
+ cn->ymin = y;
+ cn->ymax = d.height;
if(cn->flags & CN_EXPANDED) {
/* We'll offset children by the size of the arrow whatever it might be. */
assert(cn->arrow);
0, 1, n, n + 1);
}
/* The layout is scrollable */
- scrolled = scroll_widget(GTK_WIDGET(chooselayout), "choose");
+ scrolled = scroll_widget(chooselayout, "choose");
+ vadjust = gtk_layout_get_vadjustment(GTK_LAYOUT(chooselayout));
/* The scrollable layout and the search hbox go together in a vbox */
NW(vbox);