diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Oct 04 12:56:43 2026 -0500
@@ -0,0 +1,126 @@
+#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);
+}