Qt spinner (#2494)
* move android spinner * qt spinner * rotation * nothing by default * spin spin * fix rotate * style * spinner for all * -2 * unusedpull/2498/head
parent
c6e1beb402
commit
6c86afee16
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
moc_*
|
||||
*.moc
|
||||
|
||||
qt/text
|
||||
qt/spinner
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 $@)'
|
||||
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue