Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

263
LINES

< > BotCompany Repo | #1036610 // G22ManagedTextEditor - for G22Text [dev.]

JavaX fragment (include)

sclass G22ManagedTextEditor<A extends G22Text> is Swingable {
  settable G22Utils g22utils;
  settable S noScriptSelectedMsg = "Please select or create a text to edit it";
  
  gettable A script;
  
  transient SingleComponentPanel scp;
  transient JSyntaxTextFileEditor[] ides;
  transient JExtendedTabbedPane tabs;
  transient JButton btnSave, btnDiscardChanges, btnClearForAutoRun;
  transient CollapsibleLeftPanel collapsibleResultPanel;
  transient G22ScriptResultPanel resultPanel;
  transient Mode lastVisibleMode;

  abstract class Mode {
    G22ScriptMode modeEnum;
    S name;
    gettable bool editable;
    
    *(G22ScriptMode *modeEnum, S *name, bool *editable) {}
    
    simplyCached abstract IVarWithNotify<S> scriptVar();
    
    void addButtons(JPanel panel) {}
    
    toString { ret name; }
    
    S tabName() { ret scriptVar().has() ? name : "Not " + firstToLower(name); }
  }
  
  class ModeClearedForAutoRun > Mode {
    *() { super(G22ScriptMode.autoRunnable, "Cleared for auto-run", false); }
    
    IVarWithNotify<S> scriptVar_load() {
      var var = new VirtualVar<S>(
        -> script.codeForAutoRun(),
        null /*text -> script.setClearedForAutoRun(text == null ?: new ClearForAutoRun(text))*/);
      addWeakChangeListener(script.varClearedForAutoRun(), var);
      ret var;
    }
    
    void addButtons(JPanel panel) {
      panel.add(jbutton("Forget auto-run code", rThread forgetAutoRunCode));
    }
  }
  
  class ModeSaved > Mode {
    *() { super(G22ScriptMode.saved, "Saved", false); }
    
    IVarWithNotify<S> scriptVar_load() {
      ret getterVarOnly(script.varText());
    }
    
    void addButtons(JPanel panel) {
      panel.add(btnClearForAutoRun = jbutton("Clear for auto-run", rThread clearForAutoRun));
      panel.add(jbutton("Forget code", rThread forgetSaved));
    }
  }
  
  class ModeEdit > Mode {
    *() { super(G22ScriptMode.edit, "Edit", true); }
    
    IVarWithNotify<S> scriptVar_load() {
      var var = new VirtualVar<S>(
        -> script.textForEditing(),
        text -> script.receiveEditingText(text)
      );
      addWeakChangeListener(script, var);
      ret var;
    }
    
    void addButtons(JPanel panel) {
      panel.add(btnSave = jbutton("Save", rThread saveEdit));
      panel.add(btnDiscardChanges = jbutton("Discard changes", rThread discardEdit));
    }
  }
  
  transient new ModeEdit modeEdit;
  transient new ModeSaved modeSaved;
  transient L<Mode> modes = ll(
    modeEdit,
    modeSaved
  );
  
  *(G22Utils *g22utils) {}
  
  cachedVisualize {
    ides = new JSyntaxTextFileEditor[l(modes)];
    if (scp == null) scp = singleComponentPanel();
    loadScript(script);
    ret scp;
  }
  
  void setScript(A script) {
    if (this.script != script)
      if (this.script != null)
        fail("Can't set script after initialisation");
      else
        loadScript(script);
  }
  
  void loadScript(A script) {
    this.script = script;
    if (scp == null) ret;
    if (script == null)
      scp.set(jcenteredlabel(noScriptSelectedMsg()));
    else {
      tabs = jExtendedTabs();
      resultPanel = new G22ScriptResultPanel;
      collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), tabs.visualize());
      collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c);
      
      // This places tabs vertically at the right hand side...
      // (not what we want)
      //setTabPlacement(JTabbedPane.RIGHT, tabs);
      
      for (int i, Mode mode : unpair iterateWithIndex(modes)) {
        var ide = ides[i] = new JSyntaxTextFileEditor;
        ide.withResultPanel(false);
        ide.resultPanel = resultPanel;
        ide.collapsibleResultPanel = collapsibleResultPanel;
        ide.wrapSection = c -> wrapEditorSection(mode, c);
        ide.newCompileResult = -> script.newCompileResult();
        ide.makeParser = -> script.makeParser();
        modifyIDE(ide);
        var varScript = mode.scriptVar();
        ide.lvScript(varWithNotifyToLiveValue(S.class, varScript));
        addTab(tabs, str(mode));
        mode.addButtons(ide.buttons());
        ide.visualize();
        ide.setEditable(mode.editable());
        varScript.onChangeAndNow(text ->
          setTab(tabs, i, text == null ? jcenteredlabel("Empty") : wrapIDE(mode, ide)));
        ide.popDownButton.onFillingMenu(menu ->
          addMenuItem(menu, "Show History", rThread showHistory));
      }
      
      script.onChangeAndNow(r {
        for (int i, Mode mode : unpair iterateWithIndex(modes))
          setTabTitle(tabs, i, mode.tabName());
        setEnabled(script.isEditing(), btnSave, btnDiscardChanges);
        setEnabled(btnClearForAutoRun, script.isSavedDistinctFromAutoRunVersion());
        for (ide : ides)
          ide.sectionTitle(str(script));
      });
      
      onTabSelectedAndNow(tabs, -> {
        var mode = visibleMode();
        if (lastVisibleMode != null && lastVisibleMode != mode) {
          // Move selected IDE to same position as previous IDE
          
          var lastIDE = ide(lastVisibleMode);
          var ide = visibleIDE();
          awtLater(0.5, -> {
            LineAndColumn lac = caretLineAndCol(lastIDE.textArea());
            moveCaretToLineAndCol(ide.textArea(), lac);
            setEnclosingViewPosition(ide.textArea(), enclosingViewPosition(lastIDE.textArea()));
            focus(ide.textArea());
          });
        }
        lastVisibleMode = mode;
        
        tabs.setComponentBesideTabs(
          mode != modeEdit
            ? jfullcenter(withRightMargin(jbutton("Edit script", -> setMode(modeEdit))))
            : null);
      });

      setMode(script.isEditing() ? modeEdit : modeSaved);
      scp.set(collapsibleResultPanel);
    }
  }
  
  swappable JComponent wrapEditorSection(Mode mode, JComponent editorSection) {
    /*if (mode != modeEdit)
      ret withTopMargin(northAndCenterWithMargin(
        withRightMargin(jline(jbutton("Edit script", -> setMode(modeEdit)))),
        editorSection));
    else*/
      ret editorSection;
  }
  
  swappable JComponent wrapIDE(Mode mode, JSyntaxTextFileEditor ide) {
    ret ide.visualize();
  }
  
  void saveEdit {
    script.completeEdit();
    setMode(modeSaved);
  }
  
  JSyntaxTextFileEditor ide(Mode mode) {
    if (ides == null) visualize();
    ret _get(ides, indexOf(modes, mode));
  }
  
  RSyntaxTextArea visibleTextArea() {
    var ide = visibleIDE();
    ret ide?.textArea();
  }
  
  void setMode(Mode mode) {
    var caretPos = caretLineAndCol(visibleTextArea());
    printVars("setMode", +caretPos);
    selectTab(tabs, indexOf(modes, mode));
    var ide = visibleIDE();
    printVars("setMode", +ide, mode := visibleMode());
    ide.goToPosition_noFocus(caretPos);
    if (mode == modeEdit)
      focus(visibleTextArea());
  }
  
  // get currently visible mode
  Mode visibleMode() {
    ret _get(modes, indexOfSelectedTab(tabs));
  }
  
  JSyntaxTextFileEditor visibleIDE() {
    ret ide(visibleMode());
  }
  
  void discardEdit {
    setMode(modeSaved);
    script.discardEdit();
  }
  
  void forgetSaved {
    script.setTextWithHistory(null);
  }
  
  void clearForAutoRun {
    script.clearForAutoRun();
    setMode(modeClearedForAutoRun);
  }
  
  void forgetAutoRunCode {
    script.forgetAutoRunCode();
  }
  
  private void selfTest_impl {
    new G22Text script;
    setScript((A) script);
    ide(modeEdit).setText("hello");
    assertEqualsVerbose(null, script.text());
    assertEqualsVerbose("hello", script.editedText());
    saveEdit();
    assertEqualsVerbose("hello", script.text());
    assertEqualsVerbose(null, script.editedText());
  }
  
  static void selfTest(G22Utils g22utils) {
    new G22ManagedTextEditor(g22utils).selfTest_impl();
  }
  
  void showHistory {
    showText("Edit history of " + script, loadTextFile(script.historyFile()));
  }
  
  void goToPositionInAllModes(LineAndColumn lac) {
    for (ide : ides)
      ide?.goToPosition_noFocus(lac);
  }
}

Author comment

Began life as a copy of #1034345

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj

No comments. add comment

-
Snippet ID: #1036610
Snippet name: G22ManagedTextEditor - for G22Text [dev.]
Eternal ID of this version: #1036610/1
Text MD5: 83fd872587802219732748e86b1c9143
Author: stefan
Category: javax / gazelle 22
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-04-27 18:47:50
Source code size: 8240 bytes / 263 lines
Pitched / IR pitched: No / No
Views / Downloads: 151 / 159
Referenced in: