Skip to content

Commit

Permalink
webview keypress + js string callback
Browse files Browse the repository at this point in the history
  • Loading branch information
elgiano committed Jul 21, 2020
1 parent 573b6ec commit da4ca3f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 56 deletions.
4 changes: 3 additions & 1 deletion HelpSource/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const init = () => {
lineWrapping: true,
viewportMargin: Infinity,
extraKeys: {
'Shift-Enter': evalLine
'Shift-Enter': ()=>false,
'Ctrl-D': false
}
})

Expand All @@ -59,6 +60,7 @@ const init = () => {

}

// UNUSED
const evalLine = () => {
// If we are not running in the SC IDE, do nothing.
if (!window.IDE) {
Expand Down
55 changes: 30 additions & 25 deletions QtCollider/widgets/QcWebView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ QC_DECLARE_QWIDGET_FACTORY(WebView);

namespace QtCollider {

WebView::WebView(QWidget* parent): QWebEngineView(parent), _interpretSelection(false), _editable(false) {
WebView::WebView(QWidget* parent): QWebEngineView(parent), _editable(false) {
QtCollider::WebPage* page = new WebPage(this);
page->setDelegateReload(true);
setPage(page);
connectPage(page);

Expand All @@ -55,9 +54,7 @@ WebView::WebView(QWidget* parent): QWebEngineView(parent), _interpretSelection(f
page->action(QWebEnginePage::Paste)->setShortcut(QKeySequence::Paste);
page->action(QWebEnginePage::Reload)->setShortcut(QKeySequence::Refresh);

connect(this, SIGNAL(interpret(QString)), qApp, SLOT(interpret(QString)), Qt::QueuedConnection);

connect(this, SIGNAL(loadFinished(bool)), this, SLOT(updateEditable(bool)));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded(bool)));
}

void WebView::connectPage(QtCollider::WebPage* page) {
Expand Down Expand Up @@ -159,7 +156,8 @@ void WebView::toPlainText(QcCallback* cb) const {
void WebView::runJavaScript(const QString& script, QcCallback* cb) {
if (page()) {
if (cb) {
page()->runJavaScript(script, cb->asFunctor());
// convert QVariant to string until we deal with QVariants
page()->runJavaScript(script, [cb](const QVariant& t) { cb->call(t.toString()); });
} else {
page()->runJavaScript(script, [](const QVariant&) {});
}
Expand Down Expand Up @@ -228,29 +226,36 @@ void WebView::contextMenuEvent(QContextMenuEvent* event) {
menu.exec(event->globalPos());
}

void WebView::keyPressEvent(QKeyEvent* e) {
int key = e->key();
int mods = e->modifiers();

if (_interpretSelection
&& (key == Qt::Key_Enter || (key == Qt::Key_Return && mods & (Qt::ControlModifier | Qt::ShiftModifier)))) {
QString selection = selectedText();
if (!selection.isEmpty()) {
Q_EMIT(interpret(selection));
return;
}
// webView's renderer keypresses don't arrive to webView
// duplicate them
bool WebView::eventFilter(QObject* obj, QEvent* event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
QKeyEvent* newEvent =
new QKeyEvent(QEvent::KeyPress, keyEvent->key(), keyEvent->modifiers(), keyEvent->nativeScanCode(),
keyEvent->nativeVirtualKey(), keyEvent->nativeModifiers(), keyEvent->text());
QApplication::postEvent(this, newEvent);
}

QWebEngineView::keyPressEvent(e);
event->ignore();
return false;
}

void WebView::updateEditable(bool ok) {
if (ok) {
if (_editable) {
page()->runJavaScript("document.documentElement.contentEditable = true");
} else {
page()->runJavaScript("document.documentElement.contentEditable = false");
}
// stop keypresses here to avoid duplicates in parents
bool WebView::event(QEvent* ev) {
if (ev->type() == QEvent::KeyPress)
return true;

return QWebEngineView::event(ev);
}

void WebView::pageLoaded(bool ok) { this->focusProxy()->installEventFilter(this); }

void WebView::updateEditable() {
if (_editable) {
page()->runJavaScript("document.documentElement.contentEditable = true");
} else {
page()->runJavaScript("document.documentElement.contentEditable = false");
}
}

Expand Down
18 changes: 7 additions & 11 deletions QtCollider/widgets/QcWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class WebView : public QWebEngineView {

public:
Q_INVOKABLE void setFontFamily(int genericFontFamily, const QString& fontFamily);
Q_INVOKABLE void triggerPageAction(int action, bool checked);
Q_INVOKABLE void triggerPageAction(int action, bool checked = false);
Q_INVOKABLE QAction* pageAction(QWebEnginePage::WebAction) const;

// QWebEnginePage forwards
Expand All @@ -58,13 +58,12 @@ class WebView : public QWebEngineView {
Q_INVOKABLE void navigate(const QString& url);

public Q_SLOTS:
void findText(const QString& searchText, bool reversed, QtCollider::QcCallback* cb);
void findText(const QString& searchText, bool reversed, QcCallback* cb = nullptr);

Q_SIGNALS:
void linkActivated(const QString&, int, bool);
void jsConsoleMsg(const QString&, int, const QString&);
void reloadTriggered(const QString&);
void interpret(const QString& code);

// QWebEnginePage forwards
void linkHovered(const QString& url);
Expand Down Expand Up @@ -99,15 +98,11 @@ public Q_SLOTS:
bool delegateReload() const;
void setDelegateReload(bool);

Q_PROPERTY(bool enterInterpretsSelection READ interpretSelection WRITE setInterpretSelection);
bool interpretSelection() const { return _interpretSelection; }
void setInterpretSelection(bool b) { _interpretSelection = b; }

Q_PROPERTY(bool editable READ editable WRITE setEditable);
bool editable() const { return _editable; }
void setEditable(bool b) {
_editable = b;
updateEditable(true);
updateEditable();
}

// QWebEnginePage properties
Expand Down Expand Up @@ -140,19 +135,20 @@ public Q_SLOTS:
inline static QUrl urlFromString(const QString& str) { return QUrl::fromUserInput(str); }

protected:
virtual void keyPressEvent(QKeyEvent*);
virtual void contextMenuEvent(QContextMenuEvent*);
virtual bool event(QEvent* ev);
virtual bool eventFilter(QObject* obj, QEvent* event);

public Q_SLOTS:
void onPageReload();
void onRenderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus, int);
void onLinkClicked(const QUrl&, QWebEnginePage::NavigationType, bool);
void updateEditable(bool);
void updateEditable();
void pageLoaded(bool);

private:
void connectPage(QtCollider::WebPage* page);

bool _interpretSelection;
bool _editable;
};

Expand Down
25 changes: 21 additions & 4 deletions SCClassLibrary/Common/GUI/Base/QWebView.sc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WebView : View {

var <onLoadFinished, <onLoadFailed, <onLoadProgress, <onLoadStarted, <onLinkActivated, <onLinkHovered, <onReloadTriggered, <onJavaScriptMsg,
<onSelectionChanged, <onTitleChanged, <onUrlChanged, <onScrollPositionChanged, <onContentsSizeChanged, <onAudioMutedChanged,
<onRecentlyAudibleChanged;
<onRecentlyAudibleChanged, <enterInterpretsSelection;

*qtClass { ^'QtCollider::WebView'; }

Expand Down Expand Up @@ -107,6 +107,7 @@ WebView : View {
onReloadTriggered = func;
}

// this function is called by a javascript callback: see enterInterpretsSelection below
onInterpret {
|code|
code.interpret();
Expand Down Expand Up @@ -223,9 +224,25 @@ WebView : View {
url { ^this.getProperty('url') }
url_ { |url| this.setProperty('url', url) }

enterInterpretsSelection { ^this.getProperty('enterInterpretsSelection') }
enterInterpretsSelection_ { |b| this.setProperty('enterInterpretsSelection', b) }

enterInterpretsSelection_ { |b|
enterInterpretsSelection = b;
if(enterInterpretsSelection){
this.keyDownAction = { arg view, char, mods, u, keycode, key;
// 01000004 is Qt's keycode for Enter, needed on Mac
if((char.ascii==13).or(key.asHexString == "01000004")){
if(mods.isShift){
view.runJavaScript("selectLine()",this.onInterpret(_));
}{
if(mods.isCtrl || mods.isCmd) {
view.runJavaScript("selectRegion()",this.onInterpret(_));
};
}
}
};
}{
this.keyDownAction = {}
}
}
editable { ^this.getProperty('editable') }
editable_ { |b| this.setProperty('editable', b) }

Expand Down
25 changes: 10 additions & 15 deletions SCClassLibrary/Common/GUI/tools/HelpBrowser.sc
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ HelpBrowser {
.resize_(1)
.string_(str)
.value_(openNewWin)
.action_({ |b| openNewWin = b.value; webView.overrideNavigation = openNewWin; });
.action_({ |b| openNewWin = b.value; });
} {
str = "Open links in same window";
w = str.bounds.width + 5;
Button.new( window, Rect(x, y, w, h) )
.resize_(1)
.states_([[str],["Open links in new window"]])
.value_(openNewWin.asInteger)
.action_({ |b| openNewWin = b.value.asBoolean; webView.overrideNavigation = openNewWin; });
.action_({ |b| openNewWin = b.value.asBoolean; });
};

x = 0;
Expand Down Expand Up @@ -223,6 +223,8 @@ HelpBrowser {
{ "Monospace" }
));

webView.overrideNavigation = true;

webView.onLoadFinished = {
this.stopAnim;
window.name = "SuperCollider Help: %".format(webView.title);
Expand All @@ -233,16 +235,13 @@ HelpBrowser {
webView.onLinkActivated = {|wv, url|
var redirected, newPath, oldPath;
redirected = this.redirectTextFile(url);

if (not(redirected)) {
if(openNewWin) {
#newPath, oldPath = [url,webView.url].collect {|x|
if(x.notEmpty) {x.findRegexp("(^\\w+://)?([^#]+)(#.*)?")[1..].flop[1][1]}
};

#newPath, oldPath = [url,webView.url].collect {|x|
if(x.notEmpty) {x.findRegexp("(^\\w+://)?([^#]+)(#.*)?")[1..].flop[1][1]}
};
if(newPath!=oldPath) {
HelpBrowser.new(newWin:true).goTo(url);

if(newPath!=oldPath && openNewWin) {
HelpBrowser.new(newWin:openNewWin).goTo(url);
} {
this.goTo(url);
};
Expand Down Expand Up @@ -272,11 +271,7 @@ HelpBrowser {
};

webView.enterInterpretsSelection = true;
webView.keyDownAction = { arg view, char, mods;
if( (char.ascii == 13) && (mods.isCtrl || mods.isCmd || mods.isShift) ) {
view.tryPerform(\evaluateJavaScript,"selectLine()");
};
};

window.view.keyDownAction = { arg view, char, mods, uni, kcode, key;
var keyPlus, keyZero, keyMinus, keyEquals, keyF;
var modifier, zoomIn;
Expand Down

0 comments on commit da4ca3f

Please sign in to comment.