Mercurial > x11calc
view main.cpp @ 0:12567e0a7670 default tip
initial commit
| author | Yasuri <yasuri@charliesmp.net> |
|---|---|
| date | Sun, 04 Oct 2026 12:56:43 -0500 |
| parents | |
| children |
line wrap: on
line source
#include <iostream> #include <stdexcept> #include <vector> #include <string> #include <sstream> #include <cstring> #include <unistd.h> #include <X11/Xlib.h> #include <X11/Xft/Xft.h> #include <fontconfig/fontconfig.h> #include <X11/keysym.h> #include "calculate.h" #include "x11.h" extern "C" { #include "drw.h" } #include "config.h" struct Button { int x, y, w, h; std::string label; }; std::vector<Button> makeButtons() { std::vector<Button> b; for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) b.push_back({gridX + c*(btnW+gap), gridY+ r*(btnH+gap), btnW, btnH, labels[r][c]}); return b; } void redraw(Drw* drw, Clr* btnScheme, Clr* dispScheme, const std::vector<Button>& btns, const std::string& input) { // display area (also paints the pixmap's background) drw_setscheme(drw, dispScheme); drw_rect(drw, 0, 0, 500, 500, 1, 1); drw_text(drw, 10, 10, 480, 70, 10, input.c_str(), 0); // buttons drw_setscheme(drw, btnScheme); for (const auto& b : btns) { unsigned int tw = drw_fontset_getwidth(drw, b.label.c_str()); int lpad = (b.w - (int)tw) / 2; drw_text(drw, b.x, b.y, b.w, b.h, lpad, b.label.c_str(), 0); } } int main() { Display *dpy = displayopen(); int screen = DefaultScreen(dpy); Window root = RootWindow(dpy, screen); Window win = XCreateSimpleWindow(dpy, root, 0, 0, 500, 500, 1, 0xFFFFFF, 0x000000); XStoreName(dpy, win, "Calculator"); XSelectInput(dpy, win, ExposureMask | KeyPressMask | ButtonPressMask); XMapWindow(dpy, win); Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &wmDelete, 1); Drw* drw = drw_create(dpy, screen, root, 500, 500); if (!drw) { std::cerr << "drw_create failed\n"; return 1; } if (!drw_fontset_create(drw, fonts, 1)) { std::cerr << "font load failed\n"; return 1; } Clr* btnScheme = drw_scm_create(drw, btnColors, 3); Clr* dispScheme = drw_scm_create(drw, dispColors, 3); std::vector<Button> btns = makeButtons(); std::string input; XEvent ev; bool running = true; while (running) { XNextEvent(dpy, &ev); switch (ev.type) { case ClientMessage: if ((Atom)ev.xclient.data.l[0] == wmDelete) running = false; break; case Expose: if (ev.xexpose.count == 0) { redraw(drw, btnScheme, dispScheme, btns, input); drw_map(drw, win, 0, 0, winW, winH); } break; case KeyPress: { KeySym k = XLookupKeysym(&ev.xkey, 0); if (k == XK_q) running = false; break; } case ButtonPress: if (ev.xbutton.button != Button1) break; for (const auto& b : btns) { bool hit = ev.xbutton.x >= b.x && ev.xbutton.x < b.x + b.w && ev.xbutton.y >= b.y && ev.xbutton.y < b.y + b.h; if (!hit) continue; if (b.label == "=") { size_t pos = input.find_first_of("+-*/", 1); if (pos != std::string::npos) { try { double x = std::stod(input.substr(0, pos)); double y = std::stod(input.substr(pos + 1)); char op = input[pos]; std::ostringstream ss; ss << calculate(x, y, op); input = ss.str(); } catch (const std::exception& e) { input = e.what(); } } } else if (b.label == "C") { input.clear(); } else { input += b.label; } XClearArea(dpy, win, 0, 0, 0, 0, True); break; } break; } } drw_free(drw); XCloseDisplay(dpy); }
