i'm trying to build an experimental application to browse a hypertext
space. it's an unusual approach so before i ask a Tk specific question
please let me explain some details of what i want to achieve.
the idea is to have pages with text and links (like the
wikipedia). the text is structurized - among the others it has
sections, subsections, paragraphs etc. what i want to achieve is to
zoom_in/zoom_out (using mouse roll) on the text so more specific
description (e.g. subsections of section) appear or hide. it means
that the text can expand and shrink. secondly user can click on any
link to choose it. after that new small area (window) should appear in
the position of the choosen link. inside this area i will put
information pointed by the link - e.g. description of new
concept, starting with short description. further zooming in/out
should concern new area (window). it should grow taking more and more
place so more and more information could be put (subsections,
paragraphs, etc.). during the growth the previous text from where the
link was choosen should also be shown. its content should shrink and
disappear slowly as new area (window) grows.
at a time there can be more than 1 or 2 windows beceuse user could
e.g. pick another link in newly created area an proceed to it.
i want to build it to ease the exploration of big hypertext spaces
like wikipedia; to present more detailed information if requested
(zooming); to faster navigate and search for the information etc.
so to summarize:
- shrink/expand text by scrolling a mouse roll
- new areas (windows) which can grow and shrink and contain some text
- old text disappear (e.g. fade out (color changing), or transparency)
i was wondering what widgets (approach) to choose in Tk to achive
above. i thought of using frames with textareas, splitting them when
new link is choosen and insert new frame with textarea in the
middle. when the user is zooming in i could expand inner frame, put
there more and more text and smaller the outer one. color of the new
and old text could be manipulated to achieve smoothness.
i was also thinking about using TkZinc beceuse of nice feature of
transparency but i don't know if there is any nice textarea which
could limit inserted text.
if you have any ideas, suggestions or whatever what could be helpful
please answer. sorry for long post but it's hard for me to explain it
shortly. if any example figures could help, please let me know.
best regards,
ks
>i was also thinking about using TkZinc beceuse of nice feature of
>transparency but i don't know if there is any nice textarea which
>could limit inserted text.
Zinc is the way to go. It supports transparency (plain Tk::Canvas
dosn't). Animated zooming would be fairly easy to accomplish.
Look at the "magic lens" in the 'zinc-demos' program.
--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
>On Fri, 04 Aug 2006 16:07:55 +0100, ks <ksamp@vp_removeit_.pl> wrote:
>
>
>>i was also thinking about using TkZinc beceuse of nice feature of
>>transparency but i don't know if there is any nice textarea which
>>could limit inserted text.
>
>Zinc is the way to go. It supports transparency (plain Tk::Canvas
>dosn't). Animated zooming would be fairly easy to accomplish.
>
>Look at the "magic lens" in the 'zinc-demos' program.
thank you for the link. it is really cool and partially what i'm
looking to achieve. i didn't explain it well but zooming in and out
aside from enlarging/shrinking the bounding box also add/remove some
text (and this is the main idea). i'm not focusing on enlarging a font
(maybe a little to enrich the user experience) but enlarging the
description. i want to show the user a simple description at the
beginning (e.g. about a particular concept) and further zooming in
would enlarge the bounding area for it and add new more detailed
information, links, etc. i'm mainly considering the ways to create and
manipulate such bounding areas for text. transparency, enlarging the
font etc. are just nice additional features. is there a way in
tkzinc/canvas to create a scalable boudings for a text? i know
how much text i want to display at a time - i have to create a space
for it and add additional features like transparency etc. maybe you
have further thoughts which could be helpful? thanks for all in
advance.
best regards,
ks
>On Sat, 05 Aug 2006 12:21:40 GMT, zentara <zen...@highstream.net>
>wrote:
>>Zinc is the way to go. It supports transparency (plain Tk::Canvas
>>dosn't). Animated zooming would be fairly easy to accomplish.
>>
>>Look at the "magic lens" in the 'zinc-demos' program.
>
>thank you for the link. it is really cool and partially what i'm
>looking to achieve. i didn't explain it well but zooming in and out
>aside from enlarging/shrinking the bounding box also add/remove some
>text (and this is the main idea). i'm not focusing on enlarging a font
>(maybe a little to enrich the user experience) but enlarging the
>description. i want to show the user a simple description at the
>beginning (e.g. about a particular concept) and further zooming in
>would enlarge the bounding area for it and add new more detailed
>information, links, etc. i'm mainly considering the ways to create and
>manipulate such bounding areas for text. transparency, enlarging the
>font etc. are just nice additional features. is there a way in
>tkzinc/canvas to create a scalable boudings for a text? i know
>how much text i want to display at a time - i have to create a space
>for it and add additional features like transparency etc. maybe you
>have further thoughts which could be helpful? thanks for all in
>advance.
>
>best regards,
>ks
Well, it is hard to say exactly what you should do, since you give
just a broad outline of your design.
But in general, zooming is done by scaling groups or tags, which depends
on how you set up your first page.
As to your main question, on how to create bounding areas for text, you
seem to have a few choices, use groups, tags, or a combo of both.
My first idea:
Create a group for each text group, and maybe make a bounding rectangle
for it. Then add text to the group, and have each text addition tagged
with a zoom level. Then setup click bindings on each group, so the first
click will zoom all group members with a level1-zoom tag, a second click
will zoom all level2-zoom tags, etc.
Of course this will take some planning, maybe it would be better to just
assign a number, like 3 as a tag, and that will zoom everything less
than 4. And you will also have the problem, of not zooming
level-1-zooms twice, when you second click.
Here is a very rudimentary proof of concept. Some caveats:
Sometimes Zinc will demand actual objects to work on, instead of tags.
Don't get frustrated, just find a way. This can be seen where I have to
bind to the rectangle and the text, instead of just the common tag.
Text will not scale well, you will need to adjust fonts.
Also, due to inherent inaccuracies, you cannot get back to your original
position with calculated moves. So you must store your positions and
tset them back.
In this example, multiple left clicks will scale and move a box, and a
right click will restore them. If you want animation, use a sub to do it
in small automatic steps.
All the above, just requires alot of detailed hacking, so I will leave
it up to you.
The docs for Zinc are pretty good, so refer to them in case you hit a
snag.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::Zinc;
my %zgroup;
my $dx = 50; #
my $dy = 50; #the boxlet size
my ($up,$left)=(0,0);
my @colors = qw(DarkGrey orange pink hotpink red
peru goldenrod tan gold wheat
lightyellow yellow khaki lightgreen green
lightsteelblue turquoise cyan violet plum
skyblue powderblue bisque beige snow );
my $mw = MainWindow->new;
$mw->geometry('+30+30');
my $width = $mw->screenwidth() - 100;
my $height = $mw->screenheight() - 100;
my $zinc = $mw->Scrolled('Zinc', -width => $width, -height => $height -
100,
-backcolor => 'black',
-borderwidth => 3,
-relief => 'sunken',
-scrollregion => [-10, -10, 10000, 10000],
)->pack(-fill=>'both',-expand=> 1 );
for(0..scalar @colors){
setup_groups($_ + 1);
}
&fill_groups();
MainLoop;
#####################################################################
sub setup_groups{
my $z = shift;
print "$z\t";
#set color
push (@colors,shift(@colors)); #rotate colors
$zgroup{$z}{'color'} = $colors[0];
$zgroup{$z}{'group'} = $zinc->add('group', 1 ,
-visible => 1,
-tags => [$z],
);
$zinc->translate($zgroup{$z}{'group'}, 30*$z,30*$z);
#save initial matrix settings for resetting position, compatible with
tset
$zgroup{$z}{'init'} = $zinc->tget( $zgroup{$z}{'group'} );
}
#######################################
sub fill_groups{
foreach my $z (sort keys %zgroup){
$zgroup{$z}{'rect'} = $zinc->add('rectangle',
$zgroup{$z}{'group'},
[ 0 , 0 , $dx , $dy],
-linewidth => 2,
-visible => 1,
-filled => 1,
-fillcolor => $zgroup{$z}{'color'},
-tags =>[$z],
);
$zgroup{$z}{'text'} = $zinc->add('text', $zgroup{$z}{'group'},
-position => [$dx/2, $dy/2],
-anchor => 'center',
-text => $z,
-tags =>[$z],
);
$zinc->bind( $zgroup{$z}{'rect'},'<Button-1>',
sub {
print "group-> $z\n";
&scale_group($z);
}
);
$zinc->bind( $zgroup{$z}{'text'} ,'<Button-1>',
sub {
print "group-> $z\n";
&scale_group($z);
}
);
$zinc->bind( $zgroup{$z}{'rect'},'<Button-3>',
sub {
print "group-> $z\n";
&descale_group($z);
}
);
$zinc->bind( $zgroup{$z}{'text'} ,'<Button-3>',
sub {
print "group-> $z\n";
&descale_group($z);
}
);
}
}
sub scale_group{
my $z =shift;
my @pos = $zinc->coords( $zgroup{$z}{'group'} );
print "@pos\n";
# Now, we apply scale transformation to the Group item, using the
'scale'
# Zinc method. Note that we reset group coords before scaling it, in
order
# that the origin of the transformation corresponds to the center of
the
# wheel. When scale is done, we restore previous coords of group.
$zinc->translate($zgroup{$z}{'group'}, 20, -20);
$zinc->scale($zgroup{$z}{'group'}, 1.2, 1.2, $pos[0],$pos[1]);
# text will not scale, you need to configure large and small fonts
# $zinc->scale($zgroup{$z}{'text'}, 1.2, 1.2, $pos[0],$pos[1]);
}
sub descale_group{
my $z =shift;
# descaling dosn't work, you need to do a reset to original position
# my @pos = $zinc->coords( $zgroup{$z}{'group'} );
# $zinc->translate($zgroup{$z}{'group'}, -20, 20);
# $zinc->scale($zgroup{$z}{'group'}, .8, .8, $pos[0],$pos[1]);
$zinc->tset($zgroup{$z}{'group'}, @{ $zgroup{$z}{'init'} } );
}
__END__
> i'm mainly considering the ways to create and
>manipulate such bounding areas for text. transparency, enlarging the
>font etc. are just nice additional features. is there a way in
>tkzinc/canvas to create a scalable boudings for a text? i know
>how much text i want to display at a time - i have to create a space
>for it and add additional features like transparency etc. maybe you
>have further thoughts which could be helpful? thanks for all in
>advance.
As an after thought, you could use a mouse drag to create a rectangle
anywhere on the Zinc canvas. Then find all tagged elements within that
bounding rectangle, add them to a special group, and scale them up.
thanks a lot for your help. it gave me some inspirations. now i will
experiment with different approaches and see if i can come up with
something useful.
best regards
ks