=== Overview ===
[xuni.git] / src / widget / dump.c
blobeab6e04d6f3879eb35ab86165e513f5598ad0765
1 /*! \file dump.c
3 Functions that make printing information about widgets easier.
4 */
6 #include <stdlib.h>
7 #include <string.h>
9 #include "../graphics.h"
10 #include "../memory.h"
11 #include "../error.h"
12 #include "dump.h"
13 #include "widgets.h"
15 static void dump_widget_tree_level(struct xuni_t *xuni,
16 struct widget_t *widget, size_t level);
18 static void dump_indent(FILE *fp, size_t level);
19 static void dump_xml_tag_string(FILE *fp, size_t level, const char *tagname,
20 const char *data);
21 static void dump_xml_tag_double(FILE *fp, size_t level, const char *tagname,
22 double data);
23 static void dump_widget_tree_xml_level(struct xuni_t *xuni,
24 struct widget_t *widget, FILE *fp, size_t level);
26 void print_widget_backtrace(struct xuni_t *xuni, struct widget_t *widget) {
27 printf("print_widget_backtrace():\n");
29 while(widget) {
30 printf(" %9s: " /*"at (%6.2f,%6.2f), size (%6.2f,%6.2f), "*/
31 "\"%s\"\n", get_widget_type_name(xuni, widget->type),
32 /*widget->pos->scale.x, widget->pos->scale.y,
33 widget->pos->scale.w, widget->pos->scale.h,*/ widget->name);
35 widget = widget->base;
38 putchar('\n');
41 const char *get_widget_type_name(struct xuni_t *xuni,
42 enum widget_type_t type) {
44 static char buffer[BUFSIZ];
46 if((size_t)type < xuni->wtype->types) {
47 return xuni->wtype->type[type].name;
50 sprintf(buffer, "[invalid type: %lu]", (unsigned long)type);
51 return buffer;
54 /*! Prints the name of \a widget along with the names of all of its parents,
55 with the highest tree element last. Designed to print widget information
56 with as little space as possible, often taking only one line per widget.
57 \param widget The widget to print a backtrace for.
59 void print_inline_widget_backtrace(struct widget_t *widget) {
60 if(!widget) return;
62 printf("inline backtrace:");
64 while(widget) {
65 printf(" <- \"%s\"", widget->name);
66 widget = widget->base;
69 printf("\n");
72 void print_sel_widgets(struct widget_t *widget) {
73 size_t x;
75 if(!widget) return;
77 if(widget->sel) {
78 struct widget_t *w;
80 printf("sel: [vis=%i parent considered=%i children considered=%i]",
81 widget->visibility,
82 !(widget->visibility & WIDGET_VISIBILITY_INDEPENDENT),
83 !(widget->visibility & WIDGET_VISIBILITY_NOT_COMPOSE));
85 if(widget->type == WIDGET_LABEL) {
86 printf("\"%s\"", widget->p.label->text);
89 for(w = widget; w; w = w->base) {
90 printf(" <- \"%s\"", w->name);
92 printf("\n");
95 if(widget->compose) {
96 for(x = 0; x < widget->compose->widgets; x ++) {
97 print_sel_widgets(widget->compose->widget[x]);
102 void print_widget_clip(struct widget_t *widget) {
103 if(!widget) return;
105 if(!widget->pos->clip) printf("clip: None");
106 else {
107 printf("clip: off=(%i,%i) clip=(%i,%i) by (%i,%i)",
108 widget->pos->clip->xoff, widget->pos->clip->yoff,
109 widget->pos->clip->xclip, widget->pos->clip->yclip,
110 widget->pos->clip->wclip, widget->pos->clip->hclip);
113 printf(" name=\"%s\"\n", widget->name);
116 static void dump_widget_tree_level(struct xuni_t *xuni,
117 struct widget_t *widget, size_t level) {
119 size_t x;
121 if(!widget) return;
123 for(x = 0; x < level * 4; x ++) putchar(' ');
125 printf("\"%s\" [%s]\n", widget->name,
126 get_widget_type_name(xuni, widget->type));
128 if(widget->compose) {
129 for(x = 0; x < widget->compose->widgets; x ++) {
130 dump_widget_tree_level(xuni, widget->compose->widget[x],
131 level + 1);
136 void dump_widget_tree(struct xuni_t *xuni, struct widget_t *widget) {
137 puts("Widget tree dump:");
138 dump_widget_tree_level(xuni, widget, 1);
141 static void dump_indent(FILE *fp, size_t level) {
142 size_t x;
144 for(x = 0; x < level * 4; x ++) fputc(' ', fp);
147 static void dump_xml_tag_string(FILE *fp, size_t level, const char *tagname,
148 const char *data) {
150 dump_indent(fp, level + 1);
151 fprintf(fp, "<%s>%s</%s>\n", tagname, data, tagname);
154 static void dump_xml_tag_double(FILE *fp, size_t level, const char *tagname,
155 double data) {
157 dump_indent(fp, level + 1);
158 fprintf(fp, "<%s>%f</%s>\n", tagname, data, tagname);
161 static void dump_widget_tree_xml_level(struct xuni_t *xuni,
162 struct widget_t *widget, FILE *fp, size_t level) {
164 size_t x;
166 if(!widget) return;
168 dump_indent(fp, level);
169 fprintf(fp, "<widget type=\"%s\">\n",
170 get_widget_type_name(xuni, widget->type));
172 dump_xml_tag_string(fp, level, "name", widget->name);
174 if(widget->pos->scale.x) {
175 dump_xml_tag_double(fp, level, "xpos", widget->pos->scale.x);
177 if(widget->pos->scale.y) {
178 dump_xml_tag_double(fp, level, "ypos", widget->pos->scale.y);
180 if(widget->pos->scale.w != 100.0) {
181 dump_xml_tag_double(fp, level, "width", widget->pos->scale.w);
183 if(widget->pos->scale.h != 100.0) {
184 dump_xml_tag_double(fp, level, "height", widget->pos->scale.h);
187 switch(widget->type) {
188 case WIDGET_BUTTON:
189 if(widget->compose->widget[WID_BUTTON_LABEL]) {
190 dump_xml_tag_string(fp, level, "text",
191 widget->compose->widget[WID_BUTTON_LABEL]->p.label->text);
194 break;
195 case WIDGET_PANEL:
196 if(widget->compose) {
197 for(x = 0; x < widget->compose->widgets; x ++) {
198 dump_widget_tree_xml_level(xuni, widget->compose->widget[x],
199 fp, level + 1);
203 break;
204 case WIDGET_BOX:
205 break;
206 default:
207 printf("*** Dumping widgets of type %s not supported\n",
208 get_widget_type_name(xuni, widget->type));
209 break;
212 dump_indent(fp, level);
213 fputs("</widget>\n", fp);
216 void dump_widget_tree_xml(struct xuni_t *xuni, struct widget_t *widget,
217 const char *filename) {
219 FILE *fp;
221 rename(filename, "dump.oldfile");
223 fp = fopen(filename, "w");
224 if(!fp) {
225 log_message(ERROR_TYPE_SETTING, 0, __FILE__, __LINE__,
226 "Can't dump xml file \"%s\"", filename);
227 return;
230 fputs("<?xml version=\"1.0\"?>\n"
231 "<!-- ", fp);
232 fputs(filename, fp);
233 fputs(" -->\n"
234 "<xuni-resource>\n", fp);
236 dump_widget_tree_xml_level(xuni, widget, fp, 1);
238 fputs("</xuni-resource>\n", fp);
240 fclose(fp);
243 void dump_widgets_need_repaint(struct widget_t *widget) {
244 size_t x;
246 if(!widget) return;
248 if(widget->repaint) print_inline_widget_backtrace(widget);
250 if(widget->compose) {
251 for(x = 0; x < widget->compose->widgets; x ++) {
252 dump_widgets_need_repaint(widget->compose->widget[x]);