Source

Mirror / src / statusBar.cpp

Full commit
#include "statusBar.h"
#include "setup.h"
#include "monitor.h"

StatusBar::StatusBar(Setup *setup, Monitor monitor):
    setup(setup)
{
    xcb_window_t id = xcb_generate_id(setup->conn);
    width = monitor.area.width;
    int y = monitor.area.y;
    int x = monitor.area.x;
    uint32_t values[] = {XCB_EVENT_MASK_EXPOSURE};
    xcb_create_window( setup->conn, XCB_COPY_FROM_PARENT, id, setup->root, 
                        x, y-setup->statusBarHeight, width, setup->statusBarHeight, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, 
                        setup->screen->root_visual, XCB_CW_EVENT_MASK, values );
    
    xcb_visualtype_t *visualType = nullptr;
    auto depthIter = xcb_screen_allowed_depths_iterator(setup->screen);
    for (; depthIter.rem; xcb_depth_next(&depthIter))
    {
        auto visualIter = xcb_depth_visuals_iterator(depthIter.data);
        for (; visualIter.rem; xcb_visualtype_next(&visualIter))
        {
            if (setup->screen->root_visual == visualIter.data->visual_id)
            {
                visualType = visualIter.data;
            }
        }
    }
    surface =  Cairo::XcbSurface::create(setup->conn, id, visualType, width, setup->statusBarHeight);
    context = Cairo::Context::create(surface);
    
    xcb_map_window(setup->conn, id);
    draw(); 

    xcb_flush(setup->conn);
}

StatusBar::~StatusBar()
{
}

void StatusBar::setMode(std::string newMode)
{
    mode = newMode;
    draw();
}


void StatusBar::draw()
{
    context->set_source_rgb(0.1, 0.1, 0.1);
    context->paint();
    context->move_to(2, 15);
    context->set_source_rgb(1, 1, 1);
    context->select_font_face("Terminus", Cairo::FontSlant::FONT_SLANT_NORMAL, Cairo::FontWeight::FONT_WEIGHT_BOLD);
    context->set_font_size(15);
    double x,y;
    for (auto& name : tagNames)
    {
        
        if (name == activeTagName)
        {
            context->get_current_point(x, y);
            Cairo::TextExtents nameExtents;
            context->get_text_extents(name, nameExtents);
            context->rectangle(x-1, 0, nameExtents.x_advance+2,  15 + nameExtents.height);
            context->set_source_rgb(0.31, 0.7, 0.795);
            context->fill();
            context->set_source_rgb(0, 0, 0);
            context->move_to(x, y);
        }
        context->show_text(name);
        context->show_text(" ");
        context->set_source_rgb(1,1,1);
    }
	context->move_to(width/2, 15);
	context->show_text(timeText);
	Cairo::TextExtents extents;
    context->get_text_extents(mode, extents);
	context->move_to(width - extents.width-5, 15);
	context->show_text(mode);
	xcb_flush(setup->conn);
}

void StatusBar::update()
{
	char buffer[80];
	time_t rawTime;
	struct tm *timeInfo;
	time(&rawTime);
	timeInfo = localtime(&rawTime);
	std::string oldTimeText = timeText;
	timeText = " " + std::string(buffer, strftime(buffer, 80, "%l:%M", timeInfo));
	if (timeText != oldTimeText)
	{
		draw();
	}
}

void StatusBar::handleExposeEvent(EventPtr event)
{
    draw();
}

void StatusBar::setTagNames(std::vector<std::string> newTagNames)
{
    tagNames = newTagNames;
    draw();
}

void StatusBar::setActiveTag(std::string tagName)
{
    activeTagName = tagName;
    draw(); 
}