aboutsummaryrefslogtreecommitdiffstats
path: root/unix/tx/TXMenu.cxx
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:04:46 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:04:46 +0000
commitb30ae7facbdf8273f34f5d67d3d2e9c81db75576 (patch)
tree5091b0a7b991672b19c17b86b263e5ff4f173a3e /unix/tx/TXMenu.cxx
parenta2adc8d4cfdf7336ce9192414c5e775224742a97 (diff)
downloadtigervnc-b30ae7facbdf8273f34f5d67d3d2e9c81db75576.tar.gz
tigervnc-b30ae7facbdf8273f34f5d67d3d2e9c81db75576.zip
Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@590 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'unix/tx/TXMenu.cxx')
-rw-r--r--unix/tx/TXMenu.cxx186
1 files changed, 186 insertions, 0 deletions
diff --git a/unix/tx/TXMenu.cxx b/unix/tx/TXMenu.cxx
new file mode 100644
index 00000000..92712f55
--- /dev/null
+++ b/unix/tx/TXMenu.cxx
@@ -0,0 +1,186 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+//
+// TXMenu.cxx
+//
+
+#include "TXMenu.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <rfb/util.h>
+#include <X11/keysym.h>
+
+TXMenu::TXMenu(Display* dpy_, TXMenuCallback* cb_, int w, int h,
+ TXWindow* parent_)
+ : TXWindow(dpy_, w, h, parent_), cb(cb_), nEntries(0),
+ highlight(-1)
+{
+ setEventHandler(this);
+ gc = XCreateGC(dpy, win(), 0, 0);
+ addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask | LeaveWindowMask);
+}
+
+TXMenu::~TXMenu()
+{
+ XFreeGC(dpy, gc);
+ for (int i = 0; i < nEntries; i++)
+ delete [] text[i];
+}
+
+inline int TXMenu::entryHeight(int i)
+{
+ if (text[i])
+ return defaultFS->ascent + defaultFS->descent + bevel*2 + yPad*2;
+ else
+ return yPad*2 + 1;
+}
+
+void TXMenu::addEntry(const char* text_, long id_)
+{
+ assert(nEntries < maxEntries);
+ text[nEntries] = rfb::strDup(text_);
+ checked[nEntries] = false;
+ id[nEntries++] = id_;
+ int tw = 0;
+ if (text_)
+ tw = XTextWidth(defaultFS, text_, strlen(text_));
+ int newWidth = width();
+ if (tw + bevel*2 + xPad*5 + tickSize > width())
+ newWidth = tw + bevel*2 + xPad*5 + tickSize;
+ int newHeight = 0;
+ for (int i = 0; i < nEntries; i++)
+ newHeight += entryHeight(i);
+ resize(newWidth, newHeight);
+}
+
+void TXMenu::check(long id_, bool checked_)
+{
+ for (int i = 0; i < nEntries; i++) {
+ if (id[i] == id_) {
+ checked[i] = checked_;
+ break;
+ }
+ }
+}
+
+void TXMenu::paint()
+{
+ int y = 0;
+ for (int i = 0; i < nEntries; i++) {
+ if (text[i]) {
+ if (i == highlight)
+ drawBevel(gc, 0, y, width(), entryHeight(i), bevel,
+ defaultBg, darkBg, lightBg);
+ else
+ XClearArea(dpy, win(), 0, y, width(), entryHeight(i), false);
+ if (checked[i])
+ XCopyPlane(dpy, tick, win(), defaultGC, 0, 0, tickSize, tickSize,
+ bevel + xPad,
+ y + bevel + yPad + defaultFS->ascent - tickSize, 1);
+
+ XDrawImageString(dpy, win(), defaultGC, bevel + xPad*2 + tickSize,
+ y + bevel + yPad + defaultFS->ascent,
+ text[i], strlen(text[i]));
+ } else {
+ XDrawLine(dpy, win(), defaultGC, bevel + xPad, y + entryHeight(i) / 2,
+ width() - bevel - xPad, y + entryHeight(i) / 2);
+ }
+ y += entryHeight(i);
+ }
+}
+
+void TXMenu::handleEvent(TXWindow* w, XEvent* ev)
+{
+ switch (ev->type) {
+ case Expose:
+ paint();
+ break;
+
+ case ButtonRelease:
+ {
+ int y = ev->xmotion.y;
+ int entryY = 0;
+ for (int i = 0; i < nEntries; i++) {
+ if (y >= entryY && y <= entryY + entryHeight(i)) {
+ if (cb && text[i])
+ cb->menuSelect(id[i], this);
+ break;
+ }
+ entryY += entryHeight(i);
+ }
+ highlight = -1;
+ paint();
+ break;
+ }
+
+ case ButtonPress:
+ case MotionNotify:
+ {
+ int y = ev->xmotion.y;
+ int entryY = 0;
+ for (int i = 0; i < nEntries; i++) {
+ if (y >= entryY && y <= entryY + entryHeight(i)) {
+ if (highlight != i) {
+ highlight = i;
+ paint();
+ }
+ break;
+ }
+ entryY += entryHeight(i);
+ }
+ break;
+ }
+
+ case KeyPress:
+ {
+ KeySym ks;
+ char str[256];
+ XLookupString(&ev->xkey, str, 256, &ks, NULL);
+ if (ks == XK_Escape) {
+ highlight = -1;
+ unmap();
+ } else if (ks == XK_Down || ks == XK_Up) {
+ if (nEntries < 1) break;
+ if (highlight < 0)
+ highlight = (ks == XK_Down ? nEntries-1 : 0);
+ int start = highlight;
+ int inc = (ks == XK_Down ? 1 : nEntries-1);
+ do {
+ highlight = (highlight + inc) % nEntries;
+ } while (highlight != start && !text[highlight]);
+ paint();
+ } else if (ks == XK_space || ks == XK_KP_Space ||
+ ks == XK_Return || ks == XK_KP_Enter) {
+ if (cb && highlight >= 0 && text[highlight])
+ cb->menuSelect(id[highlight], this);
+ highlight = -1;
+ paint();
+ }
+ break;
+ }
+
+ case EnterNotify:
+ case LeaveNotify:
+ highlight = -1;
+ paint();
+ break;
+ }
+}