📄 scroll.cc
字号:
//**************************************************************//* filename: scroll.cc *//* *//**************************************************************//* programmed by: Thomas Wagner *//* last change: 14-05-95 *//**************************************************************#include <stdio.h>#include <stdlib.h>#include <string.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include "scroll.h"#include "include_bmps/arrowup.bmp"#include "include_bmps/arrowdown.bmp"extern unsigned long buttonpix, blackpix, shadowpix, lightpix;extern Cursor maincursor;ScrollWindow::ScrollWindow (Display * initdisplay, GC initgc, BigWindow * Parentwindow, XFontStruct * initfontstruct, short initx, short inity, short initwidth, short initheight, int initminvalue, int initmaxvalue, unsigned int options, int initactionnumber):BigWindow (initdisplay, initgc, Parentwindow->GetWindow (), initfontstruct, initx, inity, initwidth, initheight, NULL, options & SCROLL_BORDER_OPTION ? DEFAULT_BDWIDTH : 0){ counter = 0; unsigned int depth; maxvalue = initmaxvalue; minvalue = initminvalue; parent = Parentwindow; actionnumber = initactionnumber; unsigned short scrollwidth = 10, scrollheight = 10; unsigned short textheight = 0, textwidth = 0, textxpos = 0, textypos = height - SCROLL_BORDER_OPTION; if (options & SCROLL_COUNTERWINDOW_OPTION) { textheight = (fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent) + 4; textwidth = width - 2 * (SCROLL_BORDERWIDTH + DEFAULT_BDWIDTH); textxpos = SCROLL_BORDERWIDTH; textypos = height - SCROLL_BORDERWIDTH - DEFAULT_BDWIDTH - textheight - 2 * DEFAULT_BDWIDTH; textbox = new TextBox (display, gc, this, fontstruct, textxpos, textypos, textwidth, textheight, 0, "0", 1, TEXTOPTION_DARK, 0, 0); } else textbox = NULL; unsigned short actionsize = SCROLL_ARROWSIZE + 2 * SCROLL_BORDERWIDTH; unsigned short actionxpos = (width - actionsize) / 2 - ACTIONICON_BDWIDTH; unsigned short action0ypos = SCROLL_BORDERWIDTH + 1; unsigned short action1ypos = textypos - 4 * DEFAULT_BDWIDTH - actionsize; unsigned short scrolllength = action1ypos - (action0ypos + actionsize + 2 * ACTIONICON_BDWIDTH); depth = DefaultDepth (display, DefaultScreen (display)); pixmap = XCreatePixmap (display, window, width, height, depth); XSetForeground (display, gc, buttonpix); XFillRectangle (display, pixmap, gc, 0, 0, width, height); if (textbox != NULL) DrawBorder (pixmap, 0, 0, width, height, 0, 0, "", HIGH); DrawBorder (pixmap, actionxpos, SCROLL_BORDERWIDTH + 1 + actionsize + 2 * ACTIONICON_BDWIDTH, actionsize + 2 * ACTIONICON_BDWIDTH, scrolllength, 0, 0, "", LOW); XSetForeground (display, gc, blackpix); XFillRectangle (display, pixmap, gc, actionxpos + 1, SCROLL_BORDERWIDTH + 1 + actionsize + 2 * ACTIONICON_BDWIDTH + 1, actionsize, scrolllength - 2); Actionicon[0] = new ActionIcon (display, gc, this, fontstruct, actionxpos, action0ypos, actionsize, actionsize, "", arrowup_bits, arrowup_width, arrowup_height, SCROLL_COUNTUP_ACTION, ICON_SELECTABLE | ICON_REPEATEDCLICK); Actionicon[1] = new ActionIcon (display, gc, this, fontstruct, actionxpos, action1ypos, actionsize, actionsize, "", arrowdown_bits, arrowdown_width, arrowdown_height, SCROLL_COUNTDOWN_ACTION, ICON_SELECTABLE | ICON_REPEATEDCLICK); scrollwidth = actionsize - 2 * ACTIONICON_BDWIDTH; scrollheight = scrolllength - 4; scrollbar = new Scrollbar (display, gc, this, fontstruct, actionxpos + 1 + 1, SCROLL_BORDERWIDTH + 1 + 1 + actionsize + 2 * ACTIONICON_BDWIDTH + 1, scrollwidth, scrollheight); scrollbar->SetValue (counter); SetSelectedInput (ExposureMask | ButtonPressMask);}ScrollWindow::~ScrollWindow (){ UnmapMe (); delete Actionicon[0]; delete Actionicon[1]; if (textbox != NULL) delete textbox; XFreePixmap (display, pixmap); delete scrollbar;}void ScrollWindow::SetValue (int newvalue){ counter = newvalue; if (counter < minvalue) counter = minvalue; if (counter > maxvalue) counter = maxvalue; scrollbar->SetValue (counter); if (textbox != NULL) textbox->ChangeText ((short) counter);}char ScrollWindow::SetMinMax (int min, int max){ char valuechanged = FALSE; maxvalue = max; minvalue = min; scrollbar->MinMaxChanged (); if (counter < minvalue) { Action (SCROLL_SETVALUE_ACTION, minvalue); valuechanged = TRUE; } if (counter > maxvalue) { Action (SCROLL_SETVALUE_ACTION, maxvalue); valuechanged = TRUE; } scrollbar->SetValue (counter); return valuechanged;}void ScrollWindow::Action (int value1, int value2){ switch (value1) { case SCROLL_COUNTUP_ACTION: if (counter < maxvalue) { counter++; scrollbar->SetValue (counter); if (textbox != NULL) textbox->ChangeText ((short) counter); parent->Action (actionnumber, counter); } break; case SCROLL_COUNTDOWN_ACTION: if (counter > minvalue) { counter--; scrollbar->SetValue (counter); if (textbox != NULL) textbox->ChangeText ((short) counter); parent->Action (actionnumber, counter); } break; case SCROLL_SETVALUE_ACTION: if (counter != value2) { counter = value2; if (textbox != NULL) textbox->ChangeText ((short) counter); } else { if (textbox != NULL) textbox->ChangeText ((short) counter); } parent->Action (actionnumber, counter); break; }}void ScrollWindow::HandleEvent (XEvent * Event){ switch (Event->type) { case Expose: XCopyArea (display, pixmap, window, gc, Event->xgraphicsexpose.x, Event->xgraphicsexpose.y, Event->xgraphicsexpose.width, Event->xgraphicsexpose.height, Event->xgraphicsexpose.x, Event->xgraphicsexpose.y); break; case ButtonPress: if (Event->xbutton.button == Button1) { short xpos = Event->xbutton.x; short ypos = Event->xbutton.y; if ((ypos > scrollbar->minpixel) && (ypos < (scrollbar->maxpixel + scrollbar->height)) && (xpos > scrollbar->x) && (xpos < (scrollbar->x + scrollbar->width))) { int fullscrollheight = scrollbar->maxpixel + scrollbar->height; double factor = (double) (maxvalue - minvalue) / (double) fullscrollheight; short diff = (short) (factor * (ypos - (scrollbar->y + scrollbar->height / 2))); SetValue (counter - diff); Action (SCROLL_SETVALUE_ACTION, counter); } } break; }}Scrollbar::Scrollbar (Display * initdisplay, GC initgc, ScrollWindow * Parentwindow, XFontStruct * initfontstruct, short initx, short inity, short initwidth, short initheight):Window_Info (initdisplay, initgc, Parentwindow->GetWindow (), initfontstruct, initx, inity, initwidth, (short) MAX (initheight - (Parentwindow->GetMaxValue () - Parentwindow->GetMinValue ()), SCROLL_MINLENGTH), NULL, 0){ parent = Parentwindow; minpixel = inity; maxpixel = inity + (short) (initheight - height); short depth; depth = DefaultDepth (display, DefaultScreen (display)); pixmap_up = XCreatePixmap (display, window, width, height, depth); pixmap_down = XCreatePixmap (display, window, width, height, depth); XSetForeground (display, gc, buttonpix); XFillRectangle (display, pixmap_up, gc, 0, 0, width, height); XFillRectangle (display, pixmap_down, gc, 0, 0, width, height); DrawBorder (pixmap_up, 0, 0, width, height, 0, 0, "", HIGH); DrawBorder (pixmap_down, 0, 0, width, height, 0, 0, "", LOW); SetSelectedInput (ExposureMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask); MapMe ();}Scrollbar::~Scrollbar (){ UnmapMe (); XFreePixmap (display, pixmap_up); XFreePixmap (display, pixmap_down);}void Scrollbar::MinMaxChanged (){ short fullheight = (maxpixel - minpixel) + height, depth; XFreePixmap (display, pixmap_up); XFreePixmap (display, pixmap_down); SizeMe (width, MAX (SCROLL_MINLENGTH, fullheight - (parent->GetMaxValue () - parent->GetMinValue ()))); depth = DefaultDepth (display, DefaultScreen (display)); pixmap_up = XCreatePixmap (display, window, width, height, depth); pixmap_down = XCreatePixmap (display, window, width, height, depth); XSetForeground (display, gc, buttonpix); XFillRectangle (display, pixmap_up, gc, 0, 0, width, height); XFillRectangle (display, pixmap_down, gc, 0, 0, width, height); DrawBorder (pixmap_up, 0, 0, width, height, 0, 0, "", HIGH); DrawBorder (pixmap_down, 0, 0, width, height, 0, 0, "", LOW); maxpixel = minpixel + (fullheight - height);}void Scrollbar::SetValue (int newvalue){ int oldy = y; short ydiff = parent->GetMaxValue () - parent->GetMinValue (); if (ydiff > 0) y = maxpixel - (maxpixel - minpixel) * (newvalue - parent->GetMinValue ()) / (ydiff); else y = minpixel; XMoveWindow (display, window, x, y); short diff = y - oldy; XSetForeground (display, gc, blackpix); if (diff < 0) XFillRectangle (display, parent->GetWindow (), gc, x, y + height, width, -diff); else XFillRectangle (display, parent->GetWindow (), gc, x, oldy, width, diff);}void Scrollbar::HandleEvent (XEvent * Event){ static short oldy, bary; static char barstatus = 0; switch (Event->type) { case Expose: if (Event->xexpose.count == 0) { if (barstatus & STATUS_SCROLLPRESSED) XCopyArea (display, pixmap_down, window, gc, 0, 0, width, height, 0, 0); else XCopyArea (display, pixmap_up, window, gc, 0, 0, width, height, 0, 0); } break; case MotionNotify: { int newy, localy = Event->xmotion.y; int diff; char moved = FALSE; newy = Event->xmotion.y_root; if (newy != oldy) { diff = newy - oldy; if (diff > 0) // moved down if (localy > (height / 2)) moved = TRUE; if (diff < 0) // moved up if (localy < (height / 2)) moved = TRUE; if (moved == TRUE) // redraw destroyed area of parent { XSetForeground (display, gc, blackpix); oldy = y; y += diff; if (y < minpixel) y = minpixel; if (y > maxpixel) y = maxpixel; XMoveWindow (display, window, x, y); diff = y - bary; if (diff < 0) XFillRectangle (display, parent->GetWindow (), gc, x, y + height, width, -diff); else XFillRectangle (display, parent->GetWindow (), gc, x, oldy, width, diff); if ((maxpixel - minpixel) != 0) parent->Action (SCROLL_SETVALUE_ACTION, (int) ((double) (maxpixel - y) * (parent->GetMaxValue () - parent->GetMinValue ()) / (double) (maxpixel - minpixel))); } oldy = newy; bary = y; } } break; case ButtonPress: if (Event->xbutton.button == Button1) { XWarpPointer (display, window, window, 0, 0, width, height, width / 2, height / 2); XGrabPointer (display, window, TRUE, 0, GrabModeAsync, GrabModeAsync, window, maincursor, CurrentTime); oldy = Event->xbutton.y_root; bary = y; XCopyArea (display, pixmap_down, window, gc, 0, 0, width, height, 0, 0); barstatus |= STATUS_SCROLLPRESSED; } break; case ButtonRelease: if (Event->xbutton.button == Button1) { XUngrabPointer (display, CurrentTime); barstatus &= ~STATUS_SCROLLPRESSED; XCopyArea (display, pixmap_up, window, gc, 0, 0, width, height, 0, 0); } break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -