1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include <lttvwindow/gtkmultivpaned.h>
26 #include <lttvwindow/mainwindow.h>
27 #include <lttvwindow/mainwindow-private.h>
28 //#include "gtkintl.h"
30 static void gtk_multi_vpaned_class_init (GtkMultiVPanedClass *klass);
31 static void gtk_multi_vpaned_init (GtkMultiVPaned *multi_vpaned);
34 static void gtk_multi_vpaned_size_request (GtkWidget *widget,
35 GtkRequisition *requisition);
36 static void gtk_multi_vpaned_size_allocate (GtkWidget *widget,
37 GtkAllocation *allocation);
39 void gtk_multi_vpaned_scroll_value_changed (GtkAdjustment *adjust, gpointer multi_vpaned);
41 gboolean gtk_multi_vpaned_destroy(GtkObject *object,
44 GtkMultiVPaned * multi_vpaned = (GtkMultiVPaned * )object;
45 while(multi_vpaned->num_children){
46 gtk_multi_vpaned_widget_delete(multi_vpaned);
52 gtk_multi_vpaned_get_type (void)
54 static GType multi_vpaned_type = 0;
56 if (!multi_vpaned_type)
58 static const GTypeInfo multi_vpaned_info =
60 sizeof (GtkMultiVPanedClass),
62 NULL, /* base_finalize */
63 (GClassInitFunc) gtk_multi_vpaned_class_init,
64 NULL, /* class_finalize */
65 NULL, /* class_data */
66 sizeof (GtkMultiVPaned),
68 (GInstanceInitFunc) gtk_multi_vpaned_init,
69 NULL, /* value_table */
72 multi_vpaned_type = g_type_register_static (GTK_TYPE_PANED, "GtkMultiVPaned",
73 &multi_vpaned_info, 0);
76 return multi_vpaned_type;
80 gtk_multi_vpaned_class_init (GtkMultiVPanedClass *class)
82 GtkWidgetClass *widget_class;
84 widget_class = (GtkWidgetClass *) class;
86 widget_class->size_request = gtk_multi_vpaned_size_request;
87 widget_class->size_allocate = gtk_multi_vpaned_size_allocate;
91 gtk_multi_vpaned_init (GtkMultiVPaned * multi_vpaned)
95 GTK_WIDGET_SET_FLAGS (multi_vpaned, GTK_NO_WINDOW);
96 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (multi_vpaned), FALSE);
98 multi_vpaned->first_pane = NULL;
99 multi_vpaned->last_pane = NULL;
100 multi_vpaned->focused_pane = NULL;
101 multi_vpaned->iter = NULL;
102 multi_vpaned->num_children = 0;
104 multi_vpaned->vbox = NULL;
105 // multi_vpaned->scrollWindow = NULL;
106 // multi_vpaned->viewport = NULL;
107 multi_vpaned->hscrollbar = NULL;
111 GtkWidget* gtk_multi_vpaned_new ()
113 GtkWidget * widget = GTK_WIDGET (g_object_new (gtk_multi_vpaned_get_type (), NULL));
114 g_signal_connect(G_OBJECT(widget), "destroy",
115 G_CALLBACK(gtk_multi_vpaned_destroy),NULL);
120 GtkWidget * gtk_multi_vpaned_get_widget(GtkMultiVPaned * multi_vpaned)
122 if(multi_vpaned->focused_pane == NULL)return NULL;
123 return (GtkWidget*)multi_vpaned->focused_pane->child2;
126 GtkWidget * gtk_multi_vpaned_get_first_widget(GtkMultiVPaned * multi_vpaned)
128 if(multi_vpaned->first_pane == NULL)return NULL;
129 multi_vpaned->iter = multi_vpaned->first_pane;
130 return multi_vpaned->first_pane->child2;
133 GtkWidget * gtk_multi_vpaned_get_next_widget(GtkMultiVPaned * multi_vpaned)
135 if(multi_vpaned->iter != multi_vpaned->last_pane){
136 multi_vpaned->iter = (GtkPaned *)multi_vpaned->iter->child1;
137 return multi_vpaned->iter->child2;
143 void gtk_multi_vpaned_set_data(GtkMultiVPaned * multi_vpaned,char * key, gpointer value)
145 g_object_set_data(G_OBJECT(multi_vpaned->focused_pane), key, value);
148 gpointer gtk_multi_vpaned_get_data(GtkMultiVPaned * multi_vpaned,char * key)
150 if(multi_vpaned->focused_pane == NULL)return NULL;
151 return g_object_get_data(G_OBJECT(multi_vpaned->focused_pane), key);
154 void gtk_multi_vpaned_set_focus (GtkWidget * widget, GtkPaned* paned)
156 GtkMultiVPaned * multi_vpaned = GTK_MULTI_VPANED(widget);
158 if(!multi_vpaned->first_pane) return;
161 pane = multi_vpaned->first_pane;
163 if((GtkWidget*)pane == GTK_WIDGET(paned)){
164 multi_vpaned->focused_pane = pane;
167 if(pane == multi_vpaned->last_pane){
168 multi_vpaned->focused_pane = NULL;
171 pane = (GtkPaned*)pane->child1;
175 void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, const TimeWindow *time_window, gboolean first_time)
177 TimeInterval *time_span;
179 Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
180 LttvTracesetContext *tsc =
181 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
185 time_span = &tsc->time_span ;
187 multi_vpaned->hadjust->lower = ltt_time_to_double(time_span->start_time) *
188 NANOSECONDS_PER_SECOND;
189 multi_vpaned->hadjust->value = multi_vpaned->hadjust->lower;
190 multi_vpaned->hadjust->upper = ltt_time_to_double(time_span->end_time) *
191 NANOSECONDS_PER_SECOND;
194 /* Page increment of whole visible area */
195 if(multi_vpaned->hadjust == NULL){
196 g_warning("Insert a viewer first");
200 start = ltt_time_to_double(time_window->start_time) * NANOSECONDS_PER_SECOND;
201 len = multi_vpaned->hadjust->upper - multi_vpaned->hadjust->lower;
203 multi_vpaned->hadjust->page_increment = ltt_time_to_double(
204 time_window->time_width) * NANOSECONDS_PER_SECOND;
206 //if(multi_vpaned->hadjust->page_increment >= len )
207 // multi_vpaned->hadjust->value = multi_vpaned->hadjust->lower;
208 //if(start + multi_vpaned->hadjust->page_increment >= multi_vpaned->hadjust->upper )
209 // multi_vpaned->hadjust->value = start;
210 multi_vpaned->hadjust->value = start;
212 /* page_size to the whole visible area will take care that the
213 * scroll value + the shown area will never be more than what is
215 multi_vpaned->hadjust->page_size = multi_vpaned->hadjust->page_increment;
216 multi_vpaned->hadjust->step_increment = multi_vpaned->hadjust->page_increment / 10;
218 gtk_adjustment_changed (multi_vpaned->hadjust);
222 void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widget1)
226 Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
228 g_return_if_fail(GTK_IS_MULTI_VPANED(multi_vpaned));
229 g_object_ref(G_OBJECT(widget1));
232 if(!multi_vpaned->first_pane){
233 multi_vpaned->first_pane = (GtkPaned *)gtk_vpaned_new();
234 multi_vpaned->last_pane = multi_vpaned->first_pane;
236 multi_vpaned->hscrollbar = gtk_hscrollbar_new (NULL);
237 gtk_widget_show(multi_vpaned->hscrollbar);
239 multi_vpaned->hadjust = gtk_range_get_adjustment(GTK_RANGE(multi_vpaned->hscrollbar));
240 gtk_multi_vpaned_set_adjust(multi_vpaned, &tab->time_window, TRUE);
242 gtk_range_set_update_policy (GTK_RANGE(multi_vpaned->hscrollbar),
243 GTK_UPDATE_CONTINUOUS);
244 //changed by Mathieu Desnoyers, was :
245 // GTK_UPDATE_DISCONTINUOUS);
246 g_signal_connect(G_OBJECT(multi_vpaned->hadjust), "value-changed",
247 G_CALLBACK(gtk_multi_vpaned_scroll_value_changed), multi_vpaned);
248 g_signal_connect(G_OBJECT(multi_vpaned->hadjust), "changed",
249 G_CALLBACK(gtk_multi_vpaned_scroll_value_changed), multi_vpaned);
252 multi_vpaned->vbox = gtk_vbox_new(FALSE,0);
253 gtk_widget_show(multi_vpaned->vbox);
255 // multi_vpaned->viewport = gtk_viewport_new (NULL,NULL);
256 // gtk_widget_show(multi_vpaned->viewport);
258 // gtk_container_add(GTK_CONTAINER(multi_vpaned->viewport), (GtkWidget*)multi_vpaned->vbox);
259 gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->hscrollbar,FALSE,FALSE,0);
260 gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane,TRUE,TRUE,0);
262 // multi_vpaned->scrollWindow = gtk_scrolled_window_new (NULL, NULL);
263 // gtk_widget_show(multi_vpaned->scrollWindow);
264 // gtk_container_add (GTK_CONTAINER (multi_vpaned->scrollWindow), (GtkWidget*)multi_vpaned->viewport);
265 // gtk_paned_pack1(GTK_PANED(multi_vpaned), (GtkWidget*)multi_vpaned->scrollWindow,FALSE, TRUE);
267 gtk_paned_pack1(GTK_PANED(multi_vpaned), (GtkWidget*)multi_vpaned->vbox,FALSE, TRUE);
269 tmpPane = multi_vpaned->last_pane;
270 multi_vpaned->last_pane = (GtkPaned *)gtk_vpaned_new();
271 gtk_paned_pack1 (tmpPane,(GtkWidget*)multi_vpaned->last_pane, FALSE,TRUE);
273 gtk_widget_show((GtkWidget *)multi_vpaned->last_pane);
275 gtk_paned_pack2 (multi_vpaned->last_pane,widget1, TRUE, TRUE);
276 multi_vpaned->focused_pane = multi_vpaned->last_pane;
277 multi_vpaned->num_children++;
281 void gtk_multi_vpaned_widget_delete(GtkMultiVPaned * multi_vpaned)
283 GtkPaned * tmp, *prev, *next;
286 if(!multi_vpaned->focused_pane) return;
288 widget = GTK_WIDGET(multi_vpaned->focused_pane->child2); //widget in vpaned
289 g_object_unref(G_OBJECT(widget));
291 if(multi_vpaned->focused_pane == multi_vpaned->first_pane &&
292 multi_vpaned->focused_pane == multi_vpaned->last_pane){
293 // gtk_container_remove(GTK_CONTAINER(multi_vpaned),(GtkWidget*)multi_vpaned->scrollWindow);
294 gtk_container_remove(GTK_CONTAINER(multi_vpaned),(GtkWidget*)multi_vpaned->vbox);
295 multi_vpaned->first_pane = NULL;
296 multi_vpaned->last_pane = NULL;
297 multi_vpaned->focused_pane = NULL;
298 }else if(multi_vpaned->focused_pane == multi_vpaned->first_pane &&
299 multi_vpaned->focused_pane != multi_vpaned->last_pane){
300 next = (GtkPaned*)multi_vpaned->first_pane->child1;
301 g_object_ref(G_OBJECT(next));
302 gtk_container_remove(GTK_CONTAINER(multi_vpaned->first_pane),(GtkWidget*)next);
303 gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane);
304 multi_vpaned->first_pane = next;
305 gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane,TRUE,TRUE,0);
306 multi_vpaned->focused_pane = multi_vpaned->first_pane;
307 g_object_unref(G_OBJECT(next));
308 }else if(multi_vpaned->focused_pane != multi_vpaned->first_pane &&
309 multi_vpaned->focused_pane == multi_vpaned->last_pane){
310 tmp = multi_vpaned->last_pane;
311 multi_vpaned->last_pane = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->last_pane);
312 multi_vpaned->focused_pane = multi_vpaned->last_pane;
313 gtk_container_remove(GTK_CONTAINER(multi_vpaned->last_pane),(GtkWidget*)tmp);
315 tmp = multi_vpaned->focused_pane;
316 prev = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)tmp);
317 next = (GtkPaned*)tmp->child1;
318 g_object_ref(G_OBJECT(next));
319 gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)next);
320 gtk_container_remove(GTK_CONTAINER(prev),(GtkWidget*)multi_vpaned->focused_pane);
321 gtk_paned_pack1(prev, (GtkWidget*)next, FALSE, TRUE);
322 multi_vpaned->focused_pane = next;
323 g_object_unref(G_OBJECT(next));
326 multi_vpaned->num_children--;
330 void gtk_multi_vpaned_widget_move_up(GtkMultiVPaned * multi_vpaned)
332 GtkWidget* upWidget, *downWidget;
333 GtkPaned * prev,*next, *prevPrev;
335 if(multi_vpaned->last_pane == multi_vpaned->focused_pane) return;
338 prev = (GtkPaned*)multi_vpaned->focused_pane->child1;
339 g_object_ref(G_OBJECT(prev));
340 gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)prev);
342 if(prev == multi_vpaned->last_pane){
344 multi_vpaned->last_pane = multi_vpaned->focused_pane;
346 prevPrev = (GtkPaned*)prev->child1;
347 g_object_ref(G_OBJECT(prevPrev));
348 gtk_container_remove(GTK_CONTAINER(prev),(GtkWidget*)prevPrev);
351 g_object_ref(G_OBJECT(multi_vpaned->focused_pane));
352 if(multi_vpaned->first_pane == multi_vpaned->focused_pane){
353 gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->focused_pane);
354 gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)prev,TRUE,TRUE,0);
355 multi_vpaned->first_pane = prev;
357 next = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->focused_pane);
358 gtk_container_remove(GTK_CONTAINER(next),(GtkWidget*)multi_vpaned->focused_pane);
359 gtk_paned_pack1(GTK_PANED(next), (GtkWidget*)prev, FALSE,TRUE);
361 gtk_paned_pack1(GTK_PANED(prev),(GtkWidget*)multi_vpaned->focused_pane, FALSE,TRUE);
363 gtk_paned_pack1(GTK_PANED(multi_vpaned->focused_pane),(GtkWidget*)prevPrev, FALSE,TRUE);
365 g_object_unref(G_OBJECT(prev));
366 if(prevPrev) g_object_unref(G_OBJECT(prevPrev));
367 g_object_unref(G_OBJECT(multi_vpaned->focused_pane));
371 void gtk_multi_vpaned_widget_move_down(GtkMultiVPaned * multi_vpaned)
373 GtkWidget* upWidget, *downWidget;
374 GtkPaned * prev,*next, *nextNext;
376 if(multi_vpaned->first_pane == multi_vpaned->focused_pane) return;
379 next = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->focused_pane);
380 g_object_ref(G_OBJECT(next));
382 if(multi_vpaned->last_pane == multi_vpaned->focused_pane){
384 multi_vpaned->last_pane = next;
386 prev = (GtkPaned*)multi_vpaned->focused_pane->child1;
387 g_object_ref(G_OBJECT(prev));
388 gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)prev);
391 g_object_ref(G_OBJECT(multi_vpaned->focused_pane));
392 gtk_container_remove(GTK_CONTAINER(next),(GtkWidget*)multi_vpaned->focused_pane);
394 if(next == multi_vpaned->first_pane){
395 multi_vpaned->first_pane = multi_vpaned->focused_pane;
396 gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)next);
397 gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->focused_pane,TRUE,TRUE,0);
399 nextNext = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)next);
400 gtk_container_remove(GTK_CONTAINER(nextNext),(GtkWidget*)next);
401 gtk_paned_pack1(nextNext, (GtkWidget*)multi_vpaned->focused_pane, FALSE, TRUE);
403 gtk_paned_pack1(multi_vpaned->focused_pane,(GtkWidget*)next, FALSE,TRUE);
405 gtk_paned_pack1(next,(GtkWidget*)prev, FALSE,TRUE);
407 if(prev)g_object_unref(G_OBJECT(prev));
408 g_object_unref(G_OBJECT(next));
409 g_object_unref(G_OBJECT(multi_vpaned->focused_pane));
412 void gtk_multi_vpaned_set_scroll_value(GtkMultiVPaned * multi_vpaned, double value)
414 gtk_adjustment_set_value(multi_vpaned->hadjust, value);
415 //g_signal_stop_emission_by_name(G_OBJECT(multi_vpaned->hscrollbar), "value-changed");
418 void gtk_multi_vpaned_scroll_value_changed(GtkAdjustment *adjust, gpointer multi_vpaned_arg)
420 TimeWindow time_window;
421 TimeInterval *time_span;
423 GtkMultiVPaned * multi_vpaned = (GtkMultiVPaned*)multi_vpaned_arg;
424 gdouble value = gtk_adjustment_get_value(adjust);
425 gdouble upper, lower, ratio;
426 Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
427 LttvTracesetContext * tsc =
428 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
430 time_window = tab->time_window;
432 time_span = &tsc->time_span ;
433 lower = multi_vpaned->hadjust->lower;
434 upper = multi_vpaned->hadjust->upper;
435 ratio = (value - lower) / (upper - lower);
437 time = ltt_time_sub(time_span->end_time, time_span->start_time);
438 time = ltt_time_mul(time, (float)ratio);
439 time = ltt_time_add(time_span->start_time, time);
441 time_window.start_time = time;
443 time = ltt_time_sub(time_span->end_time, time);
444 if(ltt_time_compare(time,time_window.time_width) < 0){
445 time_window.time_width = time;
447 set_time_window(tab, &time_window);
452 gtk_multi_vpaned_size_request (GtkWidget *widget,
453 GtkRequisition *requisition)
455 GtkPaned *paned = GTK_PANED (widget);
456 GtkRequisition child_requisition;
458 requisition->width = 0;
459 requisition->height = 0;
461 if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
463 gtk_widget_size_request (paned->child1, &child_requisition);
465 requisition->height = child_requisition.height;
466 requisition->width = child_requisition.width;
469 if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
471 gtk_widget_size_request (paned->child2, &child_requisition);
473 requisition->width = MAX (requisition->width, child_requisition.width);
474 requisition->height += child_requisition.height;
477 requisition->height += GTK_CONTAINER (paned)->border_width * 2;
478 requisition->width += GTK_CONTAINER (paned)->border_width * 2;
480 if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
481 paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
485 gtk_widget_style_get (widget, "handle_size", &handle_size, NULL);
486 requisition->height += handle_size;
492 gtk_multi_vpaned_size_allocate (GtkWidget *widget,
493 GtkAllocation *allocation)
495 GtkPaned *paned = GTK_PANED (widget);
496 gint border_width = GTK_CONTAINER (paned)->border_width;
498 widget->allocation = *allocation;
500 if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
501 paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
503 GtkRequisition child1_requisition;
504 GtkRequisition child2_requisition;
505 GtkAllocation child1_allocation;
506 GtkAllocation child2_allocation;
509 gtk_widget_style_get (widget, "handle_size", &handle_size, NULL);
511 gtk_widget_get_child_requisition (paned->child1, &child1_requisition);
512 gtk_widget_get_child_requisition (paned->child2, &child2_requisition);
514 gtk_paned_compute_position (paned,
515 MAX (1, widget->allocation.height
518 child1_requisition.height,
519 child2_requisition.height);
521 paned->handle_pos.x = widget->allocation.x + border_width;
522 paned->handle_pos.y = widget->allocation.y + paned->child1_size + border_width;
523 paned->handle_pos.width = MAX (1, (gint) widget->allocation.width - 2 * border_width);
524 paned->handle_pos.height = handle_size;
526 if (GTK_WIDGET_REALIZED (widget))
528 if (GTK_WIDGET_MAPPED (widget))
529 gdk_window_show (paned->handle);
530 gdk_window_move_resize (paned->handle,
533 paned->handle_pos.width,
537 child1_allocation.width = child2_allocation.width = MAX (1, (gint) allocation->width - border_width * 2);
538 child1_allocation.height = MAX (1, paned->child1_size);
539 child1_allocation.x = child2_allocation.x = widget->allocation.x + border_width;
540 child1_allocation.y = widget->allocation.y + border_width;
542 child2_allocation.y = child1_allocation.y + paned->child1_size + paned->handle_pos.height;
543 child2_allocation.height = MAX (1, widget->allocation.y + widget->allocation.height - child2_allocation.y - border_width);
545 if (GTK_WIDGET_MAPPED (widget) &&
546 paned->child1->allocation.height < child1_allocation.height)
548 gtk_widget_size_allocate (paned->child2, &child2_allocation);
549 gtk_widget_size_allocate (paned->child1, &child1_allocation);
553 gtk_widget_size_allocate (paned->child1, &child1_allocation);
554 gtk_widget_size_allocate (paned->child2, &child2_allocation);
559 GtkAllocation child_allocation;
561 if (GTK_WIDGET_REALIZED (widget))
562 gdk_window_hide (paned->handle);
565 gtk_widget_set_child_visible (paned->child1, TRUE);
567 gtk_widget_set_child_visible (paned->child2, TRUE);
569 child_allocation.x = widget->allocation.x + border_width;
570 child_allocation.y = widget->allocation.y + border_width;
571 child_allocation.width = MAX (1, allocation->width - 2 * border_width);
572 child_allocation.height = MAX (1, allocation->height - 2 * border_width);
574 if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
575 gtk_widget_size_allocate (paned->child1, &child_allocation);
576 else if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
577 gtk_widget_size_allocate (paned->child2, &child_allocation);