Qt spinner (#2494)

* move android spinner

* qt spinner

* rotation

* nothing by default

* spin spin

* fix rotate

* style

* spinner for all

* -2

* unused
albatross
Adeeb Shihadeh 2020-11-06 18:44:04 -08:00 committed by GitHub
parent c6e1beb402
commit 6c86afee16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 192 additions and 68 deletions

View File

@ -4,17 +4,14 @@ from common.basedir import BASEDIR
class Spinner():
def __init__(self, noop=False):
# spinner is currently only implemented for android
self.spinner_proc = None
if not noop:
try:
self.spinner_proc = subprocess.Popen(["./spinner"],
stdin=subprocess.PIPE,
cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"),
close_fds=True)
except OSError:
self.spinner_proc = None
def __init__(self):
try:
self.spinner_proc = subprocess.Popen(["./spinner"],
stdin=subprocess.PIPE,
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
close_fds=True)
except OSError:
self.spinner_proc = None
def __enter__(self):
return self

View File

@ -7,8 +7,6 @@ from common.basedir import BASEDIR
class TextWindow:
def __init__(self, text):
# text window is only implemented for android currently
self.text_proc = None
try:
self.text_proc = subprocess.Popen(["./text", text],
stdin=subprocess.PIPE,

View File

@ -219,8 +219,6 @@ selfdrive/common/visionbuf.h
selfdrive/common/visionbuf_ion.c
selfdrive/common/visionimg.cc
selfdrive/common/visionimg.h
selfdrive/common/spinner.c
selfdrive/common/spinner.h
selfdrive/common/gpio.cc
selfdrive/common/gpio.h
@ -344,9 +342,11 @@ selfdrive/ui/SConscript
selfdrive/ui/*.cc
selfdrive/ui/*.hpp
selfdrive/ui/ui
selfdrive/ui/spinner/Makefile
selfdrive/ui/spinner/spinner
selfdrive/ui/spinner/spinner.c
selfdrive/ui/text
selfdrive/ui/spinner
selfdrive/ui/android/spinner/Makefile
selfdrive/ui/android/spinner/spinner
selfdrive/ui/android/spinner/spinner.c
selfdrive/ui/android/text/Makefile
selfdrive/ui/android/text/text

View File

@ -8,7 +8,6 @@ from functools import wraps
import cereal.messaging as messaging
from cereal import car
from common.basedir import BASEDIR
from common.hardware import ANDROID
from common.params import Params
from common.spinner import Spinner
from panda import Panda
@ -36,7 +35,7 @@ os.environ['BASEDIR'] = BASEDIR
@with_processes(['boardd'])
def test_boardd_loopback():
# wait for boardd to init
spinner = Spinner(noop=(not ANDROID))
spinner = Spinner()
time.sleep(2)
# boardd blocks on CarVin and CarParams

View File

@ -1,14 +0,0 @@
#ifndef COMMON_SPINNER_H
#define COMMON_SPINNER_H
#ifdef __cplusplus
extern "C" {
#endif
int spin(int argc, char** argv);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -78,7 +78,7 @@ import traceback
from multiprocessing import Process
# Run scons
spinner = Spinner(noop=(__name__ != "__main__" or not ANDROID))
spinner = Spinner()
spinner.update("0")
if not prebuilt:
@ -138,7 +138,6 @@ if not prebuilt:
cloudlog.error("scons build failed\n" + error_s)
# Show TextWindow
no_ui = __name__ != "__main__" or not ANDROID
error_s = "\n \n".join(["\n".join(textwrap.wrap(e, 65)) for e in errors])
with TextWindow("openpilot failed to build\n \n" + error_s) as t:
t.wait_for_exit()

View File

@ -1,2 +1,5 @@
moc_*
*.moc
qt/text
qt/spinner

View File

@ -72,5 +72,6 @@ else:
qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc"] + src
qt_env.Program("_ui", qt_src, LIBS=qt_libs + libs)
# text window
# spinner and text window
qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs + libs)
qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs + libs)

View File

@ -1,7 +1,9 @@
CC = clang
CXX = clang++
PHONELIBS = ../../../phonelibs
ROOT_DIR = ../../..
PHONELIBS = $(ROOT_DIR)/phonelibs
COMMON = $(ROOT)/selfdrive/common
WARN_FLAGS = -Werror=implicit-function-declaration \
-Werror=incompatible-pointer-types \
@ -19,10 +21,10 @@ OPENGL_LIBS = -lGLESv3
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
OBJS = spinner.o \
../../common/framebuffer.o \
../../common/util.o \
$(COMMON)/framebuffer.o \
$(COMMON)/util.o \
$(PHONELIBS)/nanovg/nanovg.o \
../../common/spinner.o \
$(COMMON)/spinner.o \
opensans_semibold.o \
img_spinner_track.o \
img_spinner_comma.o
@ -41,7 +43,7 @@ spinner: $(OBJS)
$(OPENGL_LIBS) \
-lm -llog
../../common/framebuffer.o: ../../common/framebuffer.cc
$(COMMON)/framebuffer.o: $(COMMON)/framebuffer.cc
@echo "[ CXX ] $@"
$(CXX) $(CXXFLAGS) -MMD \
-I$(PHONELIBS)/android_frameworks_native/include \
@ -49,15 +51,15 @@ spinner: $(OBJS)
-I$(PHONELIBS)/android_hardware_libhardware/include \
-c -o '$@' '$<'
opensans_semibold.o: ../../assets/fonts/opensans_semibold.ttf
opensans_semibold.o: $(ROOT_DIR)/selfdrive/assets/fonts/opensans_semibold.ttf
@echo "[ bin2o ] $@"
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
img_spinner_track.o: ../../assets/img_spinner_track.png
img_spinner_track.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_track.png
@echo "[ bin2o ] $@"
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
img_spinner_comma.o: ../../assets/img_spinner_comma.png
img_spinner_comma.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_comma.png
@echo "[ bin2o ] $@"
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'

View File

@ -42,8 +42,7 @@ bool stdin_input_available() {
return (FD_ISSET(0, &fds));
}
int spin(int argc, char** argv) {
int err;
int main(int argc, char** argv) {
bool draw_progress = false;
float progress_val = 0.0;

View File

@ -0,0 +1,126 @@
#include <stdio.h>
#include <string>
#include <iostream>
#include <QString>
#include <QGridLayout>
#include <QApplication>
#include <QDesktopWidget>
#ifdef QCOM2
#include <qpa/qplatformnativeinterface.h>
#include <QPlatformSurfaceEvent>
#include <wayland-client-protocol.h>
#endif
#include "spinner.hpp"
Spinner::Spinner(QWidget *parent) {
QGridLayout *main_layout = new QGridLayout();
main_layout->setSpacing(0);
main_layout->setMargin(50);
const int img_size = 500;
comma = new QLabel();
comma->setPixmap(QPixmap("../assets/img_spinner_comma.png").scaled(img_size, img_size, Qt::KeepAspectRatio));
comma->setFixedSize(img_size, img_size);
main_layout->addWidget(comma, 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
track_img = QPixmap("../assets/img_spinner_track.png").scaled(img_size, img_size, Qt::KeepAspectRatio);
track = new QLabel();
track->setPixmap(track_img);
track->setFixedSize(img_size, img_size);
main_layout->addWidget(track, 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
text = new QLabel("building boardd");
text->setVisible(false);
text->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
main_layout->addWidget(text, 1, 0, Qt::AlignHCenter);
progress_bar = new QProgressBar();
progress_bar->setMinimum(5);
progress_bar->setMaximum(100);
progress_bar->setTextVisible(false);
progress_bar->setVisible(false);
progress_bar->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
main_layout->addWidget(progress_bar, 1, 0, Qt::AlignHCenter);
setLayout(main_layout);
setStyleSheet(R"(
Spinner {
background-color: black;
}
QLabel {
color: white;
font-size: 80px;
}
QProgressBar {
background-color: #373737;
border: none;
margin: 100px;
height: 50px;
width: 1000px;
}
QProgressBar::chunk {
background-color: white;
}
)");
rotate_timer = new QTimer(this);
rotate_timer->start(1000/30.);
QObject::connect(rotate_timer, SIGNAL(timeout()), this, SLOT(rotate()));
notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read);
QObject::connect(notifier, SIGNAL(activated(int)), this, SLOT(update(int)));
};
void Spinner::rotate() {
transform.rotate(5);
QPixmap r = track_img.transformed(transform);
int x = (r.width() - track_img.width()) / 2;
int y = (r.height() - track_img.height()) / 2;
track->setPixmap(r.copy(x, y, track_img.width(), track_img.height()));
};
void Spinner::update(int n) {
std::string line;
std::getline(std::cin, line);
if (line.length()) {
bool number = std::all_of(line.begin(), line.end(), ::isdigit);
text->setVisible(!number);
progress_bar->setVisible(number);
text->setText(QString::fromStdString(line));
if (number) {
progress_bar->setValue(std::stoi(line));
}
}
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Spinner *spinner = new Spinner();
// TODO: get size from QScreen, doesn't work on tici
#ifdef QCOM2
int w = 2160, h = 1080;
#else
int w = 1920, h = 1080;
#endif
spinner->setFixedSize(w, h);
spinner->show();
#ifdef QCOM2
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
wl_surface *s = reinterpret_cast<wl_surface*>(native->nativeResourceForWindow("surface", spinner->windowHandle()));
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
wl_surface_commit(s);
spinner->showFullScreen();
#endif
return a.exec();
}

View File

@ -0,0 +1,27 @@
#include <QTimer>
#include <QLabel>
#include <QWidget>
#include <QPixmap>
#include <QProgressBar>
#include <QTransform>
#include <QSocketNotifier>
class Spinner : public QWidget {
Q_OBJECT
public:
explicit Spinner(QWidget *parent = 0);
private:
QPixmap track_img;
QTimer *rotate_timer;
QLabel *comma, *track;
QLabel *text;
QProgressBar *progress_bar;
QTransform transform;
QSocketNotifier *notifier;
public slots:
void rotate();
void update(int n);
};

View File

@ -0,0 +1,8 @@
#!/bin/sh
if [ -f /EON ]; then
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
exec ./android/spinner/spinner "$1"
else
exec ./qt/spinner "$1"
fi

View File

@ -1,21 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <unistd.h>
#include <assert.h>
#include <GLES3/gl3.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "common/framebuffer.h"
#include "common/spinner.h"
int main(int argc, char** argv) {
int err;
spin(argc, argv);
return 0;
}