📄 mimerichtextdraw.c
字号:
int e=0; for (e=0; e<state->Excerpt(); e++) { XDrawString(halApp->display, drawto, textGC, x-hsbVal, y-vsbVal, excerptStr, excerptStr.size()); x += excerptWd; } } // End if excerpting//// Loop through data// RichDrawDataC *dd = line->drawData; while ( dd ) { lineX = dd->x; state = line->textLine->State(dd->cmdPos);//// Set color if necessary// Pixel color = fgColor; if ( state->PLinkCount() > 0 ) color = linkColor; else if ( state->URL() ) color = urlColor; else { color = state->CurColor(); if ( color == (Pixel)NULL ) color = fgColor; } if ( *lastColor != color ) { XSetForeground(halApp->display, textGC, color); *lastColor = color; }//// Underline if necessary// if ( dd->underline ) { int underY = botY + 1 + dd->font->underY; for (int u=0; u<dd->font->underThick; u++) { XDrawLine(halApp->display, drawto, textGC, lineX-hsbVal, underY-vsbVal, lineX-hsbVal+dd->width, underY-vsbVal); underY++; } }//// Draw text if present// if ( dd->string.size() > 0 && dd->string[0] != '\t' ) { int y = botY - line->descent;//// Set font if necessary// if ( *lastFont != dd->font->fid ) { XSetFont(halApp->display, textGC, dd->font->fid); *lastFont = dd->font->fid; } if ( debuglev > 1 ) cout <<"Drawing text ^" <<dd->string <<"^ at: " <<lineX <<" " <<y <<endl; XDrawString(halApp->display, drawto, textGC, lineX-hsbVal, y-vsbVal, dd->string, dd->string.size()); } // End if not a tab//// Draw graphic if present// if ( dd->graphic ) {//// Apply the scroll offsets// dd->graphic->bounds.xmin -= hsbVal; dd->graphic->bounds.xmax -= hsbVal; dd->graphic->bounds.ymin -= vsbVal; dd->graphic->bounds.ymax -= vsbVal;//// Draw the graphic// dd->graphic->Show(); dd->graphic->Refresh();//// Undo the scroll offsets// dd->graphic->bounds.xmin += hsbVal; dd->graphic->bounds.xmax += hsbVal; dd->graphic->bounds.ymin += vsbVal; dd->graphic->bounds.ymax += vsbVal; } // End if there is a graphic#if 0 if ( debuglev > 1 ) XDrawRectangle(halApp->display, drawto, textGC, lineX-hsbVal, line->bounds.ymin-vsbVal, dd->width, line->bounds.ht);#endif dd = dd->next; } // End for each draw data} // End DrawLine/*---------------------------------------------------------------------- * Hide any graphics for the specified line */voidMimeRichTextP::HideLineGraphics(SoftLineC *line){//// Loop through data// RichDrawDataC *dd = line->drawData; while ( dd ) { if ( dd->graphic ) dd->graphic->Hide(); dd = dd->next; }} // End HideLineGraphics/*--------------------------------------------------------------- * Handle a keyboard focus change event in the area */voidMimeRichTextP::HandleFocusChange(Widget, MimeRichTextP *This, XEvent *ev, Boolean*){ switch (ev->type) {//// Start the cursor blinking again// case (FocusIn): case (EnterNotify): {#if 0 if ( debuglev > 1 ) { if ( ev->type == FocusIn ) cout <<"FocusIn" <<endl; else cout <<"EnterNotify" <<endl; }#endif if ( This->cursorTimer ) { XtRemoveTimeOut(This->cursorTimer); This->cursorTimer = (XtIntervalId)NULL; } if ( This->hlForm ) XtVaSetValues(This->hlForm, XmNbackground, This->hlColor, NULL); WArgList args; XPoint spot = This->CursorLocation(); args.Add("XmNspotLocation", &spot); XmImSetFocusValues(This->textDA, ARGS); This->hasFocus = True; if ( This->realized ) { CursorBlink(This, NULL); XmProcessTraversal(This->textDA, XmTRAVERSE_CURRENT); } } break;//// Stop the cursor blinking// case (FocusOut): case (LeaveNotify):#if 0 if ( debuglev > 1 ) { if ( ev->type == FocusOut ) cout <<"FocusOut" <<endl; else cout <<"LeaveNotify" <<endl; }#endif if ( This->cursorTimer ) { XtRemoveTimeOut(This->cursorTimer); This->cursorTimer = (XtIntervalId)NULL; } if ( This->hlForm ) XtVaSetValues(This->hlForm, XmNbackground, This->hlFormBg, NULL); if ( This->cursorOn ) This->DrawCursor(); // Turn it off XmImUnsetFocus(This->textDA); This->hasFocus = False; break; }} // End HandleFocusChange/*--------------------------------------------------------------- * Timer proc to blink insertion cursor */voidMimeRichTextP::CursorBlink(MimeRichTextP *This, XtIntervalId*){#if 0 if ( debuglev > 1 ) { cout <<"CursorBlink"; if ( This->cursorOn ) cout <<" turning off"; else cout <<" turning on"; cout <<endl; }#endif int nextTime = This->cursorOn ? This->cursorOffTime : This->cursorOnTime;//// Draw the cursor if there is a non-zero interval for the next state or// if we have lost focus and the cursor is on.// if ( nextTime > 0 || (!This->hasFocus && This->cursorOn) ) This->DrawCursor(); // Draw the cursor using XOR mode//// Set up the next blink// if ( This->timerOk && nextTime > 0 && This->hasFocus ) This->cursorTimer = XtAppAddTimeOut(halApp->context, nextTime, (XtTimerCallbackProc)CursorBlink, (XtPointer)This);} // End CursorBlink/*--------------------------------------------------------------- * Draws the cursor using XOR mode. May turn it on, may turn it off. * Depends on whether it was on or off previously. */voidMimeRichTextP::DrawCursor(){ ScreenPosC pos = cursorPos; int ht = 0; if ( pos.softLine ) ht = pos.softLine->bounds.ht; int x = pos.x - hsbVal; int y = (pos.softLine ? pos.softLine->bounds.ymin : 0) - vsbVal - 1; if ( y < 0 ) { ht += y; // Reduce height. y is negative y = 0; } else if ( y+ht > (int)drawHt ) { ht = drawHt - y; } if ( ht <= 0 ) ht = plainFont.xfont->ascent + plainFont.xfont->descent; XSetFunction(halApp->display, textGC, GXxor); XSetForeground(halApp->display, textGC, cursorColor);#if 0 if ( debuglev > 1 ) cout <<"DrawCursor at " <<x <<" " <<y <<endl;#endif XDrawLine(halApp->display, textWin, textGC, x, y, x, y+ht-1); if ( editable ) { XDrawLine(halApp->display, textWin, textGC, x-2, y, x+2, y); XDrawLine(halApp->display, textWin, textGC, x-2, y+ht-1, x+2, y+ht-1); } XSetFunction(halApp->display, textGC, GXcopy); XSetForeground(halApp->display, textGC, fgColor); cursorOn = !cursorOn;}/*--------------------------------------------------------------- * Turn the cursor off */voidMimeRichTextP::HideCursor(){ cursorHideCount++; if ( cursorHideCount > 1 ) return; if ( cursorTimer ) { XtRemoveTimeOut(cursorTimer); cursorTimer = (XtIntervalId)NULL; } lastCursorPos = cursorPos; if ( cursorOn ) DrawCursor(); // To turn it off}/*--------------------------------------------------------------- * Turn the cursor on */voidMimeRichTextP::ShowCursor(){ if ( cursorHideCount > 0 ) { cursorHideCount--; if ( cursorHideCount > 0 ) return; } if ( !cursorOn && hasFocus ) CursorBlink(this, NULL);//// Update the cursor state// RichCmdC *cmd = cursorPos.Cmd(); if ( cmd && lastCursorState != cmd->state ) { lastCursorState = cmd->state; CallCallbacks(stateCalls, pub); }//// Update the input manager// if ( hasFocus && cursorPos != lastCursorPos ) { WArgList args; XPoint spot = CursorLocation(); args.Add("XmNspotLocation", &spot); XmImSetFocusValues(textDA, ARGS); lastCursorPos = cursorPos; }} // End ShowCursor/*----------------------------------------------------------------------- * Return the x/y position of the cursor */XPointMimeRichTextP::CursorLocation(){ ScreenPosC spos(cursorPos); XPoint loc; loc.x = spos.x; loc.y = spos.softLine ? spos.softLine->bounds.ymax : 0; return loc;}/*--------------------------------------------------------------- * Scroll the window so the cursor stays visible */BooleanMimeRichTextP::ScrollToCursor(){ ScreenPosC spos = cursorPos; return ScrollToPosition(spos);}/*--------------------------------------------------------------- * Scroll the window so the specified position stays visible */BooleanMimeRichTextP::ScrollToPosition(ScreenPosC& spos){ int x = spos.x; int y = spos.softLine ? spos.softLine->bounds.ymin : 0;//// Calculate the bounds of the visible area. Use the scroll bar parameters.// int xmin, xmax, ymin, ymax, sbwd, sbht; if ( textSW ) { XtVaGetValues(textHSB, XmNvalue, &xmin, XmNsliderSize, &sbwd, NULL); XtVaGetValues(textVSB, XmNvalue, &ymin, XmNsliderSize, &sbht, NULL); } else { xmin = hsbVal; ymin = vsbVal; sbwd = drawWd; sbht = drawHt; } xmax = xmin + sbwd - 1; ymax = ymin + sbht - 1; int charWd = pub->CharWidth(); int lineHt = 0; if ( spos.softLine ) lineHt = spos.softLine->bounds.ht; if ( lineHt == 0 ) lineHt = pub->CharHeight();//// Test the x position against the visible region// int val, size, inc, pinc, sbmax; if ( (x < xmin) || (x+charWd > xmax) ) { XmScrollBarGetValues(textHSB, &val, &size, &inc, &pinc); XtVaGetValues(textHSB, XmNmaximum, &sbmax, NULL); if ( x < xmin ) val = x; else val = xmin + (x+charWd - xmax); if ( val + sbwd > sbmax ) val = sbmax - sbwd; XmScrollBarSetValues(textHSB, val, sbwd, inc, pinc, True); }//// Test the y position against the visible region// if ( (y < ymin) || (y+lineHt > ymax) ) { XmScrollBarGetValues(textVSB, &val, &size, &inc, &pinc); XtVaGetValues(textVSB, XmNmaximum, &sbmax, NULL); if ( y < ymin ) val = y; else val = ymin + (y+lineHt - ymax); if ( val + sbht > sbmax ) val = sbmax - sbht; XmScrollBarSetValues(textVSB, val, sbht, inc, pinc, True); } return True;} // End ScrollToPosition/*--------------------------------------------------------------- * Determine if the specified soft line is completely visible */BooleanMimeRichTextP::LineFullyVisible(SoftLineC *line){ if ( !textVSB ) return True;//// Calculate the bounds of the visible area. Use the scroll bar parameters.// int ymin, ymax, sbht; XtVaGetValues(textVSB, XmNvalue, &ymin, XmNsliderSize, &sbht, NULL); ymax = ymin + sbht - 1;//// Test the position against the visible region// if ( line->bounds.ymin < ymin || line->bounds.ymax > ymax ) return False; return True;} // End LineFullyVisible/*--------------------------------------------------------------- * Determine if any part of the specified soft line is visible */BooleanMimeRichTextP::LineVisible(SoftLineC *line){//// Calculate the bounds of the visible area. Use the scroll bar parameters.// int ymin, ymax, sbht; XtVaGetValues(textVSB, XmNvalue, &ymin, XmNsliderSize, &sbht, NULL); ymax = ymin + sbht - 1;//// Test the position against the visible region// if ( line->bounds.ymax < ymin || line->bounds.ymin > ymax ) return False; return True;} // End LineVisible/*----------------------------------------------------------------------- * Defer changes */voidMimeRichTextC::Defer(Boolean on){ if ( on ) { priv->defer++; // Up the count } else if ( priv->defer>0 ) { // Turn off only if deferred priv->defer--; // Refresh if last turn-off if ( (priv->defer==0) && priv->changed ) { Refresh(); CallCallbacks(priv->changeCalls, this); } }} // End Defer/*----------------------------------------------------------------------- * Make deferred changes */voidMimeRichTextC::Refresh(){// halApp->BusyCursor(True); int saveDefer = priv->defer; priv->defer = 0; priv->FormatScreen(); RectC area(0, 0, priv->drawWd, priv->drawHt); priv->DrawScreen(area); priv->defer = saveDefer;// halApp->BusyCursor(False);} // End Refresh/*----------------------------------------------------------------------- * Constructor for soft line data */SoftLineC::SoftLineC(){ textLine = NULL; totalWd = 0; descent = 0; drawData = NULL; prev = NULL; next = NULL;}/*----------------------------------------------------------------------- * Destructor for soft line data */SoftLineC::~SoftLineC(){ RichDrawDataC *data = drawData; while ( data ) { RichDrawDataC *next = data->next; delete data; data = next; }}/*---------------------------------------------------------------------- * Add a draw data record to the draw data list */voidSoftLineC::AddDrawData(RichDrawDataC *data){ if ( !drawData ) { drawData = data; return; } RichDrawDataC *last = LastData(); last->next = data; data->prev = last;}/*----------------------------------------------------------------------- * Method to see if the specified point is within a graphic */RichGraphicC*MimeRichTextP::PickGraphic(int x, int y){//// Scroll the positions// x += hsbVal; y += vsbVal;//// Loop through the graphics// u_int count = graphicList.size(); if ( count == 0 ) return NULL; int i=0; for (i=0; i<count; i++) { RichGraphicC *rg = (RichGraphicC*)*graphicList[i]; if ( rg->bounds.Inside(x, y) ) return rg; } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -