## scrollable-graphviz-widget.pkg
#
# A little wrapper widget which attaches two scrollbars
# to the basic graphviz widget.
# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublibstipulate
include package threadkit; # threadkit is from
src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg include package geometry2d; # geometry2d is from
src/lib/std/2d/geometry2d.pkg #
package f8b = eight_byte_float; # eight_byte_float is from
src/lib/std/eight-byte-float.pkg package xtr = xlogger; # xlogger is from
src/lib/x-kit/xclient/src/stuff/xlogger.pkg #
package gv = graphviz_widget; # graphviz_widget is from
src/lib/x-kit/widget/old/fancy/graphviz/graphviz-widget.pkg package b = border; # border is from
src/lib/x-kit/widget/old/wrapper/border.pkg package sb = scrollbar; # scrollbar is from
src/lib/x-kit/widget/old/leaf/scrollbar.pkg package sbl = widget_with_scrollbars; # widget_with_scrollbars is from
src/lib/x-kit/widget/old/layout/widget-with-scrollbars.pkg package wg = widget; # widget is from
src/lib/x-kit/widget/old/basic/widget.pkg package ffc = font_family_cache; # font_family_cache is from
src/lib/x-kit/widget/old/fancy/graphviz/font-family-cache.pkg package lw = line_of_widgets; # line_of_widgets is from
src/lib/x-kit/widget/old/layout/line-of-widgets.pkg package xc = xclient; # xclient is from
src/lib/x-kit/xclient/xclient.pkgherein
# This package gets used in:
#
#
src/lib/x-kit/tut/show-graph/show-graph-app.pkg #
package scrollable_graphviz_widget
: Scrollable_Graphviz_Widget # Scrollable_Graphviz_Widget is from
src/lib/x-kit/widget/old/fancy/graphviz/scrollable-graphviz-widget.api {
Scrollable_Graphviz_Widget
=
SCROLLABLE_GRAPHVIZ_WIDGET
{ widget: wg::Widget,
graphviz_widget: gv::Graphviz_Widget
};
Vport = { min: Int,
size: Int,
total: Int
};
State = (Vport, Vport);
scroll_bar_size = 10;
fun make_scrollable_graphviz_widget (font_family_cache, root_window) graph
=
{
graphviz_widget = gv::make_graphviz_widget (font_family_cache, root_window) graph ;
move_scrollbar_thumbs_mailop = gv::to_scrollbars_mailop_of graphviz_widget;
horizontal_scrollbar = sb::make_horizontal_scrollbar root_window { color=>NULL, size=>scroll_bar_size }; horizontal_scrollbar_change' = sb::scrollbar_change'_of horizontal_scrollbar;
vertical_scrollbar = sb::make_vertical_scrollbar root_window { color=>NULL, size=>scroll_bar_size }; vertical_scrollbar_change' = sb::scrollbar_change'_of vertical_scrollbar;
black = xc::black;
widget
=
sbl::make_widget_with_scrollbars root_window
{
scrolled_widget => gv::as_widget graphviz_widget,
horizontal_scrollbar
=>
THE { pad => 1,
top => FALSE,
scrollbar
=>
b::as_widget
(b::make_border
{
color => THE black,
width => 1,
child => lw::as_widget
(lw::make_line_of_widgets root_window
(lw::VT_CENTER
[
lw::SPACER { min_size=>1, best_size=>1, max_size=>THE 1 },
lw::WIDGET (sb::as_widget horizontal_scrollbar),
lw::SPACER { min_size=>1, best_size=>1, max_size=>THE 1 }
]
)
)
}
)
},
vertical_scrollbar
=>
THE { pad => 1,
left => FALSE,
scrollbar
=>
b::as_widget
(b::make_border
{
color => THE black,
width => 1,
child => lw::as_widget
(lw::make_line_of_widgets root_window
(lw::HZ_CENTER
[
lw::SPACER { min_size=>1, best_size=>1, max_size=>THE 1 },
lw::WIDGET (sb::as_widget vertical_scrollbar),
lw::SPACER { min_size=>1, best_size=>1, max_size=>THE 1 }
]
)
)
}
)
}
};
initstate
=
( { min=>0, size=>0, total=>0 },
{ min=>0, size=>0, total=>0 }
);
# Handle user drag of horizontal scrollbar:
#
fun do_horizontal_scrollbar_change (sb::SCROLL_UP r, state: State) => state;
do_horizontal_scrollbar_change (sb::SCROLL_DOWN r, state: State) => state;
do_horizontal_scrollbar_change (sb::SCROLL_END r, state as ( { min, size, total }, v))
=>
{ min' = floor (r * (float total));
#
if (min' != min)
#
gv::set_horizontal_view graphviz_widget min';
( { min=>min', size, total }, v);
else
state;
fi;
};
do_horizontal_scrollbar_change (_, state)
=>
state;
end;
# Handle user drag of vertical scrollbar:
#
fun do_vertical_scrollbar_change (sb::SCROLL_UP r, state: State) => state;
do_vertical_scrollbar_change (sb::SCROLL_DOWN r, state: State) => state;
do_vertical_scrollbar_change (sb::SCROLL_END r, state as (h, { min, size, total } ))
=>
{ min' = floor (r * (float total));
#
if (min' != min)
#
gv::set_vertical_view graphviz_widget min';
(h, { min=>min', size, total } );
else
state;
fi;
};
do_vertical_scrollbar_change (_, state)
=>
state;
end;
# Adjust scrollbars in response to non-scrollbar
# changes such as window resizing:
#
fun move_scrollbar_thumbs ( { horizontal=>gv::VIEWDIM hz, vertical=>gv::VIEWDIM vt }, (h, v))
=
{
fun change (scrollbar, { min, size, total }: Vport)
=
{ total = float total;
#
sb::set_scrollbar_thumb
#
scrollbar
#
{ size => THE ((f8b::from_int size) / total),
top => THE ((f8b::from_int min ) / total)
};
};
if (hz != h) change (horizontal_scrollbar, hz); fi;
if (vt != v) change (vertical_scrollbar, vt); fi;
(hz, vt);
};
fun loop state
=
loop (
#
do_one_mailop [
#
move_scrollbar_thumbs_mailop
==>
(\\ e = move_scrollbar_thumbs (e, state)), # Update scrollbars to reflect (e.g.) window resizing.
horizontal_scrollbar_change'
==>
(\\ e = do_horizontal_scrollbar_change (e, state)), # User drag of scrollbar thumb.
vertical_scrollbar_change'
==>
(\\ e = do_vertical_scrollbar_change (e, state)) # User drag of scrollbar thumb.
]
);
xtr::make_thread "scrollable_graphviz_widget" {.
#
loop initstate;
};
SCROLLABLE_GRAPHVIZ_WIDGET {
graphviz_widget,
widget => lw::as_widget widget
};
};
fun as_widget (SCROLLABLE_GRAPHVIZ_WIDGET { widget, ... } )
=
widget;
}; # package scrollable_graphviz_widget
end;