Mercurial > ~dholland > hg > ag > index.cgi
view anagram/vaclgui/agview.cpp @ 8:ec2b657edf13
Add explicit lint-comment-style fallthrough annotations.
GCC now assumes that if you don't have these you're making a mistake,
which is annoying.
XXX: This changeset updates the AG output files only (by hand) and is
XXX: abusive - rebuilding them will erase the change. However, I need
XXX: to get things to build before I can try to get AG to issue the
XXX: annotations itself, so this seems like a reasonable expedient.
author | David A. Holland |
---|---|
date | Mon, 30 May 2022 23:51:43 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1997-2002 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * agview.cpp */ #include <icoordsy.hpp> #include <windows.h> #include "agstring.h" #include "agview.hpp" #include "arrays.h" #include "config.h" #include "ctrlpanel.hpp" #include "dspar.hpp" #include "frame.hpp" #include "minmax.h" #include "vaclgui.hpp" //#define INCLUDE_LOGGING #include "log.h" int focusWindowId; const int AgView::defaultWindowHeight = 12; Boolean AgFocusHandler::dispatchHandlerEvent(IEvent &event) { //LOGSECTION("AgFocusHandler::dispatchHandlerEvent", Log::off); LOGSECTION_OFF("AgFocusHandler::dispatchHandlerEvent"); static int focusHandlerCalls = 0; focusHandlerCalls++; LOGV(event.eventId()); if (event.eventId() == WM_SETFOCUS) { LOGS("WM_SETFOCUS") LCV((int) event.controlWindow()); int flag; flag = gotFocus(event); if (flag) { event.setResult(flag); } return flag; } if (event.eventId() == WM_KILLFOCUS) { LOGS("WM_KILLFOCUS") LCV((int) event.controlWindow()); int flag = lostFocus(event); event.setResult(flag); return flag; } return false; } AgColumnHead::AgColumnHead(int id, IWindow* parent) : IStaticText(id, parent, parent) , title() , nCols(0) , tabs(0) , xPos(0) , color(&ColorSpec::inactiveTitle) , dataColorChange(this, onColorChange) { LOGSECTION("AgColumnHead constructor"); IPaintHandler::handleEventsFor(this); /* yBias = ICoordinateSystem::isConversionNeeded() ? font().maxSize().height() - font().maxDescender() : 0; LOGV(yBias); */ dataColorChange.attach(&ColorSpec::data); dataColorChange.attach(&ColorSpec::inactiveTitle); dataColorChange.attach(&ColorSpec::activeTitle); setText("Column headers"); show(); } AgColumnHead::~AgColumnHead() { IPaintHandler::stopHandlingEventsFor(this); } void AgColumnHead::setTitles(int nCols_, AgString title_) { LOGSECTION("AgColumnHead::setTitles"); nCols = nCols_; title = title_; setText(title.pointer()); LOGV(title.pointer()); LOGV(size().asString()); } void AgColumnHead::setMargin(int margin_) { margin = margin_; } void AgColumnHead::setPos(int pos_) { xPos = pos_; } void AgColumnHead::setTabs(int *tabs_) { tabs = tabs_; } Boolean AgColumnHead::paintWindow(IPaintEvent &event) { int i = 0; if (event.rect().area() == 0) { return true; } LOGSECTION("AgColumnHead::paintWindow"); LOGV(title.pointer()); IPresSpaceHandle handle = event.presSpaceHandle(); //cookie SetBkMode(handle, TRANSPARENT); event.clearBackground(color->bg()); font().beginUsingFont(handle); int textHeight = font().maxSize().height(); int verticalMargin = (size().height() - textHeight)/2; LOGV(textHeight); LOGV(verticalMargin); //LOGV(yBias); LOGV(margin); LOGV(xPos); int yBias = ICoordinateSystem::isConversionNeeded() ? font().maxSize().height() - font().maxDescender() : 0; IPoint trueWhere(margin - xPos, verticalMargin + yBias); IPoint where = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueWhere, size()) : trueWhere; LOGV(trueWhere.asString()); LOGV(where.asString()); AgString temp(title.pointer()); FindTabs tabsKluge(temp.pointer()); char *p = tabsKluge.getField(); LOGV(rect().asString()); while (i < nCols) { LOGV(i); LOGV(p); LOGV(where.asString()); LOGV(color->fg().asString()); LOGV(p) LCV(where.asString()); event.drawText(p,where, color->fg()); where += IPoint(tabs[i], 0); p = tabsKluge.getField(); i++; } font().endUsingFont(handle); return true; } AgStaticText &AgStaticText::scrollWindow(IPoint distance) { IRectangle clipRect(size()); //LOGSECTION("AgStaticText::scrollWindow", Log::off); LOGSECTION_OFF("AgStaticText::scrollWindow"); LOGV(distance.asString()); LOGV(clipRect.asString()); RECTL rct = clipRect.asRECTL(); ScrollWindowEx(handle(), distance.x(), distance.y(), 0, (RECT *) &rct, 0,0,SW_INVALIDATE); return *this; } AgView &AgView::hideCursor() { if (!cursorEnabled) { return *this; } //LOGSECTION("AgView::hideCursor", Log::off); LOGSECTION_OFF("AgView::hideCursor"); cursorHideCount++; LOGV(cursorHideCount); IFLOG(int flag = ) HideCaret(dataArea.handle()); LOGV(flag); return *this; } AgView &AgView::showCursor() { if (!cursorEnabled) { return *this; } //LOGSECTION("AgView::showCursor", Log::off); LOGSECTION_OFF("AgView::showCursor"); cursorHideCount--; LOGV(cursorHideCount); IFLOG(int flag = ) ShowCaret(dataArea.handle()); LOGV(flag); return *this; } AgView::AgView(IWindow *ownerWindow_) : ICanvas(nextChildId(), ownerWindow_, ownerWindow_) , ownerWindow(ownerWindow_) , horizontalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::horizontal | IWindow::visible) , verticalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::vertical | IWindow::visible) , dataHole(nextChildId(), this, this) , dataArea(nextChildId(), &dataHole, &dataHole) , vsbShowing(false) , hsbShowing(false) , columnHeadTitle(nextChildId(), this) , columnHeadsPresent(0) , cursorLine(0) , mouseDown(0) , tabArray(0) , tableWidth(0) , tableHeight(0) , cursorEnabled(0) , cursorLocation(0,0) , pixelCursor(font().avgCharWidth(),0) , cursorLineHighlight(0) , prevHorizontal(0) , prevVertical(0) , color(&ColorSpec::syntaxFile) , cursorColor(&ColorSpec::activeCursor) , rightButtonDown(0) , layoutActive(0) , retainCursor(cursorLineHighlight) , frameWindow(0) , dataColorChange(this, onColorChange) { LOGSECTION("AgView constructor"); LOGV(id()) LCV((int) this) LCV(handle().asDebugInfo()); LOGV(dataArea.id()) LCV((int) &dataArea) LCV(dataArea.handle().asDebugInfo()); dataColorChange.attach(&ColorSpec::data); dataColorChange.attach(&ColorSpec::inactiveCursor); dataColorChange.attach(&ColorSpec::activeCursor); for (int i = 0; i < 256; i++) { charWidth[i] = font().charWidth(i); } IWindow *f; for (f = ownerWindow; !f->isFrameWindow(); f=f->parent()); frameWindow = (AgFrame *) f; windowId = id(); AgString title = columnTitleText(); LOGV(title.pointer()); if (title.exists()) { columnHeadTitle.setTitles(nColumns(), title); ISize size = columnHeadTitle.size(); columnHeadTitle.setMinimumSize(size); LOGV(size.asString()); columnHeadTitle.setMargin(avgCharWidth()); columnHeadTitle.enableFillBackground(); columnHeadsPresent = 1; } horizontalScrollBar.setScrollableRange(IRange(0, 100)); horizontalScrollBar.moveScrollBoxTo(0); verticalScrollBar.setScrollableRange(IRange(0, 100)); verticalScrollBar.moveScrollBoxTo(0); IKeyboardHandler::handleEventsFor(&dataArea); IMouseHandler ::handleEventsFor(&dataArea); IMouseHandler ::handleEventsFor(&columnHeadTitle); IMouseHandler ::handleEventsFor(&verticalScrollBar); IMouseHandler ::handleEventsFor(&horizontalScrollBar); IPaintHandler ::handleEventsFor(&dataArea); IResizeHandler ::handleEventsFor(this); IScrollHandler ::handleEventsFor(this); show(); } AgView::~AgView() { delete [] tabArray; if (cursorEnabled) { AgFocusHandler::stopHandlingEventsFor(this); AgFocusHandler::stopHandlingEventsFor(&dataArea); } IKeyboardHandler::stopHandlingEventsFor(&dataArea); IMouseHandler ::stopHandlingEventsFor(&dataArea); IMouseHandler ::stopHandlingEventsFor(&columnHeadTitle); IMouseHandler ::stopHandlingEventsFor(&verticalScrollBar); IMouseHandler ::stopHandlingEventsFor(&horizontalScrollBar); IPaintHandler ::stopHandlingEventsFor(&dataArea); IResizeHandler ::stopHandlingEventsFor(this); IScrollHandler ::stopHandlingEventsFor(this); } AgView &AgView::enableCursorBar(int flag) { flag = (flag != 0); if (flag == cursorLineHighlight) { return *this; } cursorLineHighlight = flag; if (flag) { retainCursor = 1; AgFocusHandler::handleEventsFor(&dataArea); AgFocusHandler::handleEventsFor(this); LOGV(dataArea.hasFocus()); LOGV(hasFocus()); if (dataArea.hasFocus()) { LOGV(dataArea.size().height()); cursorOn(); //setCursorPos(pixelCursor); } } else { if (dataArea.hasFocus()) { //hideCursor(); cursorOff(); } AgFocusHandler::stopHandlingEventsFor(&dataArea); AgFocusHandler::stopHandlingEventsFor(this); } return *this; } AgView &AgView::enableCursor(int flag) { LOGSECTION("AgView::enableCursor"); LOGV(cursorEnabled) LCV(flag); flag = (flag != 0); if (flag == cursorEnabled) { return *this; } LOGS("changing cursor state"); cursorEnabled = flag; LOGV(cursorEnabled); if (flag) { retainCursor = 0; AgFocusHandler::handleEventsFor(&dataArea); AgFocusHandler::handleEventsFor(this); LOGV(dataArea.hasFocus()); LOGV(hasFocus()); if (dataArea.hasFocus()) { LOGV(dataArea.size().height()); cursorOn(); //setCursorPos(pixelCursor); } } else { if (dataArea.hasFocus()) { //hideCursor(); cursorOff(); } AgFocusHandler::stopHandlingEventsFor(&dataArea); AgFocusHandler::stopHandlingEventsFor(this); } return *this; } AgView &AgView::cursorOn() { //LOGSECTION("AgView::cursorOn", Log::off); LOGSECTION_OFF("AgView::cursorOn"); cint origin(horizontalScrollBar.scrollBoxPosition(), lineHeight()*verticalScrollBar.scrollBoxPosition()); pixelCursor.y = lineHeight()*cursorLine; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); cint relativeCursor = pixelCursor - origin; LOGV(relativeCursor); LOGV(cursorLine); LOGV(pixelCursor); LOGV(dataArea.rect().asString()); LOGV(dataArea.hasFocus()); IFLOG(int flag = ) CreateCaret(dataArea.handle(), NULL,0, lineHeight()); LOGV(flag); SetCaretPos(relativeCursor.x, relativeCursor.y); IFLOG(flag = ) ShowCaret(dataArea.handle()); LOGV(flag); cursorHideCount = 0; return *this; } AgView &AgView::setCursorPos(cint cursor) { if (!cursorEnabled) { return *this; } //LOGSECTION("AgView::setCursorPos", Log::off); LOGSECTION("AgView::setCursorPos"); LOGSTACK; cint origin(horizontalScrollBar.scrollBoxPosition(), lineHeight()*verticalScrollBar.scrollBoxPosition()); //cint origin(0, lineHeight()*verticalScrollBar.scrollBoxPosition()); cint relativeCursor = cursor - origin; LOGV(cursor) LCV(origin) LCV(relativeCursor); hideCursor(); IFLOG(int flag = ) SetCaretPos(relativeCursor.x, relativeCursor.y); LOGV(flag); showCursor(); return *this; } AgView &AgView::cursorOff() { //LOGSECTION("AgView::cursorOff", Log::off); LOGSECTION_OFF("AgView::cursorOff"); IFLOG(int flag = ) DestroyCaret(); LOGV(flag); return *this; } Boolean AgView::gotFocus(IEvent &) { //LOGSECTION("AgView::gotFocus", Log::off); LOGSECTION_OFF("AgView::gotFocus"); //LOGSTACK; if (cursorEnabled) { LOGV(pixelCursor); LOGV(dataArea.size().height()); cursorOn(); //setCursorPos(pixelCursor); } columnHeadTitle.color = &ColorSpec::activeTitle; columnHeadTitle.refresh(); if (cursorLineHighlight) { cursorColor = &ColorSpec::activeCursor; repaintLine(cursorLine); } focusWindowId = windowId; return false; //return true; } Boolean AgView::lostFocus(IEvent &) { //LOGSECTION("AgView::lostFocus", Log::off); LOGSECTION_OFF("AgView::lostFocus"); //LOGSTACK; if (cursorEnabled) { //hideCursor(); cursorOff(); } columnHeadTitle.color = &ColorSpec::inactiveTitle; columnHeadTitle.refresh(); if (cursorLineHighlight) { cursorColor = &ColorSpec::inactiveCursor; repaintLine(cursorLine); } return false; } int AgView::findMaxWidth() { LOGSECTION("AgView::findMaxWidth"); int maxWidth = 0; int nl = nLines(); int nCols = nColumns(); LOGV(nl) LCV(nCols); char *columnTitles = columnTitleText().pointer(); int i; if (tabArray == NULL) { tabArray = new int[nCols + 1]; memset(tabArray, 0, (nCols+1)*sizeof(int)); } IFont windowFont = font(); if (columnTitles) { //char *titles = new char[1+strlen(columnTitles)]; //char *titles = local_array(1+strlen(columnTitles), char); LocalArray<char> titles(1+strlen(columnTitles)); strcpy(titles, columnTitles); FindTabs tabs(titles); char *p = tabs.getField(); i = 0; while(i < nCols && p) { int width = windowFont.textWidth(p); if (width > tabArray[i]) { tabArray[i] = width; } if (++i >= nCols) { break; } p = tabs.getField(); } while (i < nCols) { tabArray[i++] = 0; } //delete [] titles; } else { for (i = 0; i < nCols; i++) { tabArray[i] = 0; } } columnHeadWidth = 0; for (i = 0; i < nCols; i++) { columnHeadWidth += tabArray[i] + 2*avgCharWidth(); } //int *width = new int[nCols]; //int *width = local_array(nCols, int); int *width = LocalArray<int>(nCols); memset(width, 0, nCols*sizeof(int)); LOGV((int) width); LOGV((int) tabArray); int enWidth = avgCharWidth(); int columnWidth = enWidth*tab_spacing; while (nl--) { LOGV(nl); AgString line = getLine(nl); LOGV(line); LOGV(nl); FindTabs tabs(line.pointer()); char *p = tabs.getField(); LOGV(nl) LCV((int) p); LOGV(p); int whereX = 0; if (nCols > 1) { i = 0; while (i < nCols && p) { width[i] = windowFont.textWidth(p); LOGV(width[i]); if (++i >= nCols) { break; } p = tabs.getField(); } if (i < nCols) { continue; } } else { while (p) { width[0] = whereX + font().textWidth(p); whereX = ((width[0] + columnWidth)/columnWidth) * columnWidth; p = tabs.getField(); } } for (i = 0; i < nCols; i++) { if (width[i] > tabArray[i]) { tabArray[i] = width[i]; LOGS("***") LV(tabArray[i]); } LOGS("***") LV(tabArray[i]); } } LOGS("width measured"); //delete [] width; for (i = 0; i < nCols; i++) { tabArray[i] += 2*avgCharWidth(); maxWidth += tabArray[i]; } LOGV(maxWidth); return maxWidth; } ICanvas &AgView::layout() { LOGSECTION("AgView::layout"); if (layoutActive) { return *this; } layoutActive++; doLayout(); ICanvas::setLayoutDistorted(0, IWindow::layoutChanged); ICanvas::layout(); layoutActive--; return *this; } ICanvas &AgView::setLayoutDistorted(unsigned long i, unsigned long j) { //LOGSECTION("AgView::setLayoutDistorted", Log::off); LOGSECTION_OFF("AgView::setLayoutDistorted"); //i &= ~IWindow::fontChanged; //j |= IWindow::fontChanged; tableWidth = 0; ICanvas::setLayoutDistorted(i, j); return *this; } Boolean AgView::windowResize(IResizeEvent &){ LOGSECTION("AgView resize event"); setLayoutDistorted(IWindow::layoutChanged,0); return false; } ISize AgView::suggestSize() { LOGSECTION("AgView::suggestSize"); int width = findMaxWidth(); int minWidth = 40*font().avgCharWidth(); int maxWidth = 60*font().avgCharWidth(); if (width < minWidth) { width = minWidth; } if (width > maxWidth) { width = maxWidth; } int height = tableHeight; if (nLines() > defaultWindowHeight) { width += verticalScrollBar.minimumSize().width() + 1; height = lineHeight() * defaultWindowHeight; } else if (nLines() < 5) { height = lineHeight() * 5; } LOGV(width); LOGV(height); return ISize(width, height); } Boolean AgView::paintWindow(IPaintEvent &event) { if (event.controlWindow() != &dataArea) { return false; } int height = lineHeight(); LOGSECTION("AgView::paintWindow"); IPresSpaceHandle handle = event.presSpaceHandle(); //cookie SetBkMode(handle, TRANSPARENT); font().beginUsingFont(handle); LOGV(event.rect().asString()); IRectangle invalidRect( ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToApplication(event.rect(),dataArea.size()) : event.rect() ); LOGV(invalidRect.asString()); LOGV(dataHole.rect().asString()); LOGV(dataArea.rect().asString()); int baseLine = verticalScrollBar.scrollBoxPosition(); int topY = baseLine*lineHeight(); int minY = topY + invalidRect.minY(); int maxY = topY + invalidRect.maxY(); int bottomY = topY + dataHole.size().height(); LOGV(minY) LCV(maxY); LOGV(topY) LCV(bottomY); if (minY < topY) { minY = topY; } if (maxY > bottomY) { maxY = bottomY; } invalidRect = IRectangle(IPoint(invalidRect.minX(), minY), (IPoint(invalidRect.maxX(), maxY))); LOGV(invalidRect.asString()); LOGV(dataHole.size().asString()); int firstLine = invalidRect.minY()/height; int lastLine = (invalidRect.maxY()+height - 1)/height - 1; if (firstLine < baseLine) { firstLine = baseLine; lastLine += baseLine; } int yBias = ICoordinateSystem::isConversionNeeded() ? height - maxDescender() : 0; int xMargin = avgCharWidth(); int whereX = -horizontalScrollBar.scrollBoxPosition(); int whereY = firstLine*height - topY; //baseline location IColor textBgndColor=color->bg(); IColor textFgndColor=color->fg(); IColor cursorBgndColor=color->bg(); IColor cursorFgndColor=color->fg(); if (cursorLineHighlight) { cursorBgndColor=cursorColor->bg(); cursorFgndColor=cursorColor->fg(); } LOGV(baseLine); LOGV(firstLine); LOGV(lastLine); LOGV(horizontalScrollBar.scrollBoxPosition()); int lastInvalidLine = lastLine; if (lastLine >= nLines()) { lastLine = nLines() - 1; } int windowHeight = dataArea.rect().size().height(); int dataAreaWidth = dataArea.rect().size().width() - whereX; ISize lineSize(dataAreaWidth, height); IPoint offset(xMargin, 0); int k; for (k = firstLine; k <= lastLine; k++, whereY += height) { //LOGSECTION("AgDataView::paintWindow line loop", Log::off); LOGSECTION_OFF("AgDataView::paintWindow line loop"); IPoint trueWhere(whereX, whereY + yBias); IPoint where = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueWhere, dataArea.size()) : trueWhere; IRectangle trueLineRect(0, whereY, dataAreaWidth, whereY+height); IRectangle lineRect = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueLineRect, dataArea.size()) : trueLineRect; IColor bgndColor = textBgndColor; IColor fgndColor = textFgndColor; if (k == cursorLine) { bgndColor = cursorBgndColor; fgndColor = cursorFgndColor; } LOGV(lineRect.asString()); LOGV(where.asString()); event.clearBackground(lineRect,bgndColor); AgString line = getLine(k); LOGV(line.pointer()); FindTabs tabs(line.pointer()); int enWidth = avgCharWidth(); int columnWidth = enWidth*tab_spacing; char *p = tabs.getField(); int nCols = nColumns(); where += offset; int i = 0; if (nCols > 1) { while (i < nCols && p) { LOGV(p - line.pointer()); event.drawText(p, where, fgndColor); where += IPoint(tabArray[i], 0); if (++i >= nCols) { break; } p = tabs.getField(); } } else { while (p) { event.drawText(p, where, fgndColor); int whereX = where.x(); whereX += font().textWidth(p); whereX += horizontalScrollBar.scrollBoxPosition() - enWidth; whereX = ((whereX + columnWidth)/columnWidth) * columnWidth; whereX -= horizontalScrollBar.scrollBoxPosition() - enWidth; where.setX(whereX); p = tabs.getField(); } } } if (k <= lastInvalidLine) { IRectangle trueRemainder(0,whereY,dataAreaWidth, windowHeight); IRectangle remainder = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueRemainder, dataArea.size()) : trueRemainder; LOGV(remainder.asString()); event.clearBackground(remainder,textBgndColor); } font().endUsingFont(handle); return true; } AgView &AgView::repaintLine(int line) { LOGSECTION("AgView::repaintLine"); if (line < 0 || line >= nLines()) { return *this; } int baseLine = verticalScrollBar.scrollBoxPosition(); int y = (line - baseLine) * lineHeight(); IRectangle rect(0, y, dataArea.rect().size().width(), y + lineHeight()); LOGV(line) LCV(baseLine) LCV(y) LCV(rect.asString()); dataArea.refresh(rect); return *this; } AgView &AgView::updateCursor(int line) { LOGSECTION_OFF("AgView::updateCursor"); LOGV(line) LCV(cursorLine); if (retainCursor && line != cursorLine) { int oldCursor = cursorLine; if (cursorLine < line) { cursorLocation.y = cursorLine = line; } int bottomLine = line + verticalScrollBar.visibleCount() - 1; if (cursorLine > bottomLine) { cursorLocation.y = cursorLine = bottomLine; } LOGV(line) LCV(cursorLine) LCV(bottomLine); if (cursorLineHighlight && cursorLine != oldCursor) { repaintLine(oldCursor); repaintLine(cursorLine); } } reposition(); cursorLocation.y = cursorLine; pixelCursor.y = lineHeight() * cursorLine; if (cursorEnabled && dataArea.hasFocus()) { setCursorPos(pixelCursor); } return *this; } AgView &AgView::reposition() { //LOGSECTION("AgView::reposition", Log::off); LOGSECTION("AgView::reposition"); if (cursorEnabled) hideCursor(); int verticalOffset = verticalScrollBar.scrollBoxPosition() - prevVertical; int horizontalOffset = horizontalScrollBar.scrollBoxPosition() - prevHorizontal; IPoint displacement(-horizontalOffset, -lineHeight()*verticalOffset); LOGV(displacement.asString()); dataArea.scrollWindow(displacement); dataArea.refresh(); prevHorizontal = horizontalScrollBar.scrollBoxPosition(); prevVertical = verticalScrollBar.scrollBoxPosition(); cursorLocation.y = cursorLine; pixelCursor.y = cursorLine*lineHeight(); if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return *this; } AgView &AgView::repaintCursor(int line) { LOGSECTION("AgView::repaintCursor"); LOGV(line) LCV(cursorLine); cursorLocation.y = cursorLine; pixelCursor.y = cursorLine*lineHeight(); if (cursorLineHighlight && cursorLine != line) { repaintLine(line); repaintLine(cursorLine); } return *this; } AgView &AgView::updateCursor() { LOGSECTION("AgView::updateCursor"); cursorLocation.y = cursorLine; LOGV(cursorLocation); pixelCursor.y = cursorLine*lineHeight(); LOGV(pixelCursor); if (cursorEnabled) { setCursorPos(pixelCursor); } return *this; } /* * * Layout considerations: * * The data view consists of up to four parts: two scroll bars, a heading * and a data area. * * The presence or absence of the scroll bars depends on the relative size * of the data area and the size of the table to be displayed. */ AgView &AgView::doLayout() { LOGSECTION("AgView::doLayout"); if (cursorEnabled && dataArea.hasFocus()) { hideCursor(); } if (tableWidth == 0) { tableWidth = findMaxWidth(); } tableHeight = lineHeight()*nLines(); LOGV(tableWidth); LOGV(tableHeight); columnHeadTitle.setTabs(tabArray); ISize canvasSize = size(); int canvasWidth = canvasSize.width(); int canvasHeight = canvasSize.height(); if (canvasWidth == 0 && canvasHeight == 0) { return *this; } LOGV(canvasWidth); LOGV(canvasHeight); int dataWidth = canvasWidth; int dataHeight = canvasHeight; int dataY = 0; if (columnHeadsPresent) { dataY = columnHeadTitle.minimumSize().height(); dataHeight -= dataY; columnHeadTitle.moveTo(IPoint(0,0)); } LOGV(dataWidth); LOGV(dataHeight); LOGV(tableWidth); LOGV(tableHeight); int vsbWidth = verticalScrollBar.minimumSize().width(); int hsbHeight = horizontalScrollBar.minimumSize().height(); int horizontalPosition = horizontalScrollBar.scrollBoxPosition(); int verticalPosition = verticalScrollBar.scrollBoxPosition(); Boolean vsb = true; Boolean hsb = true; if (tableHeight > canvasHeight && tableWidth <= canvasWidth - vsbWidth - 1) { // vertical scroll bar only vsb = true; hsb = false; } else if (tableWidth > canvasWidth && tableHeight <= canvasHeight - hsbHeight - 1) { // horizontal scroll bar only vsb = false; hsb = true; } else if (tableWidth <= canvasWidth && tableHeight <= canvasHeight) { // no scroll bars vsb = hsb = false; } LOGV(vsb) LCV(vsbShowing); LOGV(hsb) LCV(hsbShowing); if (vsb && !vsbShowing) { verticalScrollBar.moveScrollBoxTo(0); prevVertical = 0; verticalScrollBar.show(); vsbShowing = true; } if (!vsb && vsbShowing) { verticalScrollBar.hide(); vsbShowing = false; verticalScrollBar.moveScrollBoxTo(0); prevVertical = 0; } if (hsb && !hsbShowing) { horizontalScrollBar.show(); hsbShowing = true; horizontalScrollBar.moveScrollBoxTo(0); prevHorizontal = 0; } if (!hsb && hsbShowing) { horizontalScrollBar.hide(); hsbShowing = false; horizontalScrollBar.moveScrollBoxTo(0); prevHorizontal = 0; } if (vsbShowing) { dataWidth -= vsbWidth + 1; verticalScrollBar.moveTo(IPoint(dataWidth+1, 0)); verticalScrollBar.sizeTo(ISize(vsbWidth, canvasHeight)); } if (hsbShowing) { dataHeight -= hsbHeight + 1; horizontalScrollBar.moveTo(IPoint(0, dataHeight+1)); horizontalScrollBar.sizeTo(ISize(dataWidth, hsbHeight)); } dataHole.sizeTo(ISize(dataWidth, dataHeight)); dataHole.moveTo(IPoint(0, dataY)); LOGV(nLines()); LOGV(lineHeight()); LOGV(nLines()*lineHeight()); int desiredWidth = tableWidth; if (tableWidth < dataWidth) { desiredWidth = dataWidth; } ISize desiredSize(desiredWidth, dataHeight); LOGV(desiredSize.asString()); dataArea.sizeTo(desiredSize); LOGV(dataArea.size().asString()); LOGV(dataArea.parentSize().asString()); dataArea.moveTo(IPoint(0, 0)); LOGV(rect().asString()); LOGV(dataArea.rect().asString()); LOGV(horizontalScrollBar.rect().asString()); LOGV(verticalScrollBar.rect().asString()); horizontalScrollBar.setScrollableRange(IRange(0,tableWidth-1)); horizontalScrollBar.setVisibleCount(dataWidth); verticalScrollBar.setVisibleCount(dataHeight/lineHeight()); verticalScrollBar.setScrollableRange(IRange(0, nLines() - 1)); horizontalPosition = min( (int) horizontalScrollBar.scrollBoxRange().upperBound(), horizontalPosition ); verticalPosition = min( (int) verticalScrollBar.scrollBoxRange().upperBound(), verticalPosition ); verticalPosition = max( (int)(cursorLine - verticalScrollBar.visibleCount() + 1), verticalPosition ); horizontalScrollBar.setMinScrollIncrement(maxCharWidth()); verticalScrollBar.setMinScrollIncrement(1); horizontalScrollBar.moveScrollBoxTo(horizontalPosition); prevHorizontal = horizontalPosition; verticalScrollBar.moveScrollBoxTo(verticalPosition); prevVertical = verticalPosition; if (columnHeadsPresent) { ISize headSize(dataWidth, columnHeadTitle.minimumSize().height()); columnHeadTitle.sizeTo(headSize); columnHeadTitle.xPos = horizontalPosition; columnHeadTitle.refresh(); } refresh(); LOGV(dataArea.hasFocus()); LOGV(vsb) LCV(vsbShowing); LOGV(hsb) LCV(hsbShowing); if (cursorEnabled && dataArea.hasFocus()) { setCursorPos(pixelCursor).showCursor(); } return *this; } int AgView::charPosition(int xPos, AgString line) { int i; int enWidth = avgCharWidth(); int x = enWidth; int columnWidth = enWidth*tab_spacing; int spaceWidth = charWidth[' ']; unsigned char *p = (unsigned char *) line.pointer(); //LOGSECTION("AgView::charPosition", Log::off); LOGSECTION_OFF("AgView::charPosition"); LOGV(p) LCV(xPos); if (p == 0) { return 0; } for (i = 0; p[i]; i++) { int newX = x + charWidth[p[i]]; if (p[i] == '\t') { LOGSECTION("AgView::charPosition::tab"); LOGV(x) LCV(columnWidth); int j = 0; if (nColumns() > 1 && tabArray) { while (tabArray[j] && tabArray[j] <= x) { j++; } if (tabArray[j] > newX) { newX = tabArray[j]; } } else { /* int hPos = horizontalScrollBar.scrollBoxPosition(); newX = x + hPos - enWidth; newX = ((newX + columnWidth)/columnWidth)*columnWidth; newX -= hPos - enWidth; */ newX = enWidth + ((x-enWidth + columnWidth)/columnWidth) * columnWidth; } LOGV(x); } if (p[i] == ' ') { LOGV(x); newX = x + spaceWidth; } //if (newX > xPos) { if (xPos <= (x+newX)/2) { LOGV(i) LCV(xPos) LCV(x) LCV(newX); return i; } x = newX; } return i ? i - 1 : 0; } int AgView::xPosition(int charPos, AgString line) { //LOGSECTION("AgView::xPosition", Log::off); LOGSECTION_OFF("AgView::xPosition"); int i; int enWidth = avgCharWidth(); int x = enWidth; int columnWidth = enWidth*tab_spacing; int spaceWidth = charWidth[' ']; unsigned char *p = (unsigned char *) line.pointer(); LOGV(p); LOGV(charPos); LOGV(line.pointer()); if (p == 0) { return x; } for (i = 0; p[i] && i < charPos; i++) { if (p[i] == '\t') { LOGSECTION("AgView::xPosition::tab"); LOGV(x) LCV(columnWidth); int j = 0; if (nColumns() > 1 && tabArray) { while (tabArray[j] && tabArray[j] <= x) { j++; } if (tabArray[j] > x) { x = tabArray[j]; } } else { x = enWidth + ((x-enWidth + columnWidth)/columnWidth) * columnWidth; } /* else { int hPos = horizontalScrollBar.scrollBoxPosition(); x += hPos - enWidth; x = ((x + columnWidth)/columnWidth)*columnWidth; x -= hPos - enWidth; } */ LOGV(x); continue; } if (p[i] == ' ') { LOGV(x); x += spaceWidth; continue; } x += charWidth[p[i]]; } LOGV(x); LOGV(i); return x; } void AgView::checkFocus(void) { #ifdef AG_WINDOWSX if (!dataArea.hasFocus()) { dataArea.setFocus(); } #endif } Boolean AgView::lineDown(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } //LOGSECTION("AgView::lineDown", Log::off); LOGSECTION_OFF("AgView::lineDown"); LOGV(cursorLine); checkFocus(); hideCursor(); moveScrollBox(event); int line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); showCursor(); return true; } Boolean AgView::lineLeft(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } //LOGSECTION("AgView::lineLeft", Log::off); LOGSECTION_OFF("AgView::lineLeft"); if (cursorEnabled) { hideCursor(); } checkFocus(); moveScrollBox(event); reposition(); if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } Boolean AgView::lineRight(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } //LOGSECTION("AgView::lineRight", Log::off); LOGSECTION_OFF("AgView::lineRight"); checkFocus(); if (cursorEnabled) { hideCursor(); } moveScrollBox(event); reposition(); if (cursorEnabled) { showCursor(); } return true; } Boolean AgView::lineUp(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } checkFocus(); hideCursor(); moveScrollBox(event); int line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); showCursor(); return true; } Boolean AgView::pageDown(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } checkFocus(); hideCursor(); moveScrollBox(event); int line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); showCursor(); return true; } Boolean AgView::pageLeft(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } checkFocus(); if (cursorEnabled) { hideCursor(); } moveScrollBox(event); reposition(); if (cursorEnabled) { showCursor(); } return true; } Boolean AgView::pageRight(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } checkFocus(); if (cursorEnabled) { hideCursor(); } moveScrollBox(event); reposition(); if (cursorEnabled) { showCursor(); } return true; } Boolean AgView::pageUp(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } checkFocus(); hideCursor(); moveScrollBox(event); int line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); showCursor(); return true; } Boolean AgView::scrollBoxTrack(IScrollEvent &event) { checkFocus(); if (cursorEnabled) { hideCursor(); } moveScrollBox(event); reposition(); if (event.scrollBarWindow() == &verticalScrollBar) { int line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); if (cursorEnabled) { showCursor(); } return true; } if (cursorEnabled) { showCursor(); } //if (event.scrollBarWindow() != &horizontalScrollBar) return false; return true; } AgView &AgView::setCursorLocation(cint loc) { //LOGSECTION("AgView::setCursorLocation", Log::off); LOGSECTION_OFF("AgView::setCursorLocation"); //LOGSTACK; //hideCursor(); if (loc.y < 0) { loc.y = 0; } if (loc.y >= nLines()) { loc.y = nLines() - 1; } LOGV(cursorLocation); LOGV(loc); cursorLocation = loc; unsigned oldCursor = cursorLine; cursorLine = loc.y; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); pixelCursor.y = lineHeight()*cursorLine; int repositionFlag = 0; int vPos = verticalScrollBar.scrollBoxPosition(); int vLimit = vPos + verticalScrollBar.visibleCount() - 1; int hPos = horizontalScrollBar.scrollBoxPosition(); int hLimit = hPos + horizontalScrollBar.visibleCount() - 4; if (loc.y < vPos) { verticalScrollBar.moveScrollBoxTo(loc.y); repositionFlag = 1; } if (loc.y > vLimit) { verticalScrollBar.moveScrollBoxTo(vPos + loc.y - vLimit); repositionFlag = 1; } if (pixelCursor.x < hPos) { int x; int cursorX = cursorLocation.x - 5; if (cursorX <= 0) { x = 0; } else x = xPosition(cursorX, getLine(cursorLine)); horizontalScrollBar.moveScrollBoxTo(x); repositionFlag = 1; } if (pixelCursor.x > hLimit) { int x = xPosition(cursorLocation.x+5, getLine(cursorLine)); horizontalScrollBar.moveScrollBoxTo(hPos + x - hLimit); repositionFlag = 1; } LOGV(vPos); LOGV(vLimit); LOGV(repositionFlag); if (repositionFlag) reposition(); if (cursorLineHighlight && cursorLine != oldCursor) { repaintLine(oldCursor); repaintLine(cursorLine); } setCursorPos(pixelCursor); //showCursor(); return *this; } AgView &AgView::scrollTo(cint loc) { //LOGSECTION("AgView::scrollTo", Log::on); LOGSECTION_ON("AgView::scrollTo"); //LOGSTACK; //hideCursor(); if (loc.y < 0) { loc.y = 0; } if (loc.y >=nLines()) { loc.y = nLines() - 1; } LOGV(cursorLocation); LOGV(loc); cint pixel; pixel.x = xPosition(loc.x, getLine(loc.y)); pixel.y = lineHeight()*loc.y; int repositionFlag = 0; int vPos = verticalScrollBar.scrollBoxPosition(); int vLimit = vPos + verticalScrollBar.visibleCount() - 1; int hPos = horizontalScrollBar.scrollBoxPosition(); int hLimit = hPos + horizontalScrollBar.visibleCount() - 4; if (loc.y < vPos) { verticalScrollBar.moveScrollBoxTo(loc.y); repositionFlag = 1; } if (loc.y > vLimit) { verticalScrollBar.moveScrollBoxTo(vPos + loc.y - vLimit); repositionFlag = 1; } if (pixel.x < hPos) { int x; int cursorX = loc.x - 5; if (cursorX <= 0) { x = 0; } else { x = xPosition(cursorX, getLine(loc.y)); } horizontalScrollBar.moveScrollBoxTo(x); repositionFlag = 1; } if (pixel.x > hLimit) { int x = xPosition(loc.x+5, getLine(loc.y)); horizontalScrollBar.moveScrollBoxTo(hPos + x - hLimit); repositionFlag = 1; } LOGV(vPos); LOGV(vLimit); LOGV(repositionFlag); if (repositionFlag) { reposition(); } return *this; } Boolean AgView::virtualKeyPress(IKeyboardEvent &event) { //LOGSECTION("AgView::Virtual key press", Log::off); LOGSECTION_OFF("AgView::Virtual key press"); switch (event.virtualKey()) { case IKeyboardEvent::up: { if (!cursorLineHighlight && !cursorEnabled) { int line = verticalScrollBar.scrollBoxPosition() - 1; verticalScrollBar.moveScrollBoxTo(line); line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); return true; } int line = cursorLine; if (cursorLine <= 0) { messageBeep(); return true; } if (cursorEnabled) { hideCursor(); } cursorLine--; LOGV(cursorLine) LCV(verticalScrollBar.scrollBoxPosition()); if (cursorLine < verticalScrollBar.scrollBoxPosition()) { if (cursorLineHighlight) { repaintLine(line); } verticalScrollBar.moveScrollBoxTo(cursorLine); reposition(); } else if (cursorLineHighlight) { repaintLine(line); repaintLine(cursorLine); } cursorLocation.y = cursorLine; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); pixelCursor.y = lineHeight()*cursorLine; if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } case IKeyboardEvent::down: { LOGSECTION("Cursor down one line"); if (!cursorLineHighlight && !cursorEnabled) { int line = verticalScrollBar.scrollBoxPosition() + 1; verticalScrollBar.moveScrollBoxTo(line); line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); return true; } int line = cursorLine; if (cursorLine >= nLines() - 1) { messageBeep(); return true; } if (cursorEnabled) { hideCursor(); } cursorLine++; LOGV(cursorLine); int bottomLine = verticalScrollBar.scrollBoxPosition() + verticalScrollBar.visibleCount() - 1; LOGV(line); LOGV(cursorLine); LOGV(bottomLine); if (cursorLine > bottomLine) { if (cursorLineHighlight) { repaintLine(line); } int newLine = cursorLine - verticalScrollBar.visibleCount() + 1; verticalScrollBar.moveScrollBoxTo(newLine); reposition(); } else if (cursorLineHighlight) { repaintLine(line); repaintLine(cursorLine); } cursorLocation.y = cursorLine; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); pixelCursor.y = lineHeight()*cursorLine; if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } case IKeyboardEvent::pageUp: { LOGSECTION("AgView::pageUp"); if (event.isCtrlDown()) { if (cursorLine == 0) { messageBeep(); return true; } verticalScrollBar.moveScrollBoxTo(0); int oldCursor = cursorLine; cursorLine = 0; if (cursorLineHighlight) { repaintLine(oldCursor); repaintLine(cursorLine); } reposition(); cursorLocation.y = pixelCursor.y = 0; if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } if (!cursorLineHighlight && !cursorEnabled) { int line = verticalScrollBar.scrollBoxPosition(); line -= verticalScrollBar.visibleCount(); verticalScrollBar.moveScrollBoxTo(line); line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); return true; } int line = cursorLine; if (cursorLine <= 0) { return true; } if (cursorEnabled) { hideCursor(); } cursorLine -= verticalScrollBar.visibleCount(); if (cursorLine < 0) { cursorLine = 0; } if (cursorLine < verticalScrollBar.scrollBoxPosition()) { verticalScrollBar.moveScrollBoxTo(cursorLine); reposition(); } else if (cursorLineHighlight) { repaintLine(line); } cursorLocation.y = cursorLine; pixelCursor.y = lineHeight()*cursorLine; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } case IKeyboardEvent::pageDown: { LOGSECTION("AgView::pageDown"); if (event.isCtrlDown()) { if (cursorLine >= nLines() - 1) { messageBeep(); return true; } //cursorLine = verticalScrollBar.scrollableRange().upperBound(); cursorLine = nLines() - 1; LOGV(cursorLine); verticalScrollBar.moveScrollBoxTo(cursorLine); updateCursor(cursorLine); cursorLocation.y = cursorLine; pixelCursor.y = cursorLine*lineHeight(); return true; } if (!cursorLineHighlight && !cursorEnabled) { int line = verticalScrollBar.scrollBoxPosition(); line += verticalScrollBar.visibleCount(); verticalScrollBar.moveScrollBoxTo(line); line = verticalScrollBar.scrollBoxPosition(); updateCursor(line); } int lastLine = nLines() - 1; if (cursorLine >= lastLine) { return true; } if (cursorEnabled) { hideCursor(); } int line = cursorLine; cursorLine += verticalScrollBar.visibleCount(); pixelCursor.y = lineHeight()*cursorLine; if (cursorLine > lastLine) { cursorLine = lastLine; } if (cursorLine > verticalScrollBar.scrollBoxPosition()) { int newLine = cursorLine - verticalScrollBar.visibleCount() + 1; verticalScrollBar.moveScrollBoxTo(newLine); reposition(); } else if (cursorLineHighlight) { repaintLine(line); } cursorLocation.y = cursorLine; pixelCursor.y = lineHeight()*cursorLine; pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } case IKeyboardEvent::left: { if (cursorEnabled) { hideCursor(); if (cursorLocation.x > 0) { cursorLocation.x--; } pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); if (pixelCursor.x < horizontalScrollBar.scrollBoxPosition()) { int hPos = pixelCursor.x; if (cursorLocation.x == 0) { hPos = 0; } horizontalScrollBar.moveScrollBoxTo(hPos); reposition(); } setCursorPos(pixelCursor); showCursor(); return true; } pixelCursor.x = horizontalScrollBar.scrollBoxPosition(); pixelCursor.x -= avgCharWidth(); if (pixelCursor.x < 0) { pixelCursor.x = 0; } horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); reposition(); updateCursor(); return true; } case IKeyboardEvent::right: { LOGS("cursor right"); if (cursorEnabled) { hideCursor(); LOGS("cursor hidden"); AgString line = getLine(cursorLine); if (cursorLocation.x < line.size()) { cursorLocation.x++; } pixelCursor.x = xPosition(cursorLocation.x, line); int hPos = horizontalScrollBar.scrollBoxPosition(); int rightEdge = hPos + horizontalScrollBar.visibleCount() - 4; if (pixelCursor.x > rightEdge) { hPos += pixelCursor.x - rightEdge; horizontalScrollBar.moveScrollBoxTo(hPos); reposition(); } setCursorPos(pixelCursor); LOGS("cursor moved"); showCursor(); LOGS("cursor restored"); return true; } pixelCursor.x = horizontalScrollBar.scrollBoxPosition(); pixelCursor.x += avgCharWidth(); int netWidth = tableWidth - horizontalScrollBar.visibleCount(); if (pixelCursor.x > netWidth) { pixelCursor.x = netWidth; } horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); reposition(); cursorLocation.x = pixelCursor.x/avgCharWidth(); updateCursor(); return true; } case IKeyboardEvent::home: { if (event.isCtrlDown()) { if (cursorLine == 0) { messageBeep(); return true; } verticalScrollBar.moveScrollBoxTo(0); int oldCursor = cursorLine; cursorLine = 0; if (cursorLineHighlight) { repaintLine(oldCursor); repaintLine(cursorLine); } reposition(); cursorLocation.y = pixelCursor.y = 0; if (cursorEnabled) { setCursorPos(pixelCursor).showCursor(); } return true; } pixelCursor.x = avgCharWidth(); cursorLocation.x = 0; horizontalScrollBar.moveScrollBoxTo(0); reposition(); updateCursor(); return true; } case IKeyboardEvent::end: { if (event.isCtrlDown()) { if (cursorLine >= nLines() - 1) { messageBeep(); return true; } //cursorLine = verticalScrollBar.scrollableRange().upperBound(); cursorLine = nLines() - 1; LOGV(cursorLine); verticalScrollBar.moveScrollBoxTo(cursorLine); updateCursor(cursorLine); cursorLocation.y = cursorLine; pixelCursor.y = cursorLine*lineHeight(); return true; } if (cursorEnabled) { LOGSECTION("AgView::end"); hideCursor(); AgString line = getLine(cursorLocation.y); cursorLocation.x = line.size(); LOGV(cursorLocation); LOGV(line.size()); pixelCursor.x = xPosition(cursorLocation.x, line); LOGV(charPosition(pixelCursor.x, line)); int hPos = horizontalScrollBar.scrollBoxPosition(); int rightEdge = hPos + horizontalScrollBar.visibleCount() - 4; if (pixelCursor.x > rightEdge) { hPos += pixelCursor.x - rightEdge; horizontalScrollBar.moveScrollBoxTo(hPos); reposition(); } setCursorPos(pixelCursor); LOGS("cursor moved"); showCursor(); return true; } pixelCursor.x = tableWidth - horizontalScrollBar.visibleCount(); horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); reposition(); updateCursor(); return true; } } return false; } Boolean AgView::mouseClicked(IMouseClickEvent &event) { //LOGSECTION("AgView::mouseClickEvent", Log::off); LOGSECTION_OFF("AgView::mouseClickEvent"); LOGV(event.mouseButton()); LOGV(event.mouseAction()); if (event.controlWindow() == &columnHeadTitle || event.controlWindow() == &verticalScrollBar || event.controlWindow() == &horizontalScrollBar) { if (event.mouseAction() == IMouseClickEvent::down) { dataArea.setFocus(); } return false; } if (ControlPanel::helpCursorSet) { if (event.mouseAction() == IMouseClickEvent::down) { ControlPanel::helpCursorSet = 0; ControlPanel::resetCursor(); } } int line = event.mousePosition().y()/lineHeight(); LOGV(line) LCV(verticalScrollBar.scrollBoxPosition()); line += verticalScrollBar.scrollBoxPosition(); LOGV(line); //if (line >= nLines()) line = nLines() - 1; if (event.mouseButton() == IMouseClickEvent::button2) { if (event.mouseAction() == IMouseClickEvent::down) { rightButtonDown = true; } else if (event.mouseAction() == IMouseClickEvent::up) { rightButtonDown = false; } return false; /* else if (event.mouseAction() == IMouseClickEvent::click) { if (line == cursorLine) { return true; } if (cursorLineHighlight) { int oldLine = cursorLine; cursorLine = line; LOGV(oldLine) LCV(cursorLine); repaintLine(oldLine); repaintLine(cursorLine); } return true; } */ } if (event.mouseButton() != IMouseClickEvent::button1) { return false; } if (line >= nLines() && !mouseDown) { if (!dataArea.hasFocus()) { dataArea.setFocus(); } return false; } switch (event.mouseAction()) { case IMouseClickEvent::down: { if (event.windowUnderPointer() != dataArea.handle()) { return false; } if (!cursorLineHighlight) { return false; } dataArea.capturePointer(true); mouseDownCursorLine = cursorLine; //int line = event.mousePosition().y()/lineHeight(); int offset = horizontalScrollBar.scrollBoxPosition(); int whereX = event.mousePosition().x() + offset; LOGV(cursorLine) LCV(offset) LCV(whereX); AgString text = getLine(line); cint loc(charPosition(whereX, text), line); LOGV(loc); cursorLocation = loc; if (line != cursorLine) { cursorLine = line; if (cursorLineHighlight) { LOGV(mouseDownCursorLine) LCV(cursorLine); repaintLine(mouseDownCursorLine); repaintLine(cursorLine); } onSelect(); } mouseDown = true; return false; } case IMouseClickEvent::up: { mouseDown = false; dataArea.capturePointer(false); return false; } case IMouseClickEvent::click: { if (event.windowUnderPointer() != dataArea.handle()) { return false; } dataArea.setFocus(); //if (line == mouseDownCursorLine) { // onSelect(); //} return false; } case IMouseClickEvent::doubleClick: { dataArea.setFocus(); //onSelect(); onEnter(); return false; } } return false; } Boolean AgView::mouseMoved(IMouseEvent &event) { if (!mouseDown) { return false; } if (!cursorLineHighlight) { return false; } if (mouseTimer.isStarted()) { mouseTimer.stop(); } int mouseY = event.mousePosition().y(); if (mouseY < 0) { mouseY -= lineHeight(); } int mouseLine = mouseY/lineHeight(); int topLine = verticalScrollBar.scrollBoxPosition(); //LOGSECTION("Mouse moved", Log::off); LOGSECTION_OFF("Mouse moved"); LOGV(topLine) LCV(mouseLine); dragMouse(topLine, mouseLine); topLine = verticalScrollBar.scrollBoxPosition(); int belowLine = topLine + verticalScrollBar.visibleCount(); if (mouseLine >= topLine && mouseLine < belowLine) { return true; } IReference<ITimerFn> timerFn(new MouseDragTimer(this, topLine, mouseLine)); mouseTimer.start(timerFn, 50); LOGS("timer started"); return false; } void AgView::dragMouse(int topLine, int mouseLine) { //LOGSECTION("Agview::dragMouse", Log::off); LOGSECTION_OFF("Agview::dragMouse"); int bottomLine = topLine + verticalScrollBar.visibleCount() - 1; int line = topLine + mouseLine; if (line < 0) { line = 0; } if (line >= nLines()) { line = nLines() - 1; } if (line == cursorLine) { return; } int oldLine = cursorLine; cursorLocation.y = cursorLine = line; pixelCursor.y = lineHeight()*cursorLine; if (cursorLine < topLine) { if (cursorLineHighlight) repaintLine(oldLine); verticalScrollBar.moveScrollBoxTo(cursorLine); reposition(); return; } if (cursorLine > bottomLine) { if (cursorLineHighlight) { repaintLine(oldLine); } verticalScrollBar.moveScrollBoxTo(topLine + cursorLine - bottomLine); reposition(); return; } if (cursorLineHighlight) { repaintLine(oldLine); repaintLine(cursorLine); } return; } void AgView::mouseDragTimerInterrupt(int &topLine, int mouseLine) { //LOGSECTION("AgView::mouseDragTimer", Log::off); LOGSECTION_OFF("AgView::mouseDragTimer"); LOGV(topLine) LCV(mouseLine) LCV(cursorLine); if (!mouseDown || topLine + mouseLine == cursorLine) { mouseTimer.stop(); LOGV(mouseDown); LOGV(topLine) LCV(verticalScrollBar.scrollBoxPosition()); return; } if (topLine + mouseLine != cursorLine) { dragMouse(topLine, mouseLine); } topLine = verticalScrollBar.scrollBoxPosition(); } AgView::MouseDragTimer::MouseDragTimer(AgView * window_, int topLine_, int mouseLine_) : window(window_) , topLine(topLine_) , mouseLine(mouseLine_) {} void AgView::MouseDragTimer::timerExpired(unsigned long) { //LOGSECTION("AgView::MouseDragTimer::timerExpired", Log::off); LOGSECTION_OFF("AgView::MouseDragTimer::timerExpired"); window->mouseDragTimerInterrupt(topLine, mouseLine); }