somebar/src/bar.cpp

157 lines
4.3 KiB
C++
Raw Normal View History

2021-10-20 14:45:23 -04:00
// somebar - dwl bar
// See LICENSE file for copyright and license details.
2021-10-22 09:34:19 -04:00
#include <QColor>
2021-10-20 15:09:19 -04:00
#include <QImage>
2021-10-22 09:34:19 -04:00
#include <QPainter>
2021-10-20 14:45:23 -04:00
#include "bar.hpp"
#include "config.hpp"
const zwlr_layer_surface_v1_listener Bar::_layerSurfaceListener = {
[](void *owner, zwlr_layer_surface_v1*, uint32_t serial, uint32_t width, uint32_t height)
{
static_cast<Bar*>(owner)->layerSurfaceConfigure(serial, width, height);
}
};
2021-10-22 10:52:04 -04:00
const wl_callback_listener Bar::_frameListener = {
[](void *owner, wl_callback *cb, uint32_t)
{
static_cast<Bar*>(owner)->render();
wl_callback_destroy(cb);
}
};
2021-10-20 14:45:23 -04:00
2021-10-22 09:49:09 -04:00
static QFont getFont()
{
QFont font {fontFamily, fontSizePt};
font.setBold(fontBold);
return font;
}
2021-10-25 13:02:35 -04:00
static QFont font = getFont();
static QFontMetrics fontMetrics = QFontMetrics {font};
2021-10-22 09:49:09 -04:00
2021-10-20 14:45:23 -04:00
Bar::Bar(const wl_output *output)
{
2021-10-25 13:02:35 -04:00
_surface.reset(wl_compositor_create_surface(compositor));
_layerSurface.reset(zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell,
_surface.get(), nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar"));
zwlr_layer_surface_v1_add_listener(_layerSurface.get(), &_layerSurfaceListener, this);
2021-10-21 02:28:22 -04:00
auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
2021-10-25 13:02:35 -04:00
zwlr_layer_surface_v1_set_anchor(_layerSurface.get(),
2021-10-21 02:28:22 -04:00
anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
2021-10-22 09:49:09 -04:00
2021-10-25 13:02:35 -04:00
auto barSize = fontMetrics.ascent() + fontMetrics.descent() + paddingY * 2;
_textY = fontMetrics.ascent() + paddingY;
2021-10-22 09:49:09 -04:00
2021-10-25 13:02:35 -04:00
zwlr_layer_surface_v1_set_size(_layerSurface.get(), 0, barSize);
zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface.get(), barSize);
wl_surface_commit(_surface.get());
2021-10-22 09:34:19 -04:00
2021-10-24 13:04:29 -04:00
for (auto tag : tagNames) {
_tags.push_back({ tag, false });
2021-10-22 09:34:19 -04:00
}
2021-10-22 09:55:29 -04:00
_windowTitle = "Window title";
_status = "Status";
2021-10-20 14:45:23 -04:00
}
2021-10-25 13:02:35 -04:00
const wl_surface* Bar::surface() const { return _surface.get(); }
2021-10-20 14:45:23 -04:00
2021-10-22 11:26:05 -04:00
void Bar::click(int x, int)
{
for (auto tag=_tags.rbegin(); tag != _tags.rend(); tag++) {
if (x > tag->x) {
tag->active = !tag->active;
invalidate();
return;
}
}
}
2021-10-22 10:52:04 -04:00
void Bar::invalidate()
{
if (_invalid) return;
_invalid = true;
2021-10-25 13:02:35 -04:00
auto frame = wl_surface_frame(_surface.get());
2021-10-22 10:52:04 -04:00
wl_callback_add_listener(frame, &_frameListener, this);
2021-10-25 13:02:35 -04:00
wl_surface_commit(_surface.get());
2021-10-22 10:52:04 -04:00
}
void Bar::setStatus(const QString &status)
{
_status = status;
invalidate();
}
2021-10-20 14:45:23 -04:00
void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height)
{
2021-10-25 13:02:35 -04:00
zwlr_layer_surface_v1_ack_configure(_layerSurface.get(), serial);
2021-10-20 14:45:23 -04:00
_bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888);
2021-10-20 15:09:19 -04:00
render();
}
void Bar::render()
{
auto img = QImage {
_bufs->data(),
_bufs->width,
_bufs->height,
_bufs->stride,
2021-10-22 09:34:19 -04:00
QImage::Format_ARGB32
2021-10-20 15:09:19 -04:00
};
2021-10-22 09:34:19 -04:00
auto painter = QPainter {&img};
2021-10-22 09:42:42 -04:00
_painter = &painter;
2021-10-22 09:55:29 -04:00
_x = 0;
2021-10-25 13:02:35 -04:00
painter.setFont(font);
2021-10-22 09:34:19 -04:00
2021-10-22 09:42:42 -04:00
setColorScheme(colorActive);
painter.fillRect(0, 0, img.width(), img.height(), painter.brush());
2021-10-22 09:55:29 -04:00
renderTags();
setColorScheme(colorActive);
renderText(_windowTitle);
renderStatus();
2021-10-22 09:34:19 -04:00
2021-10-22 09:42:42 -04:00
_painter = nullptr;
2021-10-25 13:02:35 -04:00
wl_surface_attach(_surface.get(), _bufs->buffer(), 0, 0);
wl_surface_damage(_surface.get(), 0, 0, INT_MAX, INT_MAX);
wl_surface_commit(_surface.get());
2021-10-20 15:09:19 -04:00
_bufs->flip();
2021-10-22 10:52:04 -04:00
_invalid = false;
2021-10-20 14:45:23 -04:00
}
2021-10-22 09:34:19 -04:00
2021-10-22 09:42:42 -04:00
void Bar::setColorScheme(const ColorScheme &scheme)
{
_painter->setBrush(QBrush {scheme.bg});
_painter->setPen(QPen {QBrush {scheme.fg}, 1});
}
2021-10-22 09:55:29 -04:00
void Bar::renderTags()
2021-10-22 09:34:19 -04:00
{
2021-10-22 11:26:05 -04:00
for (auto &tag : _tags) {
tag.x = _x;
2021-10-22 09:42:42 -04:00
setColorScheme(tag.active ? colorActive : colorInactive);
2021-10-22 09:55:29 -04:00
renderText(tag.name);
2021-10-22 09:34:19 -04:00
}
}
2021-10-22 09:55:29 -04:00
void Bar::renderText(const QString &text)
{
auto size = textWidth(text) + paddingX*2;
_painter->fillRect(_x, 0, size, _bufs->height, _painter->brush());
_painter->drawText(paddingX+_x, _textY, text);
_x += size;
}
void Bar::renderStatus()
{
auto size = textWidth(_status) + paddingX*2;
_x = _bufs->width - size;
_painter->fillRect(_x, 0, size, _bufs->height, _painter->brush());
_painter->drawText(paddingX+_x, _textY, _status);
_x = _bufs->width;
}
2021-10-22 09:34:19 -04:00
int Bar::textWidth(const QString &text)
{
2021-10-25 13:02:35 -04:00
return fontMetrics.size(Qt::TextSingleLine, text).width();
2021-10-22 09:34:19 -04:00
}