# Transform sequential cell operations to programmatic workflow

Let's say I have a workflow that involves importing images and turning them into an animated gif.

Here's how I currently have it setup:

Import Images:

imports = {};
importimages[] := Module[{a},
If[ListQ[a], Table[Import[a[[i]]], {i, 1, Length[a]}], Import[a]]]
imports = Flatten[Append[imports, importimages[]]]


Allow for selection and rearranging:

sels = Range[Length[imports]];
CheckboxBar[Dynamic[sels], Table[i -> imports[[i]], {i, 1, Length[imports]}]]
imgs = Dynamic[imports[[sels]]]


Set animation rate and preview:

Manipulate[
displayrate = 1/rate;
ListAnimate[Setting[imgs], AnimationRate -> rate, AnimationRunning -> False],
{{rate, 1}, 0, 10, 0.1, LocalizeVariables -> False}]


Export to gif:

Export["~//Desktop//test.gif", Setting[imgs], "DisplayDurations" -> displayrate]


(By the way, feel free to improve code.)

My question is, what is the best way I can smoothly and dynamically wrap this entire workflow into a graphical program where if I were to put a non-Mathematica user in front of it, he/she can easily work it?

This question mainly stems from my poor understanding of the dynamic constructs and roots in action-based programming. The gif routine is just an example for future implementations that involve concise sequential steps.

Here's something I made. The best part is the sound effects. LOL.

My goal here is just to show some of the stuff you can do. If you click on 2 pictures it will swap their positions. If you right-click on a picture it will be removed. I didn't implement the animation/export stuff but I think something along the lines of this is a good approach. And in terms of sequential operations, I think the real answer to your question is the Buttons I'm using.

swap = {};
images = {};

combobulate[img_Image, index_] := DynamicModule[{color = White},
EventHandler[
Panel[img, ImageSize -> {80, {80}}, Alignment -> Center, Background -> Dynamic[color]],
{{"MouseClicked", 1} :> (
Switch[Length[swap],
0, color = Lighter@Purple; swap = {index},
1, If[swap[[1]] == index,
color = White; swap = {},
images[[{swap[[1]], index}]] = images[[{index, swap[[1]]}]];
EmitSound[Sound[SoundNote[12]]];
swap = {}]]),
{"MouseClicked", 2} :> (
swap = {};
Speak["deleted"];
images = Delete[images, index];
)}]
];

Column@{
Panel[Row@{
images = Join[images, Cases[

One thing to note about how the image panel updates: When 2 images have been clicked on, those images have their positions swapped in the base images list. The Dynamic on the last line detects this change in images, and so it re-does the combobulate on all the images. This has the effect of reallocating the indices, so we don't have to worry about keeping track of them. We just shuffle things around however we want and it all gets refreshed.
• Ha. Speak["deleted"]. I'll accept just for this alone. Thanks for the help. – kale Sep 30 '12 at 0:49