Set the fill of a note to an external image

If I use inline images (copied to the TB file) opening the container takes a while.

While a large image would make the file larger and might make it open more slowly, I’m skeptical that it would have any effect on the time needed to zoom into the container. Are you sure?

Oh - yes - I have a container with around 50 authors - each one with a small image and it takes several seconds to open the map view of the container. I have containers with many text only notes and they open much faster. This is no big issue for me - I try to avoid images or the switch to an external image. For the export it seems to be the better way to go too - I’m still not using the export feature but trying to find my way to curate (how Michael would call it) my notes with TB. It’s fun to discover all the hidden gems of TB :wink:

Oh – the destination has multiple images.

I’d not thought of that. Each of this images has to be unpacked and scaled to draw the map; that could be quite a bit of work.

but is there a way to show an external image in the map?

I’d ask “but why are you doing this”? If you look at these notes on $File you’ll see it simply links to a file. If viewed in Displayed Attributes or Get Info:attributes/General you see a folder icon. If clicked, Tinderbox asks macOS finder [sic] to open that file with the associated app.

In contrast, you want the Fill attribute to use a file path. But, had you looked at details of $Fill
you wouls see it is a String-data-type attribute. Clearly the tw are not the same! :slight_smile:

My last is not meant as a snarky comment. Rather, I’m truly confused as to why one would think the above method would work.

At present, Fill attribute can only use files in the app support ‘fill’ folder. I think changes are in hand (I write as at v9.0.0_) to allow macOS aliases placed there.

Either way, you can have a calculated $Fill value but the file targetted needs to be in the right place.

So for now set $Fill, noting that you can use action (not export) code to set the value of $Fill.

Yes; if you add the image to the Fill subfolder of the Tinderbox support folder, it will be available as a fill image just like the built-in fill textures such as Linen.

BTW, I do this all the time.

Personally, I don’t like story primary files in the applications fill directory. Also, for $Fill to work you can’t have the extension on the file name. And, for Hover to work you need the extension.

So, here is what I do.

I have an attribute $MediaFIleName. This is where the primary file name goes.

I have a TBXConfig note where I store my paths to my fiels.

I use Hazel. When I add a picture to my people or logo directory I have Haze move a copy to the TBX $Fill directory.

I then use a $Edict to populate the $Fill and $Hover attributes.

$Fill=$PathFIllLogo("TBXConfig")+$MediaFileName.replace("\.\w+$",""); 
$HoverImage=$PathHover("TBXConfig")+$PathFIllLogo("TBXConfig")+$MediaFileName;`

The result:
image

2 Likes

Easy to explain: I would like to use Markup to include an external image. I don’t want to manually copy the path in the Finder and paste it into the note. So I simply use the $File attribute. With an empty $File attribute I can click in the folder icon and select a file. The result is a string with the path to this file and this value is what I use in the markup. Very easy to integrate an external image that way. No need to copy&paste the path.

Now I expected that the path I got from the $File attribute could be used in the $Fill attribute too. Both attributes use strings. The limitation here is the special “fill” folder.

@satikusala that’s a nice approach. Will try this too. Did you compare the speed if you have a container with many notes containing an image as fill pattern to a collection of notes using inline images?

3 Likes

@satikusala I just tested the performance: the external $Fill images are much faster. I tested with a folder containing 40 notes each with an image. With inline images opening the folder takes several seconds, with the external images the folder opens in less then a second (map view). Great. That’s the way I will go.

I don’t understand why you store the path to the files? Since $Fill needs the name of the image file only (without the extension). No path needed here - or did I miss something (“Jacques_Derrida” works - no need for “/Users/sampleuser/Library/Application Support/Tinderbox/fill/acques_Derrida”)?!

And I still like to use $File as my transport media for the file name :wink:

Great. Glad it works for you.

I have a sub-folder in $Fill for people and a second one for Logos, i.e. for hover. The path for people points to people, and to get Hover to work I find the full path is the most reliable.

Hi @webline, thanks for your note. I’ve found that format and size matter. You need png or jpeg. Also, if the file is too large it won’t display. I don’t know what the limits are.

It’s getting even more “special” here - sorry. I just try to understand some concepts of TBX and use them for my work.
The external path for $Fill works fine now. The next thing I’m trying to solve: after I change the $File attribute I would like to update the $Fill attribute with the name of the file.

This stamp “SetFillImageFromFile” will do it:

stamp("GetFileNameOnly");
stamp("GetFileNameNoExtension");
$Fill(original)="";
$Fill(original)=$PathFillImages("pPreferences")+$ImageName(original);
$FileIsModified=false;

The first two stamps just strip the path and the type ending from the value stored in $File.
The line with $Fill(original)=""; is there because of my new issue I run into.

First step was an $Edict with:

if(!$IsPrototype){stamp("SetFillImageFromFile")}

This worked but it seems to me that this will add some overhead to my file. I want to apply the stamp only once if the value of $File has changed. It got even worse when using it as a $Rule.

So I created a new attribute called $FileIsModified and an agent with this query:

$Prototype=="pPerson" & $File=="" & $FileIsModified==false

and a simple $AgentAction: $FileIsModified=true;

Works fine - there is a delay because the Agent will not run immediately. But that’s not my problem now.

Then I created a second Agent with this query:

$Prototype=="pPerson" & $File!="" & $FileIsModified==true

and the Action:

stamp("SetFillImageFromFile");$FileIsModified=false;

Now - after so many words :wink: - here is my problem: everything works. Only the $Fill attribute never gets set to the new value. The other three attributes will be set, but not $Fill. If I apply the stamp manually to the note all attributes were set including $Fill.

Any idea? All I need is a way to simulate an “OnChange” event for the $Fill attribute.

Is there a demo file for this? I see all the code, but running it my head, I’m getting lost. :slight_smile:

One way to resolve your confusion re images is to look at this section of aTbRef, re support folders—it’s a quick read to scan through>. You will note that storage for only two forms of image use are indicated: fills and badges.

I’m not sure why these are internal and others are external; that’s a question for Eastgate but I’d hazard that easy re-use across many docs and possibly efficiency may be factors.

I do think that while, especially to old Mac users, in 2001 using filenames with no file extension would have not been confusing, in 2021 the position is reversed. This will be especially true for those not from a programming background. For a process to fail due to provision of a file extension for a file asset ( given the extension can easily be detected and parsed out), I sense a change is due here.

Another reflection of incremental app improvement over the years is that I don’t think there is documentation of what Tinderbox process can use image data, how they are specified and any format restrictions. Perhaps it is time to add this to Help along with a list of Application Support folders (default and optional). A thought, anyway :slight_smile:

@mwra here is a demo file. I solved my problem with another flag. With this flag I trigger an $Edict that set the $Fill attribute. Seems to be some kind of racing condition with the $Fill…
To test my demo you need two folders with (small) image files. Both with the same images. One in the “fill” folder of TBX the other one (#2) anywhere on your Mac. Use the $File folder icon to select any file from the folder #2 and wait. The image of the note should update after the agents ran. Then clean the $File attribute (empty) wait until the agents run and the image should disappear.

PersonsExternalImages.tbx (96.8 KB)

P.S: create new notes in the persons folder. Add the $File to this note

1 Like

Doesn’t work for me and the app crashes if I try to open the Inspector. In fact every TBX now crashes. Loks like I’ll have to re-boot in order to get Tinderbox to work again, but unfortunately I can’t re-boot tonight as I’m in the middle of running some long data scripts (non-Tinderbox work).

Tinderbox still unstable (gremlin in your file but got it open again) What is the real-world actual problem we are trying to solve here? I still can’t figure it out.

Meanwhile, stamps are useful for testing things but I doubt they were intended to be called inlined in other actions. So I’ve fixed the action code to remove the inline stamp calls. I also noted that several notes have no title ($Name). See here: PersonsExternalImages-fix.tbx (101.8 KB)

Take a look at that and see if it works better (at least not crashing all the time!)

Also, although not mentioned, there seems to be an intent to use a ‘people’ sub-folder of fills. But I’m still too lost to make much more progress.

@mwra if have no crashes at all with the file. Never had!? There are some notes with old data - referring to the external images on my Mac. Maybe that’s the reason for the crashes? Here everything is rock solid. Sorry if the file gives you trouble with your Mac.

You didn’t get the idea behind my implementation (don’t have to be a bad thing…). If you put the code into an $Edict - it will run all the time updating the attributes over and over again and slowing down TBX. That’s the reason for my use of the agents. The way you did it was my first approach but it slows down the file.

I don’t want my code in one box - if I can’t define my own methods and reuse them → stamps are my way to go. If there is no other way to reuse the code - why not use stamps? They do work fine.

Yes - in the fill folder of TBX there is a sub-folder “people” with the images. And yes - it’s a file to test stuff so there are incomplete notes and other things not finished.

Your solution is incomplete. If you empty the $File attribute and then load a new file - the $Edict will not run because $NewImageLoad=false is still set.

using only code in the $Edict will do it too - like this:

if($File=="" & $FileIsModified==false) {
  $FileIsModified=true;
  $Fill="";
} else {
  if($File!="" & $FileIsModified==true) {
    $ImageFileName=$File.replace(".*\/(.+)","$1");
    $ImageName=$ImageFileName.replace("\.\w+$","");
    $Fill(original)=$PathFillImages("/pPreferences")+$ImageName;
    $FileIsModified=false;
    $NewImageLoad=true;
  } else {
    if($NewImageLoad) {
     $Fill(original)=$PathFillImages("/pPreferences")+$ImageName;
     $NewImageLoad=false;
    }
  }
}

Easier to maintain then using the two agents and the $Edict code. Will go this way.

even less code will do - the problem with the update of $Fill I had when using the agents is gone - so this does the job:

if($File=="" & $FileIsModified==false) {
  $FileIsModified=true;
  $Fill="";
} else {
  if($File!="" & $FileIsModified==true) {
    $ImageFileName=$File.replace(".*\/(.+)","$1");
    $ImageName=$ImageFileName.replace("\.\w+$","");
    $Fill(original)=$PathFillImages("/pPreferences")+$ImageName;
    $FileIsModified=false;
  }
}

PersonsExternalImages2.tbx (1.1 MB)