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)

1  
sclass G22ManagedTextEditor<A extends G22Text> is Swingable {
2  
  settable G22Utils g22utils;
3  
  settable S noScriptSelectedMsg = "Please select or create a text to edit it";
4  
  
5  
  gettable A script;
6  
  
7  
  transient SingleComponentPanel scp;
8  
  transient JSyntaxTextFileEditor[] ides;
9  
  transient JExtendedTabbedPane tabs;
10  
  transient JButton btnSave, btnDiscardChanges, btnClearForAutoRun;
11  
  transient CollapsibleLeftPanel collapsibleResultPanel;
12  
  transient G22ScriptResultPanel resultPanel;
13  
  transient Mode lastVisibleMode;
14  
15  
  abstract class Mode {
16  
    G22ScriptMode modeEnum;
17  
    S name;
18  
    gettable bool editable;
19  
    
20  
    *(G22ScriptMode *modeEnum, S *name, bool *editable) {}
21  
    
22  
    simplyCached abstract IVarWithNotify<S> scriptVar();
23  
    
24  
    void addButtons(JPanel panel) {}
25  
    
26  
    toString { ret name; }
27  
    
28  
    S tabName() { ret scriptVar().has() ? name : "Not " + firstToLower(name); }
29  
  }
30  
  
31  
  class ModeClearedForAutoRun > Mode {
32  
    *() { super(G22ScriptMode.autoRunnable, "Cleared for auto-run", false); }
33  
    
34  
    IVarWithNotify<S> scriptVar_load() {
35  
      var var = new VirtualVar<S>(
36  
        -> script.codeForAutoRun(),
37  
        null /*text -> script.setClearedForAutoRun(text == null ?: new ClearForAutoRun(text))*/);
38  
      addWeakChangeListener(script.varClearedForAutoRun(), var);
39  
      ret var;
40  
    }
41  
    
42  
    void addButtons(JPanel panel) {
43  
      panel.add(jbutton("Forget auto-run code", rThread forgetAutoRunCode));
44  
    }
45  
  }
46  
  
47  
  class ModeSaved > Mode {
48  
    *() { super(G22ScriptMode.saved, "Saved", false); }
49  
    
50  
    IVarWithNotify<S> scriptVar_load() {
51  
      ret getterVarOnly(script.varText());
52  
    }
53  
    
54  
    void addButtons(JPanel panel) {
55  
      panel.add(btnClearForAutoRun = jbutton("Clear for auto-run", rThread clearForAutoRun));
56  
      panel.add(jbutton("Forget code", rThread forgetSaved));
57  
    }
58  
  }
59  
  
60  
  class ModeEdit > Mode {
61  
    *() { super(G22ScriptMode.edit, "Edit", true); }
62  
    
63  
    IVarWithNotify<S> scriptVar_load() {
64  
      var var = new VirtualVar<S>(
65  
        -> script.textForEditing(),
66  
        text -> script.receiveEditingText(text)
67  
      );
68  
      addWeakChangeListener(script, var);
69  
      ret var;
70  
    }
71  
    
72  
    void addButtons(JPanel panel) {
73  
      panel.add(btnSave = jbutton("Save", rThread saveEdit));
74  
      panel.add(btnDiscardChanges = jbutton("Discard changes", rThread discardEdit));
75  
    }
76  
  }
77  
  
78  
  transient new ModeEdit modeEdit;
79  
  transient new ModeSaved modeSaved;
80  
  transient L<Mode> modes = ll(
81  
    modeEdit,
82  
    modeSaved
83  
  );
84  
  
85  
  *(G22Utils *g22utils) {}
86  
  
87  
  cachedVisualize {
88  
    ides = new JSyntaxTextFileEditor[l(modes)];
89  
    if (scp == null) scp = singleComponentPanel();
90  
    loadScript(script);
91  
    ret scp;
92  
  }
93  
  
94  
  void setScript(A script) {
95  
    if (this.script != script)
96  
      if (this.script != null)
97  
        fail("Can't set script after initialisation");
98  
      else
99  
        loadScript(script);
100  
  }
101  
  
102  
  void loadScript(A script) {
103  
    this.script = script;
104  
    if (scp == null) ret;
105  
    if (script == null)
106  
      scp.set(jcenteredlabel(noScriptSelectedMsg()));
107  
    else {
108  
      tabs = jExtendedTabs();
109  
      resultPanel = new G22ScriptResultPanel;
110  
      collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), tabs.visualize());
111  
      collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c);
112  
      
113  
      // This places tabs vertically at the right hand side...
114  
      // (not what we want)
115  
      //setTabPlacement(JTabbedPane.RIGHT, tabs);
116  
      
117  
      for (int i, Mode mode : unpair iterateWithIndex(modes)) {
118  
        var ide = ides[i] = new JSyntaxTextFileEditor;
119  
        ide.withResultPanel(false);
120  
        ide.resultPanel = resultPanel;
121  
        ide.collapsibleResultPanel = collapsibleResultPanel;
122  
        ide.wrapSection = c -> wrapEditorSection(mode, c);
123  
        ide.newCompileResult = -> script.newCompileResult();
124  
        ide.makeParser = -> script.makeParser();
125  
        modifyIDE(ide);
126  
        var varScript = mode.scriptVar();
127  
        ide.lvScript(varWithNotifyToLiveValue(S.class, varScript));
128  
        addTab(tabs, str(mode));
129  
        mode.addButtons(ide.buttons());
130  
        ide.visualize();
131  
        ide.setEditable(mode.editable());
132  
        varScript.onChangeAndNow(text ->
133  
          setTab(tabs, i, text == null ? jcenteredlabel("Empty") : wrapIDE(mode, ide)));
134  
        ide.popDownButton.onFillingMenu(menu ->
135  
          addMenuItem(menu, "Show History", rThread showHistory));
136  
      }
137  
      
138  
      script.onChangeAndNow(r {
139  
        for (int i, Mode mode : unpair iterateWithIndex(modes))
140  
          setTabTitle(tabs, i, mode.tabName());
141  
        setEnabled(script.isEditing(), btnSave, btnDiscardChanges);
142  
        setEnabled(btnClearForAutoRun, script.isSavedDistinctFromAutoRunVersion());
143  
        for (ide : ides)
144  
          ide.sectionTitle(str(script));
145  
      });
146  
      
147  
      onTabSelectedAndNow(tabs, -> {
148  
        var mode = visibleMode();
149  
        if (lastVisibleMode != null && lastVisibleMode != mode) {
150  
          // Move selected IDE to same position as previous IDE
151  
          
152  
          var lastIDE = ide(lastVisibleMode);
153  
          var ide = visibleIDE();
154  
          awtLater(0.5, -> {
155  
            LineAndColumn lac = caretLineAndCol(lastIDE.textArea());
156  
            moveCaretToLineAndCol(ide.textArea(), lac);
157  
            setEnclosingViewPosition(ide.textArea(), enclosingViewPosition(lastIDE.textArea()));
158  
            focus(ide.textArea());
159  
          });
160  
        }
161  
        lastVisibleMode = mode;
162  
        
163  
        tabs.setComponentBesideTabs(
164  
          mode != modeEdit
165  
            ? jfullcenter(withRightMargin(jbutton("Edit script", -> setMode(modeEdit))))
166  
            : null);
167  
      });
168  
169  
      setMode(script.isEditing() ? modeEdit : modeSaved);
170  
      scp.set(collapsibleResultPanel);
171  
    }
172  
  }
173  
  
174  
  swappable JComponent wrapEditorSection(Mode mode, JComponent editorSection) {
175  
    /*if (mode != modeEdit)
176  
      ret withTopMargin(northAndCenterWithMargin(
177  
        withRightMargin(jline(jbutton("Edit script", -> setMode(modeEdit)))),
178  
        editorSection));
179  
    else*/
180  
      ret editorSection;
181  
  }
182  
  
183  
  swappable JComponent wrapIDE(Mode mode, JSyntaxTextFileEditor ide) {
184  
    ret ide.visualize();
185  
  }
186  
  
187  
  void saveEdit {
188  
    script.completeEdit();
189  
    setMode(modeSaved);
190  
  }
191  
  
192  
  JSyntaxTextFileEditor ide(Mode mode) {
193  
    if (ides == null) visualize();
194  
    ret _get(ides, indexOf(modes, mode));
195  
  }
196  
  
197  
  RSyntaxTextArea visibleTextArea() {
198  
    var ide = visibleIDE();
199  
    ret ide?.textArea();
200  
  }
201  
  
202  
  void setMode(Mode mode) {
203  
    var caretPos = caretLineAndCol(visibleTextArea());
204  
    printVars("setMode", +caretPos);
205  
    selectTab(tabs, indexOf(modes, mode));
206  
    var ide = visibleIDE();
207  
    printVars("setMode", +ide, mode := visibleMode());
208  
    ide.goToPosition_noFocus(caretPos);
209  
    if (mode == modeEdit)
210  
      focus(visibleTextArea());
211  
  }
212  
  
213  
  // get currently visible mode
214  
  Mode visibleMode() {
215  
    ret _get(modes, indexOfSelectedTab(tabs));
216  
  }
217  
  
218  
  JSyntaxTextFileEditor visibleIDE() {
219  
    ret ide(visibleMode());
220  
  }
221  
  
222  
  void discardEdit {
223  
    setMode(modeSaved);
224  
    script.discardEdit();
225  
  }
226  
  
227  
  void forgetSaved {
228  
    script.setTextWithHistory(null);
229  
  }
230  
  
231  
  void clearForAutoRun {
232  
    script.clearForAutoRun();
233  
    setMode(modeClearedForAutoRun);
234  
  }
235  
  
236  
  void forgetAutoRunCode {
237  
    script.forgetAutoRunCode();
238  
  }
239  
  
240  
  private void selfTest_impl {
241  
    new G22Text script;
242  
    setScript((A) script);
243  
    ide(modeEdit).setText("hello");
244  
    assertEqualsVerbose(null, script.text());
245  
    assertEqualsVerbose("hello", script.editedText());
246  
    saveEdit();
247  
    assertEqualsVerbose("hello", script.text());
248  
    assertEqualsVerbose(null, script.editedText());
249  
  }
250  
  
251  
  static void selfTest(G22Utils g22utils) {
252  
    new G22ManagedTextEditor(g22utils).selfTest_impl();
253  
  }
254  
  
255  
  void showHistory {
256  
    showText("Edit history of " + script, loadTextFile(script.historyFile()));
257  
  }
258  
  
259  
  void goToPositionInAllModes(LineAndColumn lac) {
260  
    for (ide : ides)
261  
      ide?.goToPosition_noFocus(lac);
262  
  }
263  
}

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: 150 / 158
Referenced in: [show references]