gtk2 sam7fc telemetrie application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
8.8KB

  1. /***************************************************************************
  2. * Copyright (C) 04/2008 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <gtk/gtk.h>
  20. #include "tdc_store.h"
  21. #include "tdc_parser.h"
  22. #include "tdc_proto.h"
  23. #include "gui_graph_tab.h"
  24. enum {
  25. COL_ID = 0, /* UINT */
  26. COL_GRAPH, /* BOOLEAN */
  27. COL_VALUE, /* POINTER to var */
  28. COL_VALUE_EDIT, /* BOOLEAN */
  29. COL_TYPE, /* STRING */
  30. COL_NAME, /* STRING */
  31. };
  32. static GtkListStore *list_store;
  33. static int viewmode = 0;
  34. static int sortmode = GTK_SORT_ASCENDING;
  35. static struct tdc_var *current_edited_var;
  36. static void cell_graph_toggle(GtkCellRendererToggle *cell,
  37. gchar *path_string,
  38. gpointer user_data)
  39. {
  40. GtkTreeIter it;
  41. gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(user_data), &it, path_string);
  42. gboolean toggle;
  43. struct tdc_var *var;
  44. gtk_tree_model_get(GTK_TREE_MODEL(user_data), &it,
  45. COL_GRAPH, &toggle,
  46. COL_VALUE, &var,
  47. -1);
  48. if (var->flags & TDC_GUI_GRAPH) {
  49. var->flags &= ~TDC_GUI_GRAPH;
  50. if (var->privdata_graphtab != NULL)
  51. gui_graphtab_remove_var(var);
  52. } else {
  53. if (var->privdata_graphtab == NULL)
  54. /* bailout if no new graph allowed */
  55. if (gui_graphtab_add_var(var) < 0)
  56. return;
  57. var->flags |= TDC_GUI_GRAPH;
  58. }
  59. // FIXME: assuming board 1
  60. tdcstore_graph_refresh(1, -1);
  61. gtk_list_store_set(GTK_LIST_STORE(user_data), &it,
  62. COL_GRAPH, !toggle,
  63. -1);
  64. }
  65. static gboolean header_toggle_update(GtkTreeModel *model,
  66. GtkTreePath *path,
  67. GtkTreeIter *iter,
  68. gpointer data)
  69. {
  70. gtk_tree_model_row_changed(model, path, iter);
  71. return FALSE;
  72. }
  73. static void value_edit_started(GtkCellRenderer *renderer,
  74. GtkCellEditable *editable,
  75. gchar *path,
  76. gpointer user_data)
  77. {
  78. GtkTreeIter it;
  79. gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(list_store), &it, path);
  80. gtk_tree_model_get(GTK_TREE_MODEL(list_store), &it, COL_VALUE, &current_edited_var, -1);
  81. }
  82. static void value_edit_canceled(GtkCellRenderer *renderer, gpointer user_data)
  83. {
  84. current_edited_var = NULL;
  85. }
  86. static void value_edit_done(GtkCellRendererText *cell,
  87. gchar *path,
  88. gchar *text,
  89. gpointer user_data)
  90. {
  91. GtkTreeIter it;
  92. gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(list_store), &it, path);
  93. struct tdc_var *var;
  94. gtk_tree_model_get(GTK_TREE_MODEL(list_store), &it, COL_VALUE, &var, -1);
  95. if (tdcvar_parse_value(var, text) >= 0) {
  96. // FIXME: assuming board 1
  97. tdcparser_send_setvalue(1, var->id);
  98. }
  99. current_edited_var = NULL;
  100. }
  101. static gint sort_by_name_func(GtkTreeModel *model,
  102. GtkTreeIter *a,
  103. GtkTreeIter *b,
  104. gpointer userdata)
  105. {
  106. gint ret = 0;
  107. gchar *name1, *name2;
  108. gtk_tree_model_get(model, a, COL_NAME, &name1, -1);
  109. gtk_tree_model_get(model, b, COL_NAME, &name2, -1);
  110. if (name1 == NULL || name2 == NULL) {
  111. if (name1 != NULL || name2 != NULL)
  112. ret = (name1 == NULL) ? -1 : 1;
  113. } else {
  114. ret = g_utf8_collate(name1, name2);
  115. }
  116. g_free(name1);
  117. g_free(name2);
  118. return ret;
  119. }
  120. static void header_name_toggle(GtkTreeViewColumn *treeviewcolumn,
  121. gpointer user_data)
  122. {
  123. sortmode = (sortmode == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING;
  124. GtkTreeSortable *sortable = GTK_TREE_SORTABLE(list_store);
  125. gtk_tree_sortable_set_sort_func(sortable, COL_NAME, sort_by_name_func, NULL, NULL);
  126. gtk_tree_sortable_set_sort_column_id(sortable, COL_NAME, sortmode);
  127. }
  128. static void header_value_toggle(GtkTreeViewColumn *treeviewcolumn,
  129. gpointer user_data)
  130. {
  131. viewmode = (viewmode +1) & 0x01;
  132. gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), header_toggle_update, NULL);
  133. }
  134. static void cell_value_func(GtkTreeViewColumn *column,
  135. GtkCellRenderer *cell,
  136. GtkTreeModel *model,
  137. GtkTreeIter *iter,
  138. gpointer data)
  139. {
  140. struct tdc_var *var;
  141. gtk_tree_model_get(model, iter, COL_VALUE, &var, -1);
  142. char buf[32];
  143. tdcvar_get_value(var, buf, sizeof(buf), viewmode);
  144. g_object_set(cell, "text", buf, NULL);
  145. }
  146. gint gui_vartab_init(GtkNotebook *notebook)
  147. {
  148. list_store = gtk_list_store_new(6,
  149. G_TYPE_UINT, G_TYPE_BOOLEAN,
  150. G_TYPE_POINTER, G_TYPE_BOOLEAN,
  151. G_TYPE_STRING, G_TYPE_STRING);
  152. GtkTreeSortable *sortable = GTK_TREE_SORTABLE(list_store);
  153. gtk_tree_sortable_set_sort_func(sortable, COL_NAME, sort_by_name_func, NULL, NULL);
  154. gtk_tree_sortable_set_sort_column_id(sortable, COL_NAME, sortmode);
  155. GtkWidget *view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
  156. g_object_unref(list_store);
  157. gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(view), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
  158. GtkTreeViewColumn *col;
  159. GtkCellRenderer *renderer;
  160. col = gtk_tree_view_column_new();
  161. gtk_tree_view_column_set_title(col, "Graph");
  162. gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
  163. renderer = gtk_cell_renderer_toggle_new();
  164. g_object_set(renderer, "activatable", TRUE, NULL);
  165. g_signal_connect(renderer, "toggled", (GCallback)cell_graph_toggle, list_store);
  166. gtk_tree_view_column_pack_start(col, renderer, FALSE);
  167. gtk_tree_view_column_add_attribute(col, renderer, "active", COL_GRAPH);
  168. col = gtk_tree_view_column_new();
  169. gtk_tree_view_column_set_title(col, "Value");
  170. gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
  171. g_object_set(col, "clickable", TRUE, NULL);
  172. g_signal_connect(col, "clicked", (GCallback)header_value_toggle, NULL);
  173. renderer = gtk_cell_renderer_text_new();
  174. g_signal_connect(renderer, "edited", (GCallback)value_edit_done, NULL);
  175. g_signal_connect(renderer, "editing-started", (GCallback)value_edit_started, NULL);
  176. g_signal_connect(renderer, "editing-canceled", (GCallback)value_edit_canceled, NULL);
  177. gtk_tree_view_column_pack_start(col, renderer, FALSE);
  178. gtk_tree_view_column_add_attribute(col, renderer, "editable", COL_VALUE_EDIT);
  179. gtk_tree_view_column_set_cell_data_func(col, renderer, cell_value_func, NULL, NULL);
  180. col = gtk_tree_view_column_new();
  181. gtk_tree_view_column_set_title(col, "Type");
  182. gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
  183. renderer = gtk_cell_renderer_text_new();
  184. gtk_tree_view_column_pack_start(col, renderer, FALSE);
  185. gtk_tree_view_column_add_attribute(col, renderer, "text", COL_TYPE);
  186. col = gtk_tree_view_column_new();
  187. gtk_tree_view_column_set_title(col, "Name");
  188. gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
  189. g_object_set(col, "clickable", TRUE, NULL);
  190. g_signal_connect(col, "clicked", (GCallback)header_name_toggle, NULL);
  191. renderer = gtk_cell_renderer_text_new();
  192. gtk_tree_view_column_pack_start(col, renderer, FALSE);
  193. gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NAME);
  194. GtkWidget *scrollbar = gtk_scrolled_window_new(NULL, NULL);
  195. gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  196. gtk_container_add(GTK_CONTAINER(scrollbar), view);
  197. GtkWidget *label = gtk_label_new(" Variables ");
  198. return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrollbar, label);
  199. }
  200. void gui_vartab_add_var(struct tdc_var *var)
  201. {
  202. GtkTreeIter it;
  203. gtk_list_store_append(list_store, &it);
  204. char typestr[32];
  205. tdcvar_get_type(var, typestr, sizeof(typestr));
  206. gtk_list_store_set(list_store, &it,
  207. COL_ID, var->id,
  208. COL_GRAPH, FALSE,
  209. COL_VALUE, var,
  210. COL_VALUE_EDIT, !(var->flags & TDC_READONLY),
  211. COL_TYPE, typestr,
  212. COL_NAME, var->name,
  213. -1);
  214. var->privdata_vartab = gtk_tree_iter_copy(&it);
  215. }
  216. int gui_vartab_update_var(struct tdc_var *var)
  217. {
  218. // TODO: update even in graph mode every xxx ms
  219. if (var == current_edited_var || (var->flags & TDC_GUI_GRAPH))
  220. return 0;
  221. /* do a dummy write to update cells */
  222. GtkTreeIter *it = (GtkTreeIter *)var->privdata_vartab;
  223. gtk_list_store_set(list_store, it, -1);
  224. return 0;
  225. }
  226. void gui_vartab_remove_var(struct tdc_var *var)
  227. {
  228. GtkTreeIter *it = (GtkTreeIter *)var->privdata_vartab;
  229. gtk_list_store_remove(list_store, it);
  230. gtk_tree_iter_free(it);
  231. var->privdata_vartab = NULL;
  232. }