Add PgUp/Dn/Home/End to menu, bugfixes
This commit is contained in:
		@@ -43,14 +43,6 @@ class Editor
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->document = new Tree();
 | 
					        $this->document = new Tree();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // $this->document->load((object)[
 | 
					 | 
				
			||||||
        //     'foo' => true,
 | 
					 | 
				
			||||||
        //     'bar' => [
 | 
					 | 
				
			||||||
        //         'a', 'b', 'c'
 | 
					 | 
				
			||||||
        //     ],
 | 
					 | 
				
			||||||
        //     'what' => 42
 | 
					 | 
				
			||||||
        // ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->list = new TreeList($this->document);
 | 
					        $this->list = new TreeList($this->document);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->setWindowTitle($this->shortfilename." - JSONEdit");
 | 
					        $this->setWindowTitle($this->shortfilename." - JSONEdit");
 | 
				
			||||||
@@ -86,7 +78,7 @@ class Editor
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Load a document from array/object
 | 
					     * Load a document from array/object
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
<     * @param mixed $document
 | 
					     * @param mixed $document
 | 
				
			||||||
     * @return void
 | 
					     * @return void
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function loadDocument(mixed $document): void
 | 
					    public function loadDocument(mixed $document): void
 | 
				
			||||||
@@ -164,30 +156,7 @@ class Editor
 | 
				
			|||||||
                //     break;
 | 
					                //     break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case 'I':
 | 
					                case 'I':
 | 
				
			||||||
                    $menu = new Menu($this->term, [
 | 
					                    $this->doInsertMenu();
 | 
				
			||||||
                        'value' => "Insert Value",
 | 
					 | 
				
			||||||
                        'object' => "Insert Object{}",
 | 
					 | 
				
			||||||
                        'array' => "Insert Array[]",
 | 
					 | 
				
			||||||
                        //'sep0' => "---",
 | 
					 | 
				
			||||||
                        //'__paste' => "Paste from clipboard",
 | 
					 | 
				
			||||||
                    ], 'Insert');
 | 
					 | 
				
			||||||
                    $this->redrawInfoBar([ '^C' => 'Cancel', '↑/↓' => 'Select option', 'Enter' => 'Accept' ]);
 | 
					 | 
				
			||||||
                    $sel = $menu->display(0, 0, 30, 0, "value");
 | 
					 | 
				
			||||||
                    $this->redrawEditor();
 | 
					 | 
				
			||||||
                    switch ($sel) {
 | 
					 | 
				
			||||||
                        case 'value':
 | 
					 | 
				
			||||||
                            $this->doInsertValue();
 | 
					 | 
				
			||||||
                            $this->modified = true;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        case 'array':
 | 
					 | 
				
			||||||
                            $this->doInsertValue('[]');
 | 
					 | 
				
			||||||
                            $this->modified = true;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        case 'object':
 | 
					 | 
				
			||||||
                            $this->doInsertValue('{}');
 | 
					 | 
				
			||||||
                            $this->modified = true;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case 'H':
 | 
					                case 'H':
 | 
				
			||||||
@@ -204,33 +173,7 @@ class Editor
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case "\x18": // ctrl-x
 | 
					                case "\x18": // ctrl-x
 | 
				
			||||||
                    if ($this->modified) {
 | 
					                    $this->doExit();
 | 
				
			||||||
                        $menu = new Menu($this->term, [
 | 
					 | 
				
			||||||
                            'cancel' => "Return to editor",
 | 
					 | 
				
			||||||
                            'save' => "Save changes",
 | 
					 | 
				
			||||||
                            'discard' => "Discard changes",
 | 
					 | 
				
			||||||
                            //'sep0' => "---",
 | 
					 | 
				
			||||||
                            //'__paste' => "Paste from clipboard",
 | 
					 | 
				
			||||||
                        ], 'Document is modified');
 | 
					 | 
				
			||||||
                        $this->redrawInfoBar([ '^C' => 'Cancel', '↑/↓' => 'Select option', 'Enter' => 'Accept' ]);
 | 
					 | 
				
			||||||
                        $sel = $menu->display(0, 0, 30, 0, "value");
 | 
					 | 
				
			||||||
                        $this->redrawEditor();
 | 
					 | 
				
			||||||
                        switch ($sel) {
 | 
					 | 
				
			||||||
                            case 'cancel':
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                            case 'save':
 | 
					 | 
				
			||||||
                                if ($this->doWriteFile()) {
 | 
					 | 
				
			||||||
                                    $this->running = false;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                            case 'discard':
 | 
					 | 
				
			||||||
                                $this->running = false;
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        $this->running = false;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case "g":
 | 
					                case "g":
 | 
				
			||||||
@@ -495,17 +438,28 @@ class Editor
 | 
				
			|||||||
            $items = [
 | 
					            $items = [
 | 
				
			||||||
                dirname($wd) => sprintf(
 | 
					                dirname($wd) => sprintf(
 | 
				
			||||||
                    "%-30s %10s %20s",
 | 
					                    "%-30s %10s %20s",
 | 
				
			||||||
                    "Parent Directory",
 | 
					                    "<..>",
 | 
				
			||||||
                    "<DIR>",
 | 
					                    "<DIR>",
 | 
				
			||||||
                    "-"
 | 
					                    "-"
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
            $files = glob($wd."/*");
 | 
					            $files = glob($wd."/*");
 | 
				
			||||||
 | 
					            // do two sweeps, to sort directories.
 | 
				
			||||||
            foreach ($files as $file) {
 | 
					            foreach ($files as $file) {
 | 
				
			||||||
 | 
					                if (!is_dir($file)) continue;
 | 
				
			||||||
                $items[$file] = sprintf(
 | 
					                $items[$file] = sprintf(
 | 
				
			||||||
                    "%-30s %10s %20s",
 | 
					                    "%-30s %10s %20s",
 | 
				
			||||||
                    mb_substr(is_dir($file) ? ("<".basename($file).">") : (basename($file)), 0, 30),
 | 
					                    mb_substr("<".basename($file).">", 0, 30),
 | 
				
			||||||
                    is_dir($file) ? "<DIR>" : filesize($file),
 | 
					                    "<DIR>",
 | 
				
			||||||
 | 
					                    date("Y-m-d H:i:s", filemtime($file))
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach ($files as $file) {
 | 
				
			||||||
 | 
					                if (is_dir($file)) continue;
 | 
				
			||||||
 | 
					                $items[$file] = sprintf(
 | 
				
			||||||
 | 
					                    "%-30s %10s %20s",
 | 
				
			||||||
 | 
					                    mb_substr(basename($file), 0, 30),
 | 
				
			||||||
 | 
					                    filesize($file),
 | 
				
			||||||
                    date("Y-m-d H:i:s", filemtime($file))
 | 
					                    date("Y-m-d H:i:s", filemtime($file))
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -722,6 +676,32 @@ class Editor
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function doInsertMenu(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $menu = new Menu($this->term, [
 | 
				
			||||||
 | 
					            'value' => "Insert Value",
 | 
				
			||||||
 | 
					            'object' => "Insert Object{}",
 | 
				
			||||||
 | 
					            'array' => "Insert Array[]",
 | 
				
			||||||
 | 
					        ], 'Insert');
 | 
				
			||||||
 | 
					        $this->redrawInfoBar([ '^C' => 'Cancel', '↑/↓' => 'Select option', 'Enter' => 'Accept' ]);
 | 
				
			||||||
 | 
					        $sel = $menu->display(0, 0, 40, 0, "value");
 | 
				
			||||||
 | 
					        $this->redrawEditor();
 | 
				
			||||||
 | 
					        switch ($sel) {
 | 
				
			||||||
 | 
					            case 'value':
 | 
				
			||||||
 | 
					                $this->doInsertValue();
 | 
				
			||||||
 | 
					                $this->modified = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'array':
 | 
				
			||||||
 | 
					                $this->doInsertValue('[]');
 | 
				
			||||||
 | 
					                $this->modified = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'object':
 | 
				
			||||||
 | 
					                $this->doInsertValue('{}');
 | 
				
			||||||
 | 
					                $this->modified = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function doCollapseAll(): void
 | 
					    public function doCollapseAll(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        foreach ($this->list as $path => $entry) {
 | 
					        foreach ($this->list as $path => $entry) {
 | 
				
			||||||
@@ -741,6 +721,34 @@ class Editor
 | 
				
			|||||||
        $this->redrawEditor();
 | 
					        $this->redrawEditor();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function doExit(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->modified) {
 | 
				
			||||||
 | 
					            $menu = new Menu($this->term, [
 | 
				
			||||||
 | 
					                'cancel' => "Return to editor",
 | 
				
			||||||
 | 
					                'save' => "Save changes",
 | 
				
			||||||
 | 
					                'discard' => "Discard changes",
 | 
				
			||||||
 | 
					            ], 'Document is modified');
 | 
				
			||||||
 | 
					            $this->redrawInfoBar([ '^C' => 'Cancel', '↑/↓' => 'Select option', 'Enter' => 'Accept' ]);
 | 
				
			||||||
 | 
					            $sel = $menu->display(0, 0, 30, 0, "value");
 | 
				
			||||||
 | 
					            $this->redrawEditor();
 | 
				
			||||||
 | 
					            switch ($sel) {
 | 
				
			||||||
 | 
					                case 'cancel':
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'save':
 | 
				
			||||||
 | 
					                    if ($this->doWriteFile()) {
 | 
				
			||||||
 | 
					                        $this->running = false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'discard':
 | 
				
			||||||
 | 
					                    $this->running = false;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $this->running = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Ask for input
 | 
					     * Ask for input
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,15 +105,37 @@ class Menu
 | 
				
			|||||||
                    return array_keys($this->items)[$this->index];
 | 
					                    return array_keys($this->items)[$this->index];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if ($ch == "k{UP}") {
 | 
					                switch ($ch) {
 | 
				
			||||||
 | 
					                    case "k{UP}":
 | 
				
			||||||
                        $this->index--;
 | 
					                        $this->index--;
 | 
				
			||||||
                        if ($this->index < 0) $this->index = count($this->items) - 1;
 | 
					                        if ($this->index < 0) $this->index = count($this->items) - 1;
 | 
				
			||||||
                        $this->redraw($left, $top, $width, $height);
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
                } elseif ($ch == "k{DOWN}") {
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "k{DOWN}":
 | 
				
			||||||
                        $this->index++;
 | 
					                        $this->index++;
 | 
				
			||||||
                        if ($this->index >= count($this->items)) $this->index = 0;
 | 
					                        if ($this->index >= count($this->items)) $this->index = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                        $this->redraw($left, $top, $width, $height);
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "k{PGUP}":
 | 
				
			||||||
 | 
					                        $this->index -= $height - 2;
 | 
				
			||||||
 | 
					                        if ($this->index < 0) $this->index = count($this->items) - 1;
 | 
				
			||||||
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "k{PGDN}":
 | 
				
			||||||
 | 
					                        $this->index += $height - 2;
 | 
				
			||||||
 | 
					                        if ($this->index >= count($this->items)) $this->index = 0;
 | 
				
			||||||
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "k{HOME}":
 | 
				
			||||||
 | 
					                        $this->index = 0;
 | 
				
			||||||
 | 
					                        if ($this->index >= count($this->items)) $this->index = 0;
 | 
				
			||||||
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "k{END}":
 | 
				
			||||||
 | 
					                        $this->index = count($this->items) - 1;
 | 
				
			||||||
 | 
					                        if ($this->index >= count($this->items)) $this->index = 0;
 | 
				
			||||||
 | 
					                        $this->redraw($left, $top, $width, $height);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -146,7 +168,7 @@ class Menu
 | 
				
			|||||||
        $scrollTop = $this->scroll;
 | 
					        $scrollTop = $this->scroll;
 | 
				
			||||||
        $scrollBottom = $scrollTop + $visibleItems - 1;
 | 
					        $scrollBottom = $scrollTop + $visibleItems - 1;
 | 
				
			||||||
        $thumbTop = round(($visibleItems - 1) / count($this->items) * $scrollTop);
 | 
					        $thumbTop = round(($visibleItems - 1) / count($this->items) * $scrollTop);
 | 
				
			||||||
        $thumbBottom = round(($visibleItems - 1) / count($this->items) * $scrollBottom);
 | 
					        $thumbBottom = round(($visibleItems) / count($this->items) * $scrollBottom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $tleft = round(($width / 2) - ((mb_strlen($this->title) + 2) / 2));
 | 
					        $tleft = round(($width / 2) - ((mb_strlen($this->title) + 2) / 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,10 +27,26 @@ class MessageBox
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private int $scroll = 0;
 | 
					    private int $scroll = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * constructor
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Terminal $terminal
 | 
				
			||||||
 | 
					     * @param string $text
 | 
				
			||||||
 | 
					     * @param string $title
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function __construct(private Terminal $terminal, private string $text, private string $title = 'Message')
 | 
					    public function __construct(private Terminal $terminal, private string $text, private string $title = 'Message')
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Display the message box
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param int $left
 | 
				
			||||||
 | 
					     * @param int $top
 | 
				
			||||||
 | 
					     * @param int $width
 | 
				
			||||||
 | 
					     * @param int $height
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function display(int $left, int $top, int $width, int $height = 0): void
 | 
					    public function display(int $left, int $top, int $width, int $height = 0): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $wrapped = explode("\n", wordwrap($this->text, $width - 4, cut_long_words:true));
 | 
					        $wrapped = explode("\n", wordwrap($this->text, $width - 4, cut_long_words:true));
 | 
				
			||||||
@@ -76,6 +92,18 @@ class MessageBox
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Redraw the message box
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param int $left
 | 
				
			||||||
 | 
					     * @param int $top
 | 
				
			||||||
 | 
					     * @param int $width
 | 
				
			||||||
 | 
					     * @param int $height
 | 
				
			||||||
 | 
					     * @param array $wrapped
 | 
				
			||||||
 | 
					     * @param string $title
 | 
				
			||||||
 | 
					     * @param int $maxScroll
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private function redraw(int $left, int $top, int $width, int $height, array $wrapped, string $title, int $maxScroll) {
 | 
					    private function redraw(int $left, int $top, int $width, int $height, array $wrapped, string $title, int $maxScroll) {
 | 
				
			||||||
        $visibleItems = $height - 4;
 | 
					        $visibleItems = $height - 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user