[ctb] view rocker - cycle views

Discuss and share scripts and script files...
Post Reply
SammaySarkar
Posts: 4166
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

[ctb] view rocker - cycle views

Post by SammaySarkar » 07 Mar 2019 07:05

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;

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

Re: [ctb] view rocker - cycle views

Post by klownboy » 08 Mar 2019 20:32

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:

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

Re: [ctb] view rocker - cycle views

Post by SammaySarkar » 09 Mar 2019 06:40

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!

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

Re: [ctb] view rocker - cycle views

Post by klownboy » 09 Mar 2019 13:42

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.

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

Re: [ctb] view rocker - cycle views

Post by SammaySarkar » 09 Mar 2019 14:13

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.

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

Re: [ctb] view rocker - cycle views

Post by klownboy » 09 Mar 2019 15:32

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).

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

Re: [ctb] view rocker - cycle views

Post by SammaySarkar » 11 Apr 2019 11:34

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.

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

Re: [ctb] view rocker - cycle views

Post by klownboy » 12 Apr 2019 15:26

Very nice update for viewrocker. Thanks Sammay. :tup:

Post Reply