summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-01-28 15:43:38 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-01-28 15:43:38 +0000
commite75ce196e8376de78d8a8b4ad3cbaa4ad18b937f (patch)
tree55eabf8eca167de7bd07b6204c36211fdaa596f9 /src
parentb4a56832cb2c075baf371d4ddcf755dbe0464ccc (diff)
downloadirssi-e75ce196e8376de78d8a8b4ad3cbaa4ad18b937f.zip
get_max_column_count(), columns_sort_list(): helper functions for
printing column lists git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1160 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src')
-rw-r--r--src/core/misc.c86
-rw-r--r--src/core/misc.h10
2 files changed, 96 insertions, 0 deletions
diff --git a/src/core/misc.c b/src/core/misc.c
index 0ae36b96..7326cf81 100644
--- a/src/core/misc.c
+++ b/src/core/misc.c
@@ -605,3 +605,89 @@ char *my_asctime(time_t t)
if (len > 0) str[len-1] = '\0';
return str;
}
+
+/* Returns number of columns needed to print items.
+ save_column_widths is filled with length of each column. */
+int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func,
+ int max_width, int item_extra, int item_min_size,
+ int **save_column_widths, int *rows)
+{
+ int **columns, *columns_width, *columns_rows;
+ int item_pos, items_count;
+ int ret, len, n, col, max_columns;
+
+ items_count = g_slist_length(items);
+
+ max_columns = max_width/(item_extra+item_min_size);
+ columns = g_new0(int *, max_columns);
+ columns_width = g_new0(int, max_columns);
+ columns_rows = g_new0(int, max_columns);
+
+ for (n = 1; n < max_columns; n++) {
+ columns[n] = g_new0(int, n+1);
+ columns_rows[n] = items_count < n+1 ? 1 :
+ (items_count+n)/(n+1);
+ }
+
+ /* for each possible column count, save the column widths and
+ find the biggest column count that fits to screen. */
+ item_pos = 0;
+ while (items != NULL) {
+ len = item_extra+len_func(items->data);
+ for (n = 1; n < max_columns; n++) {
+ if (columns_width[n] > max_width)
+ continue; /* too wide */
+
+ col = item_pos/columns_rows[n];
+ if (columns[n][col] < len) {
+ columns_width[n] += len-columns[n][col];
+ columns[n][col] = len;
+ }
+ }
+
+ items = items->next;
+ item_pos++;
+ }
+
+ for (n = max_columns-1; n >= 0; n--) {
+ if (columns_width[n] <= max_width)
+ break;
+ }
+ ret = n+1;
+
+ *save_column_widths = g_new(int, ret);
+ memcpy(*save_column_widths, columns[ret-1], sizeof(int)*ret);
+ *rows = columns_rows[ret-1];
+
+ for (n = 1; n < max_columns; n++)
+ g_free(columns[n]);
+ g_free(columns_width);
+ g_free(columns_rows);
+ g_free(columns);
+
+ return ret;
+}
+
+/* Return a column sorted copy of a list. */
+GSList *columns_sort_list(GSList *list, int rows)
+{
+ GSList *tmp, *sorted;
+ int row, skip;
+
+ sorted = NULL;
+
+ for (row = 0; row < rows; row++) {
+ tmp = g_slist_nth(list, row);
+ skip = 1;
+ for (; tmp != NULL; tmp = tmp->next) {
+ if (--skip == 0) {
+ skip = rows;
+ sorted = g_slist_append(sorted, tmp->data);
+ }
+ }
+ }
+
+ g_return_val_if_fail(g_slist_length(sorted) ==
+ g_slist_length(list), sorted);
+ return sorted;
+}
diff --git a/src/core/misc.h b/src/core/misc.h
index 22fe9211..110aa14b 100644
--- a/src/core/misc.h
+++ b/src/core/misc.h
@@ -6,6 +6,7 @@
g_snprintf(str, sizeof(str), "%d", num)
typedef void* (*FOREACH_FIND_FUNC) (void *item, void *data);
+typedef int (*COLUMN_LEN_FUNC)(void *data);
int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2);
long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2);
@@ -74,4 +75,13 @@ char *show_lowascii(const char *channel);
/* Get time in human readable form with localtime() + asctime() */
char *my_asctime(time_t t);
+/* Returns number of columns needed to print items.
+ save_column_widths is filled with length of each column. */
+int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func,
+ int max_width, int item_extra, int item_min_size,
+ int **save_column_widths, int *rows);
+
+/* Return a column sorted copy of a list. */
+GSList *columns_sort_list(GSList *list, int rows);
+
#endif