Een heleboel, relatief nutteloze dingen, zoals blank windows, en filerefs
[rodin/chimara.git] / src / window.c
1 #include "window.h"
2
3 /* Global tree of all windows */
4 static GNode *root_window = NULL;
5
6 /**
7  * glk_window_iterate:
8  * @win: A window, or #NULL.
9  * @rockptr: Return location for the next window's rock, or #NULL.
10  *
11  * Iterates over the list of windows; if @win is #NULL, it returns the first
12  * window, otherwise the next window after @win. If there are no more, it
13  * returns #NULL. The window's rock is stored in @rockptr. If you don't want
14  * the rocks to be returned, you may set @rockptr to #NULL.
15  *
16  * The order in which windows are returned is arbitrary. The root window is
17  * not necessarily first, nor is it necessarily last. The order may change
18  * every time you create or destroy a window, invalidating the iteration.
19  *
20  * Returns: the next window, or #NULL if there are no more.
21  */
22 winid_t
23 glk_window_iterate(winid_t win, glui32 *rockptr)
24 {
25         GNode *retnode;
26         
27         if(win == NULL)
28                 retnode = root_window;
29         else
30         {
31                 GNode *node = win->window_node;
32                 if( G_NODE_IS_LEAF(node) )
33                 {
34                         while(node && node->next == NULL)
35                                 node = node->parent;
36                         if(node)
37                                 retnode = node->next;
38                         else
39                                 retnode = NULL;
40                 }
41                 else
42                         retnode = g_node_first_child(node);
43         }
44         winid_t retval = retnode? (winid_t)retnode->data : NULL;
45                 
46         /* Store the window's rock in rockptr */
47         if(retval && rockptr)
48                 *rockptr = glk_window_get_rock(retval);
49                 
50         return retval;
51 }
52
53 /**
54  * glk_window_get_rock:
55  * @win: A window.
56  * 
57  * Returns the window @win's rock value. Pair windows always have rock 0.
58  *
59  * Returns: A rock value.
60  */
61 glui32
62 glk_window_get_rock(winid_t win)
63 {
64         g_return_val_if_fail(win != NULL, 0);
65         return win->rock;
66 }
67
68 /**
69  * glk_window_open:
70  * @split: The window to split to create the new window. Must be 0 if there
71  * are no windows yet.
72  * @method: Position of the new window and method of size computation. One of
73  * #winmethod_Above, #winmethod_Below, #winmethod_Left, or #winmethod_Right
74  * OR'ed with #winmethod_Fixed or #winmethod_Proportional. If @wintype is
75  * #wintype_Blank, then #winmethod_Fixed is not allowed.
76  * @size: Size of the new window, in percentage points if @method is
77  * #winmethod_Proportional, otherwise in characters if @wintype is 
78  * #wintype_TextBuffer or #wintype_TextGrid, or pixels if @wintype is
79  * #wintype_Graphics.
80  * @wintype: Type of the new window. One of #wintype_Blank, #wintype_TextGrid,
81  * #wintype_TextBuffer, or #wintype_Graphics.
82  * @rock: The new window's rock value.
83  *
84  * If there are no windows, create a new root window. @split must be 0, and
85  * @method and @size are ignored. Otherwise, split window @split into two, with
86  * position, size, and type specified by @method, @size, and @wintype. See the
87  * Glk documentation for the window placement algorithm.
88  *
89  * Returns: the new window.
90  */
91 winid_t
92 glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype, 
93                 glui32 rock)
94 {
95         extern GtkBuilder *builder;
96
97         if(split)
98         {
99                 g_warning("glk_window_open: splitting of windows not implemented");
100                 return NULL;
101         }
102
103         if(root_window != NULL)
104         {
105                 g_warning("glk_window_open: there is already a window");
106                 return NULL;
107         }
108         /* We only create one window and don't support any more than that */
109         winid_t new_window = g_new0(struct glk_window_struct, 1);
110         root_window = g_node_new(new_window);
111
112         new_window->rock = rock;
113         new_window->window_type = wintype;
114
115         GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") );                      
116         if(vbox == NULL)
117         {
118                 error_dialog(NULL, NULL, "Could not find vbox");
119                 return NULL;
120         }
121
122         switch(wintype)
123         {
124                 case wintype_Blank:
125                 {
126                         /* A blank window will be a label without any text */
127                         GtkWidget *window = gtk_label_new("");
128                         gtk_box_pack_end(vbox, window, TRUE, TRUE, 0);
129                         gtk_widget_show(window);
130                         
131                         new_window->widget = window;
132                         /* You can print to a blank window's stream, but it does nothing */
133                         new_window->window_stream = window_stream_new(new_window);
134                         new_window->echo_stream = NULL;
135                 }
136                         break;  
137                 case wintype_TextBuffer:
138                 {
139                         GtkWidget *scroll_window = gtk_scrolled_window_new(NULL, NULL);
140                         GtkWidget *window = gtk_text_view_new();
141                         gtk_container_add( GTK_CONTAINER(scroll_window), window );
142                         gtk_box_pack_end(vbox, scroll_window, TRUE, TRUE, 0);
143                         gtk_widget_show_all(scroll_window);
144
145                         new_window->widget = window;
146                         new_window->window_stream = window_stream_new(new_window);
147                         new_window->echo_stream = NULL;
148                         new_window->input_request_type = INPUT_REQUEST_NONE;
149                         new_window->line_input_buffer = NULL;
150                         new_window->line_input_buffer_unicode = NULL;
151                 }
152                         break;
153                 default:
154                         g_warning("glk_window_open: unsupported window type");
155                         g_free(new_window);
156                         return NULL;
157         }
158
159         new_window->window_node = root_window;
160
161         return new_window;
162 }
163
164 /**
165  * glk_set_window:
166  * @win: A window.
167  *
168  * Sets the current stream to @win's window stream.
169  */
170 void
171 glk_set_window(winid_t win)
172 {
173         glk_stream_set_current( glk_window_get_stream(win) );
174 }
175
176 /**
177  * glk_window_get_stream:
178  * @win: A window.
179  *
180  * Gets the stream associated with @win.
181  *
182  * Returns: The window stream.
183  */
184 strid_t glk_window_get_stream(winid_t win)
185 {
186         return win->window_stream;
187 }
188