[ctb] view rocker - cycle views

Discuss and share scripts and script files...
bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

[ctb] view rocker - cycle views

Post by bdeshi »

Here's a simple CTB script to cycle among two or more view modes. By default it toggles between Details and Thumbnails View.

The script takes care of all aspects of the ctb: icon, caption, left and right click actions.
Save it as, say, <xyscripts>\_ctb\viewrocker.xys; then just enter ::load "<xyscripts>\_ctb\viewrocker.xys",,'f'; // adjust path as both left- and right-click script of the ctb, and you're done.
The variable $view_cycle or the permanent $P_VIEWROCKER_VIEW_TABLE is the list of views this script will cycle among.

Code: Select all

/* viewrocker.xys
** ctb script to cycle a set of viewmodes.
** set *both* left- & right-click script of a ctb as below, done.
**   ::load "<xyscripts>\_ctb\viewrocker.xys",,'f'; // adjust path
*/

"_Initialize"

  global $view_table, $view_cycle;
  //$view_cycle: /-separated get(view) id of views to cycle among
  if !(isset($P_VIEWROCKER_VIEW_CYCLE)) {
    $view_cycle = '0/4'; // details/thumbs#1
  } else {
    $view_cycle = $P_VIEWROCKER_VIEW_CYCLE;
  }
  // $view_table: <get('view')>|<view cmdID>[|<view icon>[|...]]
  if !(isset($P_VIEWROCKER_VIEW_TABLE)) {
    $view_table = <<<#>>
      0|302|:viewdetails|Details
      1|303|:viewdetails|Details with Thumbnails#1
      2|304|:viewlist|List
      3|305|:views|Small Icons
      4|306|:viewthumbs|Thumbnails #1
      5|307|:viewthumbs|Thumbnails #2
      6|308|:viewthumbs|Thumbnails #3
      7|309|:views|Large Icons
      8|313|:views|Small Tiles
      9|314|:views|Large Tiles
    #>>;
  } else {
    $view_table = $P_VIEWROCKER_VIEW_TABLE;
  }

  // icon and caption
  $ico = ':views';
  $cap = "LClick: Cycle View ($hooked_views)<crlf>RClick:Views Menu";
  $lc  = '_lclick'; // left-click   script label(s) ;-separated
  $rc  = '_rclick'; // rights-click script label(s) ;-separated

  if !(ctbicon()) { ctbicon($ico); }
  if !(ctbname()) { ctbname($cap); }
  if     (get('trigger') == 1) { load '*', $lc, 's'; }
  elseif (get('trigger') == 2) { load '*', $rc, 's'; }

"default" eval(); // avoids "does not contain any visible scripts."

/* == LCLICK ======================================================== */
"lclick|icon : _lclick"
  global $view_table, $view_cycle;
  $view_id = get('view');
  $index = gettokenindex($view_id, $view_cycle, '/');
  if ($index) {
    $next_index = ($index == gettoken($view_cycle, 'count', '/'))
      ? 1 : ($index+1);
    $next_view_id = gettoken($view_cycle, $next_index, '/');
    $next_view_info = regexmatches($view_table, "^ *$next_view_id\|.+");
    $next_view_info = trim($next_view_info, <crlf>);
    if ($next_view_info) {
      $next_view_cmd = gettoken($next_view_info, 2, '|');
      $next_view_icon = gettoken($next_view_info, 3, '|');
      ctbicon($next_view_icon ? $next_view_icon : ':views');
      load "#$next_view_cmd;",, 's';
    }
  } else {
    button 'views', 2;
  }

/* == RCLICK ======================================================== */
"rclick|icon : _rclick"
  button 'views', 2;
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

klownboy
Posts: 4109
Joined: 28 Feb 2012 19:27

Re: [ctb] view rocker - cycle views

Post by klownboy »

Hi Sammay, reviewing your script got me thinking of my own version that I've used for many years. Similar intent but simpler. It cycles between detail and list views for left click of the mouse, and cycles between detail and thumbnail for right click. What I was thinking (and I subsequently added to my version) was having the script not only detect the current view with $view = get("view"); but also determine the Folder View Setting for that particular folder using $fvs = get("fvs",<curpath>, "view");. Don gave me that get variation to support my ThumbnailMaintenance script. This way you can intelligently switch between detail and a thumbnail view that is already established in FVS. If the folder has no FVS setting that script line returns "-1".

So with get("view"); we obtain the current view but get("fvs",<curpath>, "view"); provides the thumbnail view we actually want to rock or cycle through. This way I don't have to worry about creating thumbnails unnecessarily in a thumbnail view I don't want for that particular folder since it will use the thumbnail view saved in FVS. My own photos I want thumbnail view #3 "240x240", downloaded wallpapers I want thumbnail #2 "240x180", and PDF and icons I use thumbnail view #1 "180x180". That's exactly what I'll get if on right click cycle from detail to thumbnail view. Of course if you don't have or use FVS's for your folders this logic doesn't work well. As I mentioned, the script can detect that if the return is "-1" so you could either exit with a message or do whatever else is desired. I don't bother changing the CTB name only the state and icon since I'd rather just see the text function of the [L]eft and [R]ight click.

Code: Select all

//So I use this (in part) to accomplish the switching between detail and thumbnail views....
	$fvs = get("fvs",<curpath>, "view");
	$view = get("view");
		if (($view <= 3) AND (gettokenindex($fvs, "4|5|6", "|"))) {
			$thumb_cid = replacelist($fvs, "4|5|6", "306|307|308","|");
			ctbicon(":viewthumbs");
			ctbstate(1);
			#$thumb_cid;
		}
		elseif ($view > 3) {
			ctbicon(":viewdetails");
			ctbstate(0);
			#302;
		}
//***bla bla bla
Thanks for your script. :appl:
Windows 11, 22H2 Build 22621.1555 at 100% 2560x1440

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: [ctb] view rocker - cycle views

Post by bdeshi »

Nice idea, Ken. Actually I get by with just one thumbnail view (only for previews), so the fact that different folders might demand different thumbnail views didn't even come to my mind!
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

klownboy
Posts: 4109
Joined: 28 Feb 2012 19:27

Re: [ctb] view rocker - cycle views

Post by klownboy »

Thanks Sammay, until I made that change, I was actually checking for certain paths and using that information to apply the proper thumbnail view. This was automated and much simpler at least for someone using multiple thumbnail views and FVSs. I suppose if you didn't use FVS's you could also check the thumbnail database for an existing cache(s) for a particular folder, but that seemed like too much work for what should be a simple thing. Thanks again.
Windows 11, 22H2 Build 22621.1555 at 100% 2560x1440

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: [ctb] view rocker - cycle views

Post by bdeshi »

Code: Select all

$view_cycle = '0/4'; // details/thumbs#1
I thought of adjust that cycle interpretation so that an example definition$view_cycle = '0/f4/2/8';cycles among details -> fvs or thumbs#1 -> list -> small tiles ... .

But this mechanism can fail when fvs view and a view in the cycle match up. For the example cycle -- details -> fvs/thumbs#1 -> list -> small tiles -- if someone has an fvs with small tiles, and the current view is also the same, then the script wouldn't know if the current tiles view was from fvs or from the fourth element of $view_cycle = '0/f4/2/8';, and thus can't figure out the next view to cycle to. A permanent variable to define state has to be introduced (which can go stale too).

I guess I'm worrying over very distant edge cases, but still this boils down to "too much work for what should be a simple thing." as you said.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

klownboy
Posts: 4109
Joined: 28 Feb 2012 19:27

Re: [ctb] view rocker - cycle views

Post by klownboy »

In most cases I think something like this view rocking/switching is actually better suited to a keyboard command rather than a CTB. What I was thinking at least for my script which already does one switch with left click and a different one for right click would be to modify the script such that it detects if accomplished via CTB vs another method. If it's a non-CTB method I'd have it detect if a modifier key (e.g., shift) is pressed, if it is the script would accomplish the same action as the the right click. I don't want to get to carried away but once it's done it's done (at least for another few years). :)

I think your script with the heredoc lookup table is much better suited to cycle through more than 2 views if that's what the user wants. By the way, that method is similar in some ways to what TheQwerty did on his nice "Wall of Pictures" script which I use quite often. I modified that one a little to change layouts when I want as well as the view (i.e., so if I have a modifier key pressed it will not only change the thumbnail view mode, but also perform a layout change like a full wall - no bars, no nav panel, and no title bar via AHK).
Windows 11, 22H2 Build 22621.1555 at 100% 2560x1440

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: [ctb] view rocker - cycle views

Post by bdeshi »

Here's an updated version of the script that takes FVS saved views into consideration when cycling views.

Code: Select all

/* viewrocker.xys
** ctb script to cycle a set of viewmodes.
** set *both* left- & right-click script of a ctb as below, done.
**   ::load "<xyscripts>\_ctb\viewrocker.xys",,'f'; // adjust path
** left-click will cycle between views defined in $view_cycle
** right-click will show regular Views menu.
*/

"_Initialize"

  global $view_table, $view_cycle, $view_cycle_unlisted;
  // $view_cycle: /-separated get(view) id of views to cycle among
  // if a view id is prepended with 'f', then the view is retrieved
  // from fvs, otherwise the view id after deleting 'f' is applied.
  // eg, for `$view_cycle = '1/f4'`, view cycles from 1:details to
  // either the view from fvs, otherwise 4:thumbs#1
  $view_cycle = isset($P_VIEWROCKER_VIEW_CYCLE)
    ? $P_VIEWROCKER_VIEW_CYCLE
    : '0/f4'; // details/fvs|thumbs#1
  // $view_table: <get('view')>|<view cmdID>[|<view icon>[|...]]
  $view_table = isset($P_VIEW_TABLE)
    ? $P_VIEW_TABLE
    : <<<#>>
      0|302|:viewdetails|Details
      1|303|:viewdetails|Details with Thumbnails#1
      2|304|:viewlist|List
      3|305|:views|Small Icons
      4|306|:viewthumbs|Thumbnails #1
      5|307|:viewthumbs|Thumbnails #2
      6|308|:viewthumbs|Thumbnails #3
      7|309|:views|Large Icons
      8|313|:views|Small Tiles
      9|314|:views|Large Tiles
    #>>;
  // perform cycling even if current view is not in $view_cycle
  $view_cycle_unlisted = isset($P_VIEWROCKER_CYCLE_UNLISTED)
    ? $P_VIEWROCKER_CYCLE_UNLISTED
    : 1;
  // icon and caption
  $ico = ':views';
  $cap = "LClick: Cycle View ($view_cycle)<crlf>RClick:Views Menu";
  $lc  = '_lclick'; // left-click   script label(s) ;-separated
  $rc  = '_rclick'; // rights-click script label(s) ;-separated

  if !(ctbicon()) { ctbicon($ico); }
  ctbname($cap);
  if     (get('trigger') == 1) { load '*', $lc, 's'; }
  elseif (get('trigger') == 2) { load '*', $rc, 's'; }

"default" eval(); // avoids "does not contain any visible scripts."

/* == LCLICK ======================================================== */
"lclick|icon : _lclick"
  global $view_table, $view_cycle, $view_cycle_unlisted;
  $view_id = get('view');
  $fvs_view_id = get('#471') ? get('fvs', <curpath>, 'view') : -1;
  if ($view_id == $fvs_view_id) {
    $rev_cycle = formatlist($view_cycle, 'v', '/');
    $cycle_len = gettoken($view_cycle, 'count', '/');
    $similar_id = abs(gettokenindex($fvs_view_id, $rev_cycle, '/')-$cycle_len)+1;
    $view_id = $similar_id ? gettoken($view_cycle, $similar_id, '/') : $view_id;
  } else {
    $pattern = ($view_id == $fvs_view_id) ? 'f.+' : "f?$view_id";
    $view_id = gettoken(regexmatches($view_cycle, $pattern, '/'), 1, '/');
  }
  $index = gettokenindex($view_id, $view_cycle, '/');
  $index = $index ? $index: $view_cycle_unlisted ? 1 : $index;
  if ($index) {
    $next_index = ($index == gettoken($view_cycle, 'count', '/'))
      ? 1 : ($index+1);
    $next_view_id = gettoken($view_cycle, $next_index, '/');
    if (strpos($next_view_id, 'f') == 0) {
      $next_view_id = ($fvs_view_id == -1)
        ? substr($next_view_id, 1)
        : $fvs_view_id;      
    }
    $next_view_info = regexmatches($view_table, "^ *$next_view_id\|.+");
    $next_view_info = trim($next_view_info, <crlf>);
    if ($next_view_info) {
      $next_view_cmd = gettoken($next_view_info, 2, '|');
      $next_view_icon = gettoken($next_view_info, 3, '|');
      ctbicon($next_view_icon ? $next_view_icon : ':views');
      load "#$next_view_cmd;",, 's';
    }
  } else {
    button 'views', 2;
  }
/* == RCLICK ======================================================== */
"rclick|icon : _rclick"
  button 'views', 2;

  • perm $P_VIEWROCKER_VIEW_CYCLE or $view_cycle in-script sets the list of views to cycle among.
    This is a "/"-separated list of view IDs as returned by get('view').
    If an ID is prefixed with "f", then the script tries to apply the view from FVS; failing that, falls back to the ID minus the "f" prefix.
    For example, if $view_cycle = '0/f4/9', the script will cycle between details view (id 0) --> either FVS ("f" of "f4") or Thumbnails #1 view (id 4 of "f4") --> large tiles view (id 9) --> loop.
  • perm $P_VIEWROCKER_CYCLE_UNLISTED or $view_cycle_unlisted in-script
    1: cycling is enforced even if current view is not listed in $view_cycle.
    0: show views menu if current view is not listed in $view_cycle.
  • perm $P_VIEW_TABLE exists to update the view table in case new view modes are added to XYplorer and this script doesn't get updated to reflect that.
If FVS view is applied and the cycle also lists an id matching the fvs view, then the id after that one is cycled next. Yes it's confusing.
If multiple IDs in $view_cycle are prefixes with "f", the script's behavior is undefined.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

klownboy
Posts: 4109
Joined: 28 Feb 2012 19:27

Re: [ctb] view rocker - cycle views

Post by klownboy »

Very nice update for viewrocker. Thanks Sammay. :tup:
Windows 11, 22H2 Build 22621.1555 at 100% 2560x1440

Lusayalumino
Posts: 86
Joined: 13 Aug 2018 07:16
Location: USA

Re: [ctb] view rocker - cycle views

Post by Lusayalumino »

This is a very practical script... thanks for sharing! :tup:
XYPlorer, Great Form -- Awesome Function

yuyu
Posts: 114
Joined: 19 Jun 2018 12:40

Re: [ctb] view rocker - cycle views

Post by yuyu »

Great and useful script. Unfortunately it doesn't work anymore for me in latest XY versions (starting from v24.80.0002).

jupe
Posts: 2758
Joined: 20 Oct 2017 21:14
Location: Win10 22H2 120dpi

Re: [ctb] view rocker - cycle views

Post by jupe »

Yeah there was a breaking change for scripting, which currently the dev has decided to leave as is, so scripts will need updating, in this case changing line 56 of the script in the first post (or line 77 in the updated FVS version), to the following should resolve it. (untested)

$next_view_info = regexmatches($view_table, "^ *" . "$next_view_id\|.+");

admin
Site Admin
Posts: 60357
Joined: 22 May 2004 16:48
Location: Win8.1 @100%, Win10 @100%
Contact:

Re: [ctb] view rocker - cycle views

Post by admin »

Hmmm, I really start to dislike this breaking change :maf: What could be done? A per-script allow statement like AllowInterpolatedDeref 1;?

jupe
Posts: 2758
Joined: 20 Oct 2017 21:14
Location: Win10 22H2 120dpi

Re: [ctb] view rocker - cycle views

Post by jupe »

I tend to like that solution better that the current situation.

highend
Posts: 13276
Joined: 06 Feb 2011 00:33

Re: [ctb] view rocker - cycle views

Post by highend »

AllowInterpolatedDeref 1;
+ 1
One of my scripts helped you out? Please donate via Paypal

Lusayalumino
Posts: 86
Joined: 13 Aug 2018 07:16
Location: USA

Re: [ctb] view rocker - cycle views

Post by Lusayalumino »

Interesting... still working for me in 24.80. I wonder why mine still works?
XYPlorer, Great Form -- Awesome Function

Post Reply