News:

Happy New Year!

Main Menu

Have You Considered a Criminal Career?

Started by Yacine, January 13, 2025, 11:35:32 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yacine

In these times of high inflation and financial uncertainty, you might be thinking, "Why not kidnap someone?" Sure, it's a bold move, but you'll need a ransom letter that looks straight out of a Hollywood movie—mismatched fonts, chaotic design, the works.
But forget scissors and glue; this is the digital age. Enter the Ransom Letter SmartShape that will bring your cinematic ransom note dreams to life in Visio.


The Ransom Letter SmartShape
This ingenious shape automatically generates a ransom note-style message with randomly styled letters. Here's how it works:
  • Type your message into the parent shape, and the SmartShape takes over, splitting the text into individual characters.
  • Each character appears as a sub-shape with a random font, random size, and colorful background, giving you that authentic chaotic ransom note vibe.
  • The magic lies in the sub-shapes:
    • Every sub-shape is assigned a unique instance number using the custom property Prop.Nr. The clever trick here is that all the logic resides in the first instance, and duplicating the sub-shape automatically increments Prop.Nr via the EventDrop formula.
    • With Prop.Nr, the possibilities are endless:
      • Extract the corresponding character from the parent's text using: MID(SHAPETEXT(TheParent!TheText), Prop.Nr, 1)
      • Calculate the position dynamically. Heads up: Normally, you can use the instance number for simple layouts, but ransom letters are tricky. Since characters vary in width, I used a macro to calculate the precise position of each preceding character.


Have Fun With It!
Play around with the Ransom Letter SmartShape. Explore its custom properties, tweak the styles, and create your own masterpiece. It's fun, functional, and downright chaotic.

You cannot view this attachment.
You cannot view this attachment.

But Wait, There's More
Here's the twist: randomly picking fonts isn't as easy as it sounds. Sure, you could use RAND() to choose from all installed fonts, but here's the problem:
  • Some fonts (like barcodes or Wingdings) don't display readable letters.
  • The result? Your ransom letter ends up looking more like an escape room puzzle than a coherent demand.
To solve this, I developed a Font Selection SmartShape, which I'll introduce in the next post. Stay tuned for part two, where I explain how to curate a perfect list of fonts for your project!


Yacine

Yacine

#1
Font Selection Made Easy: The Font Selector SmartShape
Choosing a font by generating a random integer isn't quite clever enough. Why? Because not all fonts are created equal. Some don't print readable characters—they display pictures, barcodes, or other unhelpful symbols instead.
To make things worse, the fonts installed on your machine can vary from one computer to another, and so can their order and total number.
So, how do you pick the right ones? Enter the Font Selector SmartShape, your new best friend for curating a perfect font list.


How It Works
This clever shape helps you browse and select the fonts you actually want to use:
  • Preview Fonts in Rows:
    The shape displays as many text boxes (rows) as you've defined in Prop.NumRows. Each row contains a pangram or sample text.
  • Dynamic Font Assignment:
    Each text box is assigned a font based on its row number and the current range (User.Range).
    The range is controlled by a slider (a control point) at the bottom of the parent shape, allowing you to "scan" through sections of your font collection.
  • Select and Add Fonts to the List:
    When you spot a font you like, sub-select the row, right-click, and use the "Add to Fonts List" action. This adds the font's index number to Prop.FontsList in the parent shape.
  • Export and Use the List:
    Once you've curated your font list, simply copy it into the FontsList
     field of the Ransom Letter SmartShape™.


Have Fun With It!
Explore the Font Selector SmartShape to build your own customized font library. Say goodbye to unreadable fonts and hello to the ransom note of your dreams.


And Remember...
Keep it fun and creative! Let's hope the next woman you give a ride to is your model girlfriend—not the wife of a random rich guy. 😄

You cannot view this attachment.

You cannot view this attachment.
Yacine

Yacine

#2
Pangrams: A New Discovery (For Me, at Least)
So, here's the thing—I didn't know much about pangrams until AI pointed them out to me. Turns out, they're pretty cool and come in handy when testing fonts. Who knew?
What's even more fascinating is that there are loads of different pangrams out there, tailored to different languages. Some are well-known, like the classic "The quick brown fox jumps over the lazy dog" in English, which uses every letter of the alphabet. Others are like hidden gems, unique to specific languages:
  • In German: "Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."
  • In French: "Portez ce vieux whisky au juge blond qui fume."
  • In Spanish: "El veloz murciélago hindú comía feliz cardillo y kiwi."
  • In Italian: "Quel vituperabile xenofobo zelante osava difendere gli squallidi accampamenti abusivi."
Apparently, people have been creating these pangram sentences just for the joy of including every letter.

What Did I Do?
I've included some of the more common anagrams in the Font Selector SmartShape, but it's just the tip of the iceberg. If you want to explore, there are plenty more to discover in other languages, too. Why stop at English, German, French, or Spanish? I've heard there are even pangrams in Klingon! (Okay, maybe I made that up. But who's checking?)

Your Turn to Explore
So, give it a try—pick your favorite language, type out an anagram, and see how your fonts handle it. Who knows? You might stumble across a pangram masterpiece that no one's ever thought of before.
Or at the very least, you'll get a laugh testing fonts with sentences like, "Victor jagt zwölf Boxkämpfer..." while pretending you're a secret agent from Sylter Deich.

Yacine

Yacine

Yacine

wapperdude

👀 😵😲. Initial read of title almost resulted in deletion.  Saved by virtue of the OP. 
Visio 2019 Pro

Paul Herber

All I can think of is Mmmmm, pizza.
Wonderful. Brilliant. I'll hang up my hat.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

wapperdude

#6
I tried to different  notes.  Both have the same fonts selected.  What I found was that it's not obvious which fonts the program is actually using from the list.  Visually, it doesn't seem sufficiently random.  Also, resetting the list of fonts to have a clean slate, and then adding would be nice easy button to have.

Without blinking, the zoo keeper used feathered quills dipped into various viles of ink, jotting down brilliant platitudes.
You cannot view this attachment.

Yielding zero success, the wretched rusted bolt refused to turn, vanquishing all  positive hopes of quickly removing the jammed nut.
You cannot view this attachment.
Visio 2019 Pro

wapperdude

#7
Played around a bit more. 
1) Don't know if I mucked things up by manually clearing the list in the ShapeData Window, but could no longer add fonts to the list.  It stayed unchanged with the singular entry I had left.
2) I could add the numbers manually.  However, there does seem to be a max limit.  Did I fail to catch that?
3) The slider intent is a good idea, but it doesn't allow for enough entries...I have a lot of possible fonts.
4) The shapes that hold the font samples, well, don't.  Generally, could tell any difference from shape to shape.  I added simple shape, opened it's shapesheet.  Selected font I wanted and found the number for it from shape sheet.  That's what I entered into the list.
5) The problem with the slider is that you must reselect the group shape after each individual shape selected to add font to list.  Plus, it needs to be offset, below the shape.

Anyway, pretty clever overall.  Once I had my desired fonts selected...not shown above, lot of development thought and work.  Kudos!!!

Here's updated with new font list:

You cannot view this attachment.
Visio 2019 Pro

Yacine

#8
Thanks for the review. I appreciate your effort.

I will not put more work in the ransom letter - it is fine enough as exercise on how to split a string into individual letters.

The font selector however is probably worth investing some time - as UI exercise, similar to the controls Chris developed for his calendar shape (https://www.visguy.com/2025/01/06/monthly-planner-calendar-2025/).

I'll come back on that.
Yacine

Thomas Winkel

Looks great much fun 😂
But on my notebook the document takes minutes to load.

Yacine

#10
Continuation of the Ransom Letter Post: Solving the Font Selector Issues

This post builds on the previous ransom letter post, specifically addressing the font selector that had two significant flaws:
  • The selection mechanism for the displayed font range, which relied on a control point at the bottom of the main shape.
  • Adding a font proved overly complicated because you had to sub-select the font shape.

The Idea: A Rotary Dial Control for Number Selection
For the first issue — smoothly selecting a number with a UI element — I wanted something similar to a scrollbar or spin button but suitable for "endless ranges".
An endless rotary dial control seemed like the perfect solution.

Step 1: Handling the Angle and Detecting Zero Crossings
To achieve this, I needed to address a key challenge: handling angle overflow. When you pass the 0° mark, the default behavior is for the angle to jump back to 0°. That's no good for our rotary control.

First, I normalized the angle to range from 0° to 360° clockwise:

User.angle = IF(Angle <= 0, -Angle, 360 deg - Angle)
Next, I needed to detect when the shape passes the 0° value, either clockwise (CW) or counterclockwise (CCW).
When this happens, the angle "jumps" between high (e.g., 300°) and low values (e.g., 10°). To handle this, I stored the previous angle and compared it to the current angle.

In simple terms:

IF delta_angle > big_angle THEN
  // Passed zero CCW
ELSE
  IF delta_angle < -big_angle THEN
      // Passed zero CW
  ELSE
      // No action


Step 2: Storing Rotations and Calculating the Final Value
Instead of directly incrementing or decrementing the angle, I introduced a rotation counter (User.rot). This made it easier to handle zero crossings.

User.update = IF(
  (User.angle - User.prevAngle) < -User.bigDiff,
  SETF(GetRef(User.Rot), User.Rot + 1),
  IF(
      (User.angle - User.prevAngle) > User.bigDiff,
      SETF(GetRef(User.Rot), User.Rot - 1),
      0
  )
) + SETF(GetRef(User.prevAngle), User.angle)

The final angle calculation then becomes:

User.finalAngle = User.rot * 360 deg + User.angle

Making It Reusable: A Generic Rotary Dial Control
This is where things get interesting. Instead of baking all the logic into one specific smart shape, I thought: What if the rotary dial control could be an independent, reusable element? It would work as a modular control that writes values into other shapes dynamically.

The idea:

  • Use SETF and GETREF to write values into a target shape.
  • Dynamically determine the target shape ID and property to write into.


The Challenge: Linking to a Target Shape
To link the rotary control to a target shape, we need a way to provide the ID of the target shape. There are a few options:

  • Manually input the target ID: This is feasible but not user-friendly.
  • Use VBA to select the target: Better, but it requires macros to be available (e.g., in the stencil or document).
  • Borrow functionality from smart callouts:
    This is where things get fun. You've likely seen those smart callout shapes with the yellow star. When you glue their control point to another shape, they trigger a dialog that lets you pick a property from the target shape. These callouts must be using some automation to determine the ID of the target shape they're glued to.

You cannot view this attachment.  You cannot view this attachment.

The Magic Formula: Borrowing Callout Logic
Inspecting the ShapeSheet of a smart callout reveals this critical line of code:

=DEPENDSON(Controls.Row_1, Controls.Row_1.Y) + RUNADDONWARGS("cc", "/cmd=2")

Here's what it does:

  • Controls.Row_1: Represents the control point that can be glued to another shape.
  • RUNADDONWARGS("cc", "/cmd=2"): Triggers Visio's Configure Callout add-on.

When you include this line in your own shape and glue the control point to a target shape, Visio automatically adds new rows to your ShapeSheet, including:

  • User.ccParentName: The name of the target shape.
  • User.ccReportOn: The property of the target shape you want to interact with.



Writing Values to the Target Shape
Now that we have the target shape's name (User.ccParentName) and property (User.ccReportOn), we can dynamically build a formula to write values into the target shape.

For example:

User.setF2 = SETF(GetRef(Sheet.5!Prop.start), Prop.value)

But we want to build this formula dynamically at runtime, like so:

User.setF1 = DEPENDSON(User.ccParentName, User.ccReportOn) +
  SETF(
      GetRef(User.setF2),
      "SETF(GetRef(" & User.ccParentName & "!" & User.ccReportOn & "), Prop.value)"
  )


The Result: A Reusable Rotary Dial Control
With this setup, you now have a modular rotary dial control that can write values into any number property of any shape. The same principle can be extended to create other types of controls, such as:

  • Text editors
  • Dropdown lists
  • Color pickers
Let your imagination run wild—the sky's the limit!

What's Next?
While this solves the rotary dial problem, I'm still thinking about how to make the font selection more intuitive without requiring sub-selection. Any ideas? Let me know what you think!

Yacine

Yacine

#11
The font selector controlled by the rotary dial control:

You cannot view this attachment.
Yacine

Browser ID: smf (possibly_robot)
Templates: 4: index (default), Display (default), GenericControls (default), GenericControls (default).
Sub templates: 6: init, html_above, body_above, main, body_below, html_below.
Language files: 4: index+Modifications.english (default), Post.english (default), Editor.english (default), Drafts.english (default).
Style sheets: 4: index.css, attachments.css, jquery.sceditor.css, responsive.css.
Hooks called: 676 (show)
Files included: 33 - 1308KB. (show)
Memory used: 1292KB.
Tokens: post-login.
Cache hits: 16: 0.00375s for 26,612 bytes (show)
Cache misses: 5: (show)
Queries used: 17.

[Show Queries]