[Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Learn how to use AAO by reading tutorials, and seek help from the AAO community.

Moderator: EN - Forum Moderators

Post Reply
User avatar
TimeAxis
Posts: 381
Joined: Fri Jan 01, 2021 8:27 pm
Spoken languages: English
Contact:

[Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Post by TimeAxis »

Better Layout:
Spoiler : :
Keyboard Controls:
Spoiler : Keyboard Control Script :
If you're like me and hate having to use the mouse to click repeatedly to advance text in order to play through AAO cases, this script may be for you. It allows you to press 'enter' or 'space' to advance text. You will still need to use the mouse to select dialogue options or navigate most menus, though. There's also a little bonus feature. Holding 'ctrl' will allow you to rapidly skip forward. (Warning: Skipping could potentially cause bugs or other weird behavior. I tested it a bit and it was fine, especially for straight-forward text sections, but I make no guarantees.)

You can use it in one of two ways.

Method 1: Installing it as a Userscript.
Step 1: Install a User Script Extension for your Browser. (On Firefox there is Tampermonkey, Greasemonkey, or Violentmonkey. To name a few. On Chrome, there is Tampermonkey) Keep in mind that I'm not responsible for any of these extensions and you should be sure to pick one that you personally trust. I also probably can't help you with troubleshooting these extensions as I don't use them very often. I recommend google if you have trouble.
Step 2: Once the extension is installed, either click here and install it (most extensions will allow you to install it from that link) or copy the code below into a new user script.

Method 2: Copying and Pasting it into your browser.
If you don't want to use a Userscript, right-click on the player page, press Inspect, and open the Console tab, then copy and paste the following code into the Console and press Enter. You would have to do this every time you want to use it, as it doesn't save if you leave or refresh the page.

Code: Select all

// ==UserScript==
// @name         AAO Keyboard Controls
// @namespace    AAOKeyboardControls
// @version      1.1
// @description  Allow Enter/Space/Shift to be used in AAO
// @author       TimeAxis
// @match        *://*aaonline.fr/player.php*
// @match        *://aaonline.fr/player.php*
// @grant        none
// ==/UserScript==

//////////////////////////////////////////////////////////
//                   KEYBOARD CONTROLS
//////////////////////////////////////////////////////////


// Define the key codes for arrow keys
const aaokeyboard_keyCodes = {
  enter: 13,
  space: 32,
  shift: 16,
};

// Function to check if an element is visible
function aaokeyboard_isVisible(element) {
  const style = getComputedStyle(element);
  return style.display !== 'none' && style.visibility !== 'hidden';
}

// Define the target image source URLs for each arrow key
const aaokeyboard_targetImageSrcs = {
  enter: ["http://www.aaonline.fr/img/player/proceed.gif","http://www.aaonline.fr/img/player/skip.gif","http://aaonline.fr/img/player/proceed.gif","http://aaonline.fr/img/player/skip.gif","https://aaonline.fr/img/player/proceed.gif","https://aaonline.fr/img/player/skip.gif","https://www.aaonline.fr/img/player/proceed.gif","https://www.aaonline.fr/img/player/skip.gif","https://aaonline.fr/img/player/statement_forwards.gif","http://aaonline.fr/img/player/statement_forwards.gif","https://www.aaonline.fr/img/player/statement_forwards.gif","http://www.aaonline.fr/img/player/statement_forwards.gif","https://aaonline.fr/img/player/statement_skip_forwards.gif","http://aaonline.fr/img/player/statement_skip_forwards.gif","https://www.aaonline.fr/img/player/statement_skip_forwards.gif","http://www.aaonline.fr/img/player/statement_skip_forwards.gif"],
};

// Keep track of the Enter key press state and whether a click has been performed
let aaokeyboard_enterPressed = false;
let aaokeyboard_enterClicked = false;

// Function to simulate click on images with the target source URLs
function aaokeyboard_clickImagesWithSrc(srcArray) {
  const images = document.querySelectorAll('img');
  let clicked = false; // Flag to track if a click has been performed
  images.forEach(img => {
    if (aaokeyboard_isVisible(img) && aaokeyboard_isVisible(img.parentElement) && !clicked) {
      // Perform case-insensitive comparison of URLs
      const imgSrc = img.src.toLowerCase();
      srcArray.forEach(src => {
        if (imgSrc === src.toLowerCase()) {
          img.click();
          clicked = true; // Set the flag to prevent multiple clicks
          return; // Break out of loop after clicking the first visible image
        }
      });
    }
  });
}

document.addEventListener("keydown", event => {
  const keyCode = event.keyCode;
  if ((keyCode === aaokeyboard_keyCodes.enter || keyCode === aaokeyboard_keyCodes.space) && !aaokeyboard_enterClicked && !aaokeyboard_enterPressed) {
    aaokeyboard_enterPressed = true;
    aaokeyboard_clickImagesWithSrc(aaokeyboard_targetImageSrcs.enter);
    aaokeyboard_enterClicked = true;
    event.preventDefault(); // Prevent default behavior
  }
  if (keyCode === aaokeyboard_keyCodes.shift) {
    aaokeyboard_enterPressed = false;
    aaokeyboard_enterClicked = false;
    aaokeyboard_clickImagesWithSrc(aaokeyboard_targetImageSrcs.enter);
    event.preventDefault(); // Prevent default behavior
  }
});

document.addEventListener("keyup", event => {
  const keyCode = event.keyCode;
  if (keyCode === aaokeyboard_keyCodes.enter) {
    aaokeyboard_enterPressed = false;
    aaokeyboard_enterClicked = false;
  }
  if (keyCode === aaokeyboard_keyCodes.space) {
    aaokeyboard_enterPressed = false;
    aaokeyboard_enterClicked = false;
  }
});

console.log("AAOKeyboard Script loaded.");
Disclaimer: This script is not endorsed by Unas or the AAO staff. Always be careful when installing user scripts or running code through your browser. Only install scripts from sources you trust. In this case, the code is right there for anyone to read it, so feel free to review it and check for anything shady.
Backlog Script:
Spoiler : Backlog :
I have a terrible memory when going through cases, so if you're like me, you could probably use this. It adds a backlog that lets you review the last 100 dialogue lines.

Method 1: Installing it as a Userscript.
Step 1: Install a User Script Extension for your Browser. (On Firefox there is Tampermonkey, Greasemonkey, or Violentmonkey. To name a few. On Chrome, there is Tampermonkey) Keep in mind that I'm not responsible for any of these extensions and you should be sure to pick one that you personally trust. I also probably can't help you with troubleshooting these extensions as I don't use them very often. I recommend google if you have trouble.
Step 2: Once the extension is installed, either click here and install it (most extensions will allow you to install it from that link) or copy the code below into a new user script.

Method 2: Copying and Pasting it into your browser.
If you don't want to use a Userscript, right-click on the player page, press Inspect, and open the Console tab, then copy and paste the following code into the Console and press Enter. You would have to do this every time you want to use it, as it doesn't save if you leave or refresh the page.

Code: Select all

// ==UserScript==
// @name         AAO Backlog Script
// @namespace    AAOlogscript
// @version      1.1
// @description  Adds a Backlog button to AAO trials
// @author       TimeAxis
// @match        *://*aaonline.fr/player.php*
// @match        *://aaonline.fr/player.php*
// @grant        none
// ==/UserScript==

    console.log("logscript_init() function started.");

	const logscript_oldproceed = proceed;

	var logscript_lastText = "";
	var logscript_lastName = "";
	var logscript_lastFrameID = -1;
	var logscript_lastMerged = false;

	var logscript_currentFrameData = false; 
	var logscript_currentText = "";
	var logscript_currentName = "";
	var logscript_currentFrameID = -1;
	var logscript_mergedFrame = false;

	var logscript_log = [];

	proceed = function(conditions, backwards){
		logscript_currentFrameData = trial_data.frames[player_status.current_frame_index];

		logscript_currentFrameID = logscript_currentFrameData.id;
		logscript_mergedFrame = logscript_currentFrameData.merged_to_next;
		logscript_currentText = top_screen.text_display.dialogue_box.innerHTML;
		logscript_currentName = top_screen.text_display.name_box.innerHTML;

		//Check for partially completed textbox
		var ls_fake_container = document.createElement('div');
		top_screen.text_display.instantTypeText(ls_fake_container, top_screen.text_display.dialogue_box.textContent);
		var ls_clean_text_contents1 = ls_fake_container.textContent.trim();
		ls_fake_container.remove();
		ls_fake_container = document.createElement('div');
		top_screen.text_display.instantTypeText(ls_fake_container, logscript_currentFrameData.text_content);
		var ls_clean_text_contents2 = ls_fake_container.textContent.trim();
		ls_fake_container.remove();
		ls_fake_container = null;
		
		const logscript_result = logscript_oldproceed.apply(this, arguments);

		if (ls_clean_text_contents1 == ls_clean_text_contents2 || (logscript_lastMerged)){
			if ((!logscript_mergedFrame) && (logscript_currentFrameID != logscript_lastFrameID) && ((player_status.proceed_click_met) || (player_status.proceed_timer_met && player_status.proceed_timer && player_status.proceed_typing) || (player_status.proceed_typing_met) || ((!player_status.proceed_click_met) && (!player_status.proceed_timer_met) && (!player_status.proceed_typing_met))) && (logscript_currentText != "")){
				logscript_addToLog(logscript_currentName,logscript_currentText);
				logscript_refreshLog();

				logscript_lastText = logscript_currentText;
				logscript_lastName = logscript_currentName;
				logscript_lastFrameID = logscript_currentFrameID;
				logscript_lastMerged = logscript_mergedFrame;
			}
		} else {
			console.log("1:" + ls_clean_text_contents1 +"/2:" + ls_clean_text_contents2);
			logscript_lastMerged = logscript_mergedFrame;
		}



		return logscript_result;
	};

	function logscript_addToLog(name, frametext) {
		if (logscript_log.length > 99) {
			// Remove the first element
			logscript_log.shift();
		}
		logscript_log.push([name, frametext]);
	}

	function logscript_refreshLog(){
		const logscript_contentContainer = document.getElementById('backlog_content');
		logscript_contentContainer.innerHTML = ""
		for(let i = 0; i < logscript_log.length; i++){
			let name = logscript_log[i][0];
			let dialogue = logscript_log[i][1];
			if(name != ""){
				logscript_contentContainer.innerHTML = logscript_contentContainer.innerHTML + "<span class='backlog-name'>" + name + "</span><br/><div class='backlog-text'>" + dialogue + "</div>";
			} else {
				logscript_contentContainer.innerHTML = logscript_contentContainer.innerHTML + "<br/><div class='backlog-text'>" + dialogue + "</div>";
			}
		}
		logscript_contentContainer.scrollTop = logscript_contentContainer.scrollHeight;
	}

	// Create a button element
	const logscript_logButton = document.createElement("button");

	// Set the button's CSS style
	logscript_logButton.style.position = 'absolute';
	logscript_logButton.style.top = '-2px';
	logscript_logButton.style.left = '-2px';

	// Find the parent element with the id "screen-meta"
	const logscript_screenMeta = document.getElementById('screen-meta');

	// Append the button to the parent element
	logscript_screenMeta.appendChild(logscript_logButton);
	logscript_logButton.id = "backlog-button";
	logscript_logButton.innerHTML = "Backlog"; 
	logscript_logButton.onclick = toggleBacklog;

	// Create Backlog HTML and CSS
	function logscript_generateBacklog() {
		// Create main container
		const logscript_container = document.createElement('div');
		logscript_container.id = 'backlog';
		logscript_container.className = 'backlog-container';

		// Create header
		const logscript_header = document.createElement('div');
		logscript_header.className = 'backlog-header';
		logscript_header.textContent = 'Backlog:';

		// Create close icon
		const logscript_closeIcon = document.createElement('div');
		logscript_closeIcon.className = 'backlog-close-icon';
		logscript_closeIcon.textContent = '✖';
		logscript_closeIcon.onclick = closeBacklog;

		// Append close icon to the header
		logscript_header.appendChild(logscript_closeIcon);

		// Create content container
		const logscript_contentContainer = document.createElement('div');
		logscript_contentContainer.id = 'backlog_content';
		logscript_contentContainer.className = 'backlog-content';

		// Append header and content to the main container
		logscript_container.appendChild(logscript_header);
		logscript_container.appendChild(logscript_contentContainer);

		// Append the main container to the document body
		const logscript_parentDiv = document.getElementById('screens');
		logscript_parentDiv.insertBefore(logscript_container, logscript_parentDiv.childNodes[2]);
		logscript_container.style.display = 'none';

		// Create style element
		const styleElement = document.createElement('style');
		styleElement.textContent = `
			.backlog-container {
				width: 254px;
				z-index: 999;
				height: 185px;
				position: absolute;
				color: white;
				left: 0px;
				width: 256px;
				min-height: 52px;
				margin: 10px;
				padding: 2px 2px 2px 2px;
				border: 2px ridge rgba(136, 136, 136, 0.75);
				border-radius: 3px;
				resize: none;
				background: rgba(0, 0, 0, 0.85);
				font: 12px aaDialogueText, sans-serif;
				text-align: start;
				line-height: 16px;
			}

			.backlog-header {
				font: 12px sans-serif;
				color: white;
			}

			.backlog-close-icon {
				position: absolute;
				top: 1px;
				right: 2px;
				cursor: pointer;
				font: 12px sans-serif;
				text-align: start;
				white-space: pre-wrap;
				line-height: 16px;
				color: white;
			}

			.backlog-close-icon:hover {
				color: grey;
			}

			.backlog-content {
				overflow-y: auto !important;
				height: 150px;
				text-align: left;
				scrollbar-width: thin;
				padding: 20px 10px 0px 0px;
				position: relative;
				width: 256px;
				color: white;
			}
			
			.backlog-name {
				margin-top: 7px;
				height: 12px;
				min-width: 44px;
				padding: 0 2px;
				overflow: hidden;
				border: 2px ridge rgba(136,136,136,0.75);
				border-radius: 3px;
				background: rgba(27,34,108,0.75);
				white-space: nowrap;
				font-size: 10px;
				line-height: 10px;
				color: white;
			}

			.backlog-text {
				margin-bottom: 0px;
			}
		`;

		// Append style element to the document head
		document.head.appendChild(styleElement);
	}

	// Function to close backlog (example function, replace with your logic)
	function closeBacklog() {
		const logscript_container = document.getElementById('backlog');
		logscript_container.style.display = 'none';
	}

	function openBacklog() {
		const logscript_container = document.getElementById('backlog');
		const logscript_contentContainer = document.getElementById('backlog_content');

		logscript_container.style.display = 'block';
		logscript_contentContainer.scrollTop = logscript_contentContainer.scrollHeight;
	}

	function toggleBacklog() {
		const logscript_container = document.getElementById('backlog');
		if (logscript_container.style.display === 'none' || logscript_container.style.display === '') {
			openBacklog();
		} else {
			closeBacklog();
		}
		logscript_logButton.blur();
	}

	// Call the function to generate HTML and CSS
	logscript_generateBacklog();

Disclaimer: This script is not endorsed by Unas or the AAO staff. Always be careful when installing user scripts or running code through your browser. Only install scripts from sources you trust. In this case, the code is right there for anyone to read it, so feel free to review it and check for anything shady.
If anyone really wants a certain script, I may be willing to do it, but keep in mind the following is either not possible or beyond my ability:
- Keyboard control on examining places, with some kind of cursor. (I tried it, it was a nightmare. Not happening)
- Multiplayer/Amogus/Doom (Yes, they're probably possible, no I'm not doing it.)
- Things that would render a case unplayable without the script. (This would more just be unwise.)
Last edited by TimeAxis on Sat Dec 09, 2023 1:58 pm, edited 9 times in total.
Image
Question Arcs (Threads Coming Eventually)
ImageImageImageImage
Gaiden Episodes
Champion of Turnabouts ★
HALLOWEEN HERO
Other
Phoenix Wright: Ace Attornauts
The Curious Case of the Phantom Limousine (Coming Eventually)
User avatar
SuperAj3
Posts: 1306
Joined: Wed Sep 01, 2010 11:19 am
Spoken languages: English, 日本語(少しだけ)
Location: Legal Land

Re: [Tool] AAO Keyboard Controls Script

Post by SuperAj3 »

This is seriously amazing to see! A feature I've wished existed for years now.

Definitely will see how this goes but amazing work Time!
ImageImageImageImage
Avatar from the TSub website :april:
User avatar
risefromtheashes
Posts: 341
Joined: Wed Apr 04, 2018 2:33 am
Spoken languages: English, Russian, conversational Spanish/Armenian

Re: [Tool] AAO Keyboard Controls Script

Post by risefromtheashes »

Image

Edit: In all seriousness, this made me realize how cool it would be to have arrow key selections for multiple choice prompts and examining/pinpointing locations on a background.
The Mindcastle System
(Don't know what a system is? Play 6-4, and take a look here.)
----------
OUR CASES:
- Athena Cykes ~ Locks on the Heart (synopsis)
- A Little Piece of Healing
- The Killer Turnabout (~70% complete!)
- I guess we made the Looking Back case comp ceremony with Super legenda, but that's not an actual case

----------
Check out our music & art thread here!
User avatar
TimeAxis
Posts: 381
Joined: Fri Jan 01, 2021 8:27 pm
Spoken languages: English
Contact:

Re: [Tool] AAO Keyboard Controls Script

Post by TimeAxis »

While I could theoretically make a hotkey to click on any particular known unique button (like I did manage to make an arrow key movement script for Halloween Hero, and I could add present/press hotkeys, although I don't really feel like it atm), dialogue choice buttons don't have any unique identifiers, so there's no way that I'm aware of to identify which one to click, and making a whole "highlight and select" system would be way beyond me.

The best I could even imagine on that front would be if cases were specifically designed with the script in mind and added their own identifiers to choices, like detecting whether a dialogue option has a number 1-9 at the beginning, and making the number keys automatically click the corresponding option. But that's just spitballing, I have no plans to attempt that currently.
Image
Question Arcs (Threads Coming Eventually)
ImageImageImageImage
Gaiden Episodes
Champion of Turnabouts ★
HALLOWEEN HERO
Other
Phoenix Wright: Ace Attornauts
The Curious Case of the Phantom Limousine (Coming Eventually)
User avatar
TimeAxis
Posts: 381
Joined: Fri Jan 01, 2021 8:27 pm
Spoken languages: English
Contact:

Re: [Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Post by TimeAxis »

I've made a script that adds a Backlog button to the left of the Lifebar. This one should be compatible with the keyboard script with no issues. Haven't tested it on any super long cases, so feel free to let me know if anything breaks.

Backlog Script:
Spoiler : Backlog :
I have a terrible memory when going through cases, so if you're like me, you could probably use this. It adds a backlog that lets you review that last 100 dialogue lines.

Method 1: Installing it as a Userscript.
Step 1: Install a User Script Extension for your Browser. (On Firefox there is Tampermonkey, Greasemonkey, or Violentmonkey. To name a few. On Chrome, there is Tampermonkey) Keep in mind that I'm not responsible for any of these extensions and you should be sure to pick one that you personally trust. I also probably can't help you with troubleshooting these extensions as I don't use them very often. I recommend google if you have trouble.
Step 2: Once the extension is installed, either click here and install it (most extensions will allow you to install it from that link) or copy the code below into a new user script.

Method 2: Copying and Pasting it into your browser.
If you don't want to use a Userscript, right-click on the player page, press Inspect, and open the Console tab, then copy and paste the following code into the Console and press Enter. You would have to do this every time you want to use it, as it doesn't save if you leave or refresh the page.

Code: Select all

// ==UserScript==
// @name         AAO Backlog Script
// @namespace    AAOlogscript
// @version      1.1
// @description  Adds a Backlog button to AAO trials
// @author       TimeAxis
// @match        *://*aaonline.fr/player.php*
// @match        *://aaonline.fr/player.php*
// @grant        none
// ==/UserScript==

    console.log("logscript_init() function started.");

	const logscript_oldproceed = proceed;

	var logscript_lastText = "";
	var logscript_lastName = "";
	var logscript_lastFrameID = -1;
	var logscript_lastMerged = false;

	var logscript_currentFrameData = false; 
	var logscript_currentText = "";
	var logscript_currentName = "";
	var logscript_currentFrameID = -1;
	var logscript_mergedFrame = false;

	var logscript_log = [];

	proceed = function(conditions, backwards){
		logscript_currentFrameData = trial_data.frames[player_status.current_frame_index];

		logscript_currentFrameID = logscript_currentFrameData.id;
		logscript_mergedFrame = logscript_currentFrameData.merged_to_next;
		logscript_currentText = top_screen.text_display.dialogue_box.innerHTML;
		logscript_currentName = top_screen.text_display.name_box.innerHTML;

		//Check for partially completed textbox
		var ls_fake_container = document.createElement('div');
		top_screen.text_display.instantTypeText(ls_fake_container, top_screen.text_display.dialogue_box.textContent);
		var ls_clean_text_contents1 = ls_fake_container.textContent.trim();
		ls_fake_container.remove();
		ls_fake_container = document.createElement('div');
		top_screen.text_display.instantTypeText(ls_fake_container, logscript_currentFrameData.text_content);
		var ls_clean_text_contents2 = ls_fake_container.textContent.trim();
		ls_fake_container.remove();
		ls_fake_container = null;
		
		const logscript_result = logscript_oldproceed.apply(this, arguments);

		if (ls_clean_text_contents1 == ls_clean_text_contents2 || (logscript_lastMerged)){
			if ((!logscript_mergedFrame) && (logscript_currentFrameID != logscript_lastFrameID) && ((player_status.proceed_click_met) || (player_status.proceed_timer_met && player_status.proceed_timer && player_status.proceed_typing) || (player_status.proceed_typing_met) || ((!player_status.proceed_click_met) && (!player_status.proceed_timer_met) && (!player_status.proceed_typing_met))) && (logscript_currentText != "")){
				logscript_addToLog(logscript_currentName,logscript_currentText);
				logscript_refreshLog();

				logscript_lastText = logscript_currentText;
				logscript_lastName = logscript_currentName;
				logscript_lastFrameID = logscript_currentFrameID;
				logscript_lastMerged = logscript_mergedFrame;
			}
		} else {
			console.log("1:" + ls_clean_text_contents1 +"/2:" + ls_clean_text_contents2);
			logscript_lastMerged = logscript_mergedFrame;
		}



		return logscript_result;
	};

	function logscript_addToLog(name, frametext) {
		if (logscript_log.length > 99) {
			// Remove the first element
			logscript_log.shift();
		}
		logscript_log.push([name, frametext]);
	}

	function logscript_refreshLog(){
		const logscript_contentContainer = document.getElementById('backlog_content');
		logscript_contentContainer.innerHTML = ""
		for(let i = 0; i < logscript_log.length; i++){
			let name = logscript_log[i][0];
			let dialogue = logscript_log[i][1];
			if(name != ""){
				logscript_contentContainer.innerHTML = logscript_contentContainer.innerHTML + "<span class='backlog-name'>" + name + "</span><br/><div class='backlog-text'>" + dialogue + "</div>";
			} else {
				logscript_contentContainer.innerHTML = logscript_contentContainer.innerHTML + "<br/><div class='backlog-text'>" + dialogue + "</div>";
			}
		}
		logscript_contentContainer.scrollTop = logscript_contentContainer.scrollHeight;
	}

	// Create a button element
	const logscript_logButton = document.createElement("button");

	// Set the button's CSS style
	logscript_logButton.style.position = 'absolute';
	logscript_logButton.style.top = '-2px';
	logscript_logButton.style.left = '-2px';

	// Find the parent element with the id "screen-meta"
	const logscript_screenMeta = document.getElementById('screen-meta');

	// Append the button to the parent element
	logscript_screenMeta.appendChild(logscript_logButton);
	logscript_logButton.id = "backlog-button";
	logscript_logButton.innerHTML = "Backlog"; 
	logscript_logButton.onclick = toggleBacklog;

	// Create Backlog HTML and CSS
	function logscript_generateBacklog() {
		// Create main container
		const logscript_container = document.createElement('div');
		logscript_container.id = 'backlog';
		logscript_container.className = 'backlog-container';

		// Create header
		const logscript_header = document.createElement('div');
		logscript_header.className = 'backlog-header';
		logscript_header.textContent = 'Backlog:';

		// Create close icon
		const logscript_closeIcon = document.createElement('div');
		logscript_closeIcon.className = 'backlog-close-icon';
		logscript_closeIcon.textContent = '✖';
		logscript_closeIcon.onclick = closeBacklog;

		// Append close icon to the header
		logscript_header.appendChild(logscript_closeIcon);

		// Create content container
		const logscript_contentContainer = document.createElement('div');
		logscript_contentContainer.id = 'backlog_content';
		logscript_contentContainer.className = 'backlog-content';

		// Append header and content to the main container
		logscript_container.appendChild(logscript_header);
		logscript_container.appendChild(logscript_contentContainer);

		// Append the main container to the document body
		const logscript_parentDiv = document.getElementById('screens');
		logscript_parentDiv.insertBefore(logscript_container, logscript_parentDiv.childNodes[2]);
		logscript_container.style.display = 'none';

		// Create style element
		const styleElement = document.createElement('style');
		styleElement.textContent = `
			.backlog-container {
				width: 254px;
				z-index: 999;
				height: 185px;
				position: absolute;
				color: white;
				left: 0px;
				width: 256px;
				min-height: 52px;
				margin: 10px;
				padding: 2px 2px 2px 2px;
				border: 2px ridge rgba(136, 136, 136, 0.75);
				border-radius: 3px;
				resize: none;
				background: rgba(0, 0, 0, 0.85);
				font: 12px aaDialogueText, sans-serif;
				text-align: start;
				line-height: 16px;
			}

			.backlog-header {
				font: 12px sans-serif;
				color: white;
			}

			.backlog-close-icon {
				position: absolute;
				top: 1px;
				right: 2px;
				cursor: pointer;
				font: 12px sans-serif;
				text-align: start;
				white-space: pre-wrap;
				line-height: 16px;
				color: white;
			}

			.backlog-close-icon:hover {
				color: grey;
			}

			.backlog-content {
				overflow-y: auto !important;
				height: 150px;
				text-align: left;
				scrollbar-width: thin;
				padding: 20px 10px 0px 0px;
				position: relative;
				width: 256px;
				color: white;
			}
			
			.backlog-name {
				margin-top: 7px;
				height: 12px;
				min-width: 44px;
				padding: 0 2px;
				overflow: hidden;
				border: 2px ridge rgba(136,136,136,0.75);
				border-radius: 3px;
				background: rgba(27,34,108,0.75);
				white-space: nowrap;
				font-size: 10px;
				line-height: 10px;
				color: white;
			}

			.backlog-text {
				margin-bottom: 0px;
			}
		`;

		// Append style element to the document head
		document.head.appendChild(styleElement);
	}

	// Function to close backlog (example function, replace with your logic)
	function closeBacklog() {
		const logscript_container = document.getElementById('backlog');
		logscript_container.style.display = 'none';
	}

	function openBacklog() {
		const logscript_container = document.getElementById('backlog');
		const logscript_contentContainer = document.getElementById('backlog_content');

		logscript_container.style.display = 'block';
		logscript_contentContainer.scrollTop = logscript_contentContainer.scrollHeight;
	}

	function toggleBacklog() {
		const logscript_container = document.getElementById('backlog');
		if (logscript_container.style.display === 'none' || logscript_container.style.display === '') {
			openBacklog();
		} else {
			closeBacklog();
		}
		logscript_logButton.blur();
	}

	// Call the function to generate HTML and CSS
	logscript_generateBacklog();

Disclaimer: This script is not endorsed by Unas or the AAO staff. Always be careful when installing user scripts or running code through your browser. Only install scripts from sources you trust. In this case, the code is right there for anyone to read it, so feel free to review it and check for anything shady.
Image
Question Arcs (Threads Coming Eventually)
ImageImageImageImage
Gaiden Episodes
Champion of Turnabouts ★
HALLOWEEN HERO
Other
Phoenix Wright: Ace Attornauts
The Curious Case of the Phantom Limousine (Coming Eventually)
User avatar
TimeAxis
Posts: 381
Joined: Fri Jan 01, 2021 8:27 pm
Spoken languages: English
Contact:

Re: [Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Post by TimeAxis »

AAO Better Layout Script
For people who want a bigger, more centered screen.
Image
Features
  • 1.5x Larger Screen (With option to make it 2x)
  • Toggle image interpolation on or off (For that pixelated effect)
  • Choose between the court record being on the left or right of the screen
  • Toggle Evidence descriptions to always be expanded (You can still only see 3 lines of text and need to hover over them to see the rest)
  • Night mode, for AAO night-owls
  • Fully compatible with the Backlog and Keyboard Control scripts
Get it HERE.
See instruction for other scripts in the OP for how to use it.

Also, since it was requested, here is a small script that changes the font on the nametags.
Image
Question Arcs (Threads Coming Eventually)
ImageImageImageImage
Gaiden Episodes
Champion of Turnabouts ★
HALLOWEEN HERO
Other
Phoenix Wright: Ace Attornauts
The Curious Case of the Phantom Limousine (Coming Eventually)
User avatar
Enthalpy
Community Manager
Posts: 5162
Joined: Wed Jan 04, 2012 4:40 am
Gender: Male
Spoken languages: English, limited Spanish

Re: [Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Post by Enthalpy »

That's impressive! I may give this a try myself.
[D]isordered speech is not so much injury to the lips that give it forth, as to the disproportion and incoherence of things in themselves, so negligently expressed. ~ Ben Jonson
User avatar
drvonkitty
Posts: 564
Joined: Sat Apr 14, 2012 12:25 am
Spoken languages: English

Re: [Tool] TimeAxis's Scripts (Keyboard Control, Backlog)

Post by drvonkitty »

i've been using these scripts for a few weeks now & i just wanted to give major props to timeaxis--thanks for making this. the "pixelated" filter, for example, is such a small thing but a massive improvement to case presentation and feel. i would love to see that become the default for AAO if at all possible!
Image

Image
Post Reply