Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
class GRE_GROUP g_group =MainLayout.GetGroupByName("Group 1");
class GRDEVICE_MEM_RGB24 imgdev;
class GRDEVICE_MEM_BINARY maskdev;
class GC imagegc, maskgc;
class GRE_GROUP group;
proc OnLayoutLoadEnd (
class GRE_LAYOUT layout
) {
group = layout.GetGroupByName("ProvinceMaps");
g_group = group;
}
func OnViewDataTipShowRequest (
class GRE_VIEW view,
class POINT2D point, # Point in screen coordinates
class TOOLTIP datatip
) {
datatip.Delay = 500;
datatip.String = "";
local class GRE_LAYER layer = g_group.FirstLayer;
local class LABELPLACE place, places[];
local class GRE_LABELS labels;
local class POINT2D offset, delta, oldcenter, newpt, groupcenter, groupdelta, center;
local class REGION2D reg, groupreg;
local class RECT extents, groupextents, oldextents;
local numeric zoom = 2.0, q, angle, SolutionFound, dTheta;
local class POINT2D offsets[];
local class LABELATTACHMENT attachment;
local class POLYLINE leader;
local class COLOR foregroundcolor;
foregroundcolor.name = "red2";
offset.x = 10; # Offset so label doesn't fall under cursor
offset.y = 10;
imagegc = imgdev.CreateGC();
while (layer) {
labels = layer.GetLabels(view);
labels.GetItemAtLocation(point, place, 10);
reg = place.GetRegion();
places = labels.GetItemsOverlappingRegion(reg);
numeric number = places.GetNumItems();
if (number > 1) {
# Find the extents of the labels as they are on the screen
groupreg.Clear();
for q = 1 to number {
groupreg.UnionRegion(places[q].GetRegion());
}
groupextents = groupreg.Extents;
groupcenter = groupextents.center;
# Expand the extents so that our labels will be placed far enough
# out for their leader lines to look good
groupextents.Expand(10, 10);
# Compute zoomed extents so we know how big to make our window
# and decide where we'll place the labels while we're at it
reg.Clear();
for q = 1 to number {
place = places[q];
center = place.GetRegion().Extents.center;
angle = groupcenter.GetAngle(center);
# Remove the leaders so we don't try to zoom them
place.SetCopyOnWrite(1);
while (place.GetNumAttachments()) {
place.DeleteAttachment(place.GetAttachment(1).Element);
}
zoom = 30 / place.GetRegion().Extents.GetHeight();
if (zoom < 1.0) zoom = 1.0;
place.Zoom(zoom);
dTheta = 0;
SolutionFound = false;
while (!SolutionFound && dTheta < 360) {
# Move out from center until label no longer intersects
# the extents of the actual labels
delta.x = cos(angle);
delta.y = sin(angle);
extents = place.GetRegion().Extents;
offset.x = groupcenter.x - extents.center.x;
offset.y = groupcenter.y - extents.center.y;
extents += offset;
while (groupextents.Overlaps(extents)) {
offset += delta;
extents += delta;
}
# Make sure this label won't overlap another one. If it will,
# move 10 degrees around and try again. If we get all the
# way around the circle and still can't find a spot, give up.
SolutionFound = reg.TestRect(extents, "FullOutside");
if (!SolutionFound) {
dTheta += 10;
angle += 10 / deg;
}
}
offsets[q] = offset;
place.Move(offset);
reg.UnionRegion(place.GetRegion());
}
groupdelta.x = -reg.Extents.x1;
groupdelta.y = -reg.Extents.y1;
imgdev.Create(reg.Extents.GetHeight()+5,reg.Extents.GetWidth()+5);
imgdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
imgdev.Clear("white");
imagegc = imgdev.CreateGC();
imagegc.SetOutputScale(view.GetMapScale());
maskdev.Create(imgdev.GetHeight(),imgdev.GetWidth());
maskdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
maskdev.ClearAll();
maskgc = maskdev.CreateGC();
maskgc.SetOutputScale(view.GetMapScale());
maskgc.SetPixelFunction("Set");
for q = 1 to number {
place = places[q];
oldextents = place.GetRegion().Extents;
center = oldextents.center;
oldextents += groupdelta;
center += groupdelta;
place.SetCopyOnWrite(1);
# Remove the leaders so we don't try to zoom them
while (place.GetNumAttachments()) {
place.DeleteAttachment(place.GetAttachment(1).Element);
}
zoom = 30 / place.GetRegion().Extents.GetHeight();
if (zoom < 1.0) zoom = 1.0;
place.Zoom(zoom);
extents = place.GetRegion().Extents;
delta = offsets[q] + groupdelta;
extents += delta;
newpt = extents.center;
place.Move(delta);
leader.Clear();
leader.AppendVertex(center);
leader.AppendVertex(newpt);
attachment.Leader = leader;
place.AddAttachment(attachment);
# Draw the label to use as an image tip
place.DrawSample(imagegc, foregroundcolor);
# Draw again into a mask device
place.DrawSample(maskgc, foregroundcolor);
}
# Figure out where to place the tip
newpt.x = -groupdelta.x;
newpt.y = -groupdelta.y;
offset = newpt - point;
# Show the tip
datatip.SetImageTip(imgdev, maskdev, offset);
return (1);
}
else { # Single data tip case
place = places[1];
extents = place.GetRegion().Extents;
oldcenter = extents.center;
# Make sure we're modifying a COPY of the place, not the original
place.SetCopyOnWrite(1);
# Remove the leaders so we don't try to zoom them
while (place.GetNumAttachments()) {
place.DeleteAttachment(place.GetAttachment(1).Element);
}
zoom = 30 / place.GetRegion().Extents.GetHeight();# THIS IS CATCHING THE LABEL SIZE, IF IT IS SMALLER THAN 1, DON'T DO BELOW...
# Zoom it up. Maybe compute a zoom factor based on current size?
if (zoom > 1.2) {
place.Zoom(zoom);
# Get new extents
extents = place.GetRegion().Extents;
# Move the label to (0,0)
delta.x = -extents.x1;
delta.y = -extents.y1;
place.Move(delta);
# Draw the label to use as an image tip
imgdev.Create(extents.GetHeight()+2, extents.GetWidth()+2);
imgdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
imgdev.Clear("white");
imagegc = imgdev.CreateGC();
imagegc.SetOutputScale(view.GetMapScale());
place.DrawSample(imagegc,foregroundcolor);
# Draw again into a mask device
maskdev.Create(imgdev.GetHeight(),imgdev.GetWidth());
maskdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
maskdev.ClearAll();
maskgc = maskdev.CreateGC();
maskgc.SetOutputScale(view.GetMapScale());
maskgc.SetPixelFunction("Set");
place.DrawSample(maskgc, foregroundcolor);
# Figure out where to place the tip
newpt.x = oldcenter.x - imgdev.GetWidth() / 2;
newpt.y = oldcenter.y - imgdev.GetHeight() / 2;
offset = newpt - point;
# Show the tip
datatip.SetImageTip(imgdev, maskdev, offset);
return (1);
}
}
layer = layer.NextLayer;
}
return (0);
}
proc OnViewDataTipHidden (
class GRE_VIEW view
) {
# Insert code here
}