void DisplayElement::GetBounds (WebRect *rect) { if (mFlags & DISPLAY_FLAG_BOUNDS_VALID) { *rect = mBounds; return; } *rect = mRect; WebRect childRect; DisplayElement *pChild = mpFirstChild; while (pChild) { if (!(pChild->mFlags & DISPLAY_FLAG_FIXED_POS)) { pChild->GetBounds(&childRect); childRect.Shift(mRect.left, mRect.top); rect->Or(&childRect); } pChild = pChild->mpNext; } SetFlag(DISPLAY_FLAG_BOUNDS_VALID); mBounds = *rect; }
void DisplayElement::InvalidateChild (DisplayElement *pChild, WebRect *pDirty) { WebRect dirty; dirty.Set(pDirty); dirty.Shift(mRect.left, mRect.top); if (GetOverflow() == DISPLAY_OVERFLOW_HIDDEN) { WebRect clipRect; GetClipRect(&clipRect); // If completely outside clipping rect, stop here if (!dirty.Overlaps(&clipRect)) { return; } // clip pDirty to our rect dirty.And(&clipRect); } if ((mFlags & DISPLAY_FLAG_FIXED_POS) || !mpParent) { DisplayManager *pManager = GetManager(); if (pManager) { if (mFlags & DISPLAY_FLAG_FIXED_POS) { dirty.Shift(pManager->mViewRect.left, pManager->mViewRect.top); } pManager->InvalidateViewportRegion(&dirty); } } else { mpParent->InvalidateChild(this, &dirty); } }
/*---------------------------------------------------------------------------*/ template<class T> IPositionedFormatContext* HTMLElementDisplay<T>::FormatSelfPositioned ( DisplayElement* displayParent, IPositionedFormatContext* rootContext, IPositionedFormatContext* parentContext, FormatContextFactory* childContextFactory, WEBC_BOOL generateChildContext ) { WebRect rect; WEBC_UINT16 position = GetPosition(); IPositionedFormatContext* childContext = 0; if (position == TU_POSITION_RELATIVE) { if (generateChildContext) { const WebRect * tmpRect = &(((DisplayElement *)(this))->mRect); rect.Set(tmpRect); rect.MoveTo(0,0); CSSLength height; GetCSSLength(&height, CSS_PROPERTY_HEIGHT); childContext = childContextFactory->newPositioned ( &rect, (height.type == CSS_LENGTH_UNIT_AUTO) || (height.type == CSS_LENGTH_UNIT_PERCENT && parentContext->parentHeightIsAuto()), // parent height is auto TU_DIR_LTR, 0, // border-left-width 0, // border-top-width 0, // border-right-width 0, // border-bottom-width 0, // autoIndentLeft 0, // autoIndentTop 0 // autoIndentRight ); } } else { WebRect containingBlock; IPositionedFormatContext* containingContext; DISPLAY_INT borderLeftValue; DISPLAY_INT borderTopValue; DISPLAY_INT borderRightValue; DISPLAY_INT borderBottomValue; if (displayParent) { if (displayParent != T::mpParent) { mHtmlElementDisplayFlags &= ~HELEM_DISPLAY_FLAG_STYLE_SET; } displayParent->InsertOrdered(this); } if (position == TU_POSITION_FIXED) { T::SetFixedPosition(WEBC_TRUE); containingContext = rootContext; } else { T::SetFixedPosition(WEBC_FALSE); containingContext = parentContext; } containingContext->getContainingBlock(&containingBlock); WEBC_BOOL parentHeightIsAuto = containingContext->parentHeightIsAuto(); int textDirection = containingContext->getTextDirection(); DISPLAY_INT parentBorderLeft = containingContext->getParentBorderLeft(); DISPLAY_INT parentBorderTop = containingContext->getParentBorderTop(); DISPLAY_INT parentBorderRight = containingContext->getParentBorderRight(); DISPLAY_INT parentBorderBottom = containingContext->getParentBorderBottom(); DISPLAY_INT autoIndentLeft = parentContext->getAutoIndentLeft(); DISPLAY_INT autoIndentTop = parentContext->getAutoIndentTop(); DISPLAY_INT autoIndentRight = parentContext->getAutoIndentRight(); if (position == TU_POSITION_FIXED) { WebRect parentRect; parentContext->getContainingBlock(&parentRect); autoIndentLeft += parentRect.left; autoIndentTop += parentRect.top; autoIndentRight += (containingBlock.right - parentRect.right); } DISPLAY_INT parentWidth = containingBlock.Width() - (parentBorderLeft + parentBorderRight); DISPLAY_INT parentHeight = containingBlock.Height() - (parentBorderTop + parentBorderBottom); WebFont font = mpHtmlElement->GetWebFont(); DISPLAY_INT emHeight = font? WEB_FONT_HEIGHT(font) : WEBC_CFG_DEFAULT_TEXT_HEIGHT; DISPLAY_INT exHeight = emHeight >> 1; // First find the left edge and width CSSLength left; CSSLength right; CSSLength width; // Find value for left, right, width, marginLeft, marginRight GetCSSLength(&left, CSS_PROPERTY_LEFT); GetCSSLength(&right, CSS_PROPERTY_RIGHT); GetCSSLength(&width, CSS_PROPERTY_WIDTH); DISPLAY_INT leftValue; DISPLAY_INT rightValue; DISPLAY_INT widthValue; DISPLAY_INT marginLeftValue; DISPLAY_INT paddingLeftValue; DISPLAY_INT paddingTopValue; DISPLAY_INT paddingRightValue; DISPLAY_INT paddingBottomValue; // Find value for padding and border paddingLeftValue = GetPixelLength(CSS_PROPERTY_PADDING_LEFT, parentWidth, emHeight, exHeight, 0); paddingTopValue = GetPixelLength(CSS_PROPERTY_PADDING_TOP, parentWidth, emHeight, exHeight, 0); paddingRightValue = GetPixelLength(CSS_PROPERTY_PADDING_RIGHT, parentWidth, emHeight, exHeight, 0); paddingBottomValue = GetPixelLength(CSS_PROPERTY_PADDING_BOTTOM, parentWidth, emHeight, exHeight, 0); borderLeftValue = GetBorderWidth(CSS_LEFT, parentWidth, emHeight, exHeight, parentBorderLeft); borderTopValue = GetBorderWidth(CSS_TOP, parentWidth, emHeight, exHeight, parentBorderTop); borderRightValue = GetBorderWidth(CSS_RIGHT, parentWidth, emHeight, exHeight, parentBorderRight); borderBottomValue = GetBorderWidth(CSS_BOTTOM, parentWidth, emHeight, exHeight, parentBorderBottom); CSSLength height; CSSLength top; CSSLength bottom; DISPLAY_INT heightValue=0; WEBC_BOOL heightIsAuto=0; GetCSSLength(&height, CSS_PROPERTY_HEIGHT); GetCSSLength(&top, CSS_PROPERTY_TOP); #define NOTHING_KNOWN 0 #define HEIGHT_KNOWN 1 #define TOP_KNOWN 2 #define BOTTOM_KNOWN 4 WEBC_UINT8 verticalCase; verticalCase = (height.type == CSS_LENGTH_UNIT_AUTO || (height.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto))? 0 : HEIGHT_KNOWN; verticalCase |= (top.type == CSS_LENGTH_UNIT_AUTO)? 0 : TOP_KNOWN; if (verticalCase != (HEIGHT_KNOWN|TOP_KNOWN)) { GetCSSLength(&bottom, CSS_PROPERTY_BOTTOM); verticalCase |= (bottom.type == CSS_LENGTH_UNIT_AUTO || parentHeightIsAuto)? 0 : BOTTOM_KNOWN; } DISPLAY_INT topValue = 0; DISPLAY_INT bottomValue = 0; DISPLAY_INT marginTopValue = 0; DISPLAY_INT marginBottomValue = 0; switch (verticalCase) { case NOTHING_KNOWN: // top = auto indent top // height = content height topValue = autoIndentTop; heightValue = 0; heightIsAuto = WEBC_TRUE; marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0); break; case HEIGHT_KNOWN: // top = auto indent top // height = height topValue = autoIndentTop; heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight); heightIsAuto = WEBC_FALSE; marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0); break; case TOP_KNOWN: // top = top // height = content height if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto) { topValue = autoIndentTop; } else { topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight); } heightValue = 0; heightIsAuto = WEBC_TRUE; marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0); break; case HEIGHT_KNOWN|TOP_KNOWN: // top = top // height = height if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto) { topValue = autoIndentTop; } else { topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight); } heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight); heightIsAuto = WEBC_FALSE; marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0); break; case BOTTOM_KNOWN: // bottom = bottom // height = content height // top = parentHeight - (height + bottom) bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0); marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0); heightValue = 0; heightIsAuto = WEBC_TRUE; break; case HEIGHT_KNOWN|BOTTOM_KNOWN: // bottom = bottom // height = height // top = parentHeight - (height + bottom) bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0); heightValue = CSS_LengthToPixels(&height, parentHeight, emHeight, exHeight); heightIsAuto = WEBC_FALSE; marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0); topValue = parentHeight - (borderTopValue + paddingTopValue + heightValue + paddingBottomValue + borderBottomValue + marginBottomValue + bottomValue); break; case TOP_KNOWN|BOTTOM_KNOWN: // top = top // bottom = bottom // height = parentHeight - (top + bottom) if (top.type == CSS_LENGTH_UNIT_PERCENT && parentHeightIsAuto) { topValue = autoIndentTop; } else { topValue = CSS_LengthToPixels(&top, parentHeight, emHeight, exHeight); } bottomValue = GetPixelLength(&bottom, parentHeight, emHeight, exHeight, 0); marginTopValue = GetPixelLength(CSS_PROPERTY_MARGIN_TOP, parentWidth, emHeight, exHeight, 0); marginBottomValue = GetPixelLength(CSS_PROPERTY_MARGIN_BOTTOM, parentWidth, emHeight, exHeight, 0); heightValue = parentHeight - (topValue + marginTopValue + borderTopValue + paddingTopValue + paddingBottomValue + borderBottomValue + marginBottomValue + bottomValue); heightIsAuto = WEBC_FALSE; break; } if (width.type != CSS_LENGTH_UNIT_AUTO) { widthValue = CSS_LengthToPixels(&width, parentWidth, emHeight, exHeight); WEBC_BOOL leftAligned = (textDirection == TU_DIR_RTL)? (right.type == CSS_LENGTH_UNIT_AUTO && left.type != CSS_LENGTH_UNIT_AUTO) : (left.type != CSS_LENGTH_UNIT_AUTO || right.type == CSS_LENGTH_UNIT_AUTO); if (leftAligned) { // ignore right and margin-right leftValue = GetPixelLength(&left, parentWidth, emHeight, exHeight, autoIndentLeft); marginLeftValue = GetPixelLength(CSS_PROPERTY_MARGIN_LEFT, parentWidth, emHeight, exHeight, 0); } else { DISPLAY_INT marginRightValue; // ignore left and margin-left rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight); marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0); leftValue = parentWidth - (rightValue + marginRightValue + borderRightValue + paddingRightValue + widthValue + paddingLeftValue + borderLeftValue); marginLeftValue = 0; } } else { // width.type == CSS_LENGTH_UNIT_AUTO // try to get the intrinsic width of the element. This might rely on the // calculated height of the element; for example, in the case of an image with // specified height and auto width, the aspect ratio of the source image determines // the resulting intrinsic width. DISPLAY_INT marginRightValue; WEBC_BOOL hasIntrinsicWidth = GetIntrinsicWidth(&widthValue, heightValue, heightIsAuto); if (left.type == CSS_LENGTH_UNIT_AUTO && right.type != CSS_LENGTH_UNIT_AUTO && hasIntrinsicWidth) { rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight); marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0); marginLeftValue = 0; leftValue = parentWidth - (widthValue + borderLeftValue + paddingLeftValue + paddingRightValue + borderRightValue + marginRightValue + rightValue); } else { leftValue = GetPixelLength(&left, parentWidth, emHeight, exHeight, autoIndentLeft); marginLeftValue = GetPixelLength(CSS_PROPERTY_MARGIN_LEFT, parentWidth, emHeight, exHeight, 0); if (!hasIntrinsicWidth || (right.type != CSS_LENGTH_UNIT_AUTO && left.type != CSS_LENGTH_UNIT_AUTO)) { // right and left are both non-auto, OR element has no intrinsic width: // calculate left, right, and margins then extrapolate width rightValue = GetPixelLength(&right, parentWidth, emHeight, exHeight, autoIndentRight); marginRightValue = GetPixelLength(CSS_PROPERTY_MARGIN_RIGHT, parentWidth, emHeight, exHeight, 0); widthValue = parentWidth - (leftValue + marginLeftValue + borderLeftValue + paddingLeftValue + paddingRightValue + borderRightValue + marginRightValue + rightValue); // we don't want to stretch the width beyond what the maximum content // width; only give the element as much space as it actually needs. if (right.type == CSS_LENGTH_UNIT_AUTO || left.type == CSS_LENGTH_UNIT_AUTO) { // to speed this up, bail out of GetMaxWidth when we exceed widthValue DISPLAY_INT maxWidth = GetMaxWidthSmallerThan(widthValue); // NOTE: GetMaxWidth and GetMaxWidthSmallerThan return the total width // of the element, including borders and padding. So we must subtract // borders and padding to make it correspond to the contentWidth maxWidth -= (borderLeftValue + paddingLeftValue + paddingRightValue + borderRightValue); if (maxWidth < widthValue) { WEBC_BOOL leftAligned = (textDirection == TU_DIR_RTL)? (right.type == CSS_LENGTH_UNIT_AUTO && left.type != CSS_LENGTH_UNIT_AUTO) : (left.type != CSS_LENGTH_UNIT_AUTO || right.type == CSS_LENGTH_UNIT_AUTO); if (!leftAligned) { // box is right-aligned // adjust leftValue to account for the unused space leftValue += (widthValue - maxWidth); } widthValue = maxWidth; } } } } } // Now format the content of this element DISPLAY_INT contentHeight = FormatContentPositioned ( widthValue, heightValue, heightIsAuto, borderLeftValue, borderTopValue, borderRightValue, borderBottomValue, paddingLeftValue, paddingTopValue, paddingRightValue, paddingBottomValue ); // Find the top edge and height // NOTE: top and bottom percentages are relative to parent's HEIGHT, whereas // margin-top and margin-bottom are relative to parent's WIDTH, except in the root // context (tbd - handle this special case correctly) switch (verticalCase) { case NOTHING_KNOWN: case TOP_KNOWN: heightValue = contentHeight; break; case BOTTOM_KNOWN: // height = content height // top = parentHeight - (height + bottom) heightValue = contentHeight; topValue = parentHeight - (borderTopValue + paddingTopValue + heightValue + paddingBottomValue + borderBottomValue + marginBottomValue + bottomValue); break; } rect.Set (0, 0, borderLeftValue + paddingLeftValue + widthValue + paddingRightValue + borderRightValue - 1, borderTopValue + paddingTopValue + heightValue + paddingBottomValue + borderBottomValue - 1 ); rect.MoveTo ( parentBorderLeft + leftValue + marginLeftValue, parentBorderTop + topValue + marginTopValue ); if (position == TU_POSITION_FIXED) { rect.Shift(containingBlock.left, containingBlock.top); } Move(&rect); if (generateChildContext) { childContext = childContextFactory->newPositioned ( &rect, heightIsAuto, TU_DIR_LTR, borderLeftValue, borderTopValue, borderRightValue, borderBottomValue, paddingLeftValue, paddingTopValue, paddingRightValue ); } } return (childContext); }
void WebEditBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc) { WebChar c; long line; WebRect box; GetFrameRect(&box); box.Shift(x,y); // gc->StartBuffer(); // begin buffering graphics commands gc->Rectangle(&box, GetBgColor(gc), GetBgColor(gc), 1); // draw background DrawFrame(&box, gc); // save the current graphics context clip rectangle and set clipping to the // text display region of the widget GetTextRect(&box); box.Shift(x,y); WebRect clipSave; gc->GetClip(&clipSave); if (clipSave.Overlaps(&box)) { WebRect clip(box); clip.And(&clipSave); gc->SetClip(&clip); miXOffset = (mpHScroll)? mpHScroll->GetPosition() : 0; miYOffset = (mpVScroll)? mpVScroll->GetPosition() : 0; // render our text WebFont font = mFont.GetFont(); if (mpText && font) { // this loop draws up to the last line for (line=0; line<(miNumLines-1); line++) { c = mpText[GetLineOffset(line+1)]; mpText[GetLineOffset(line+1)] = 0; DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line * WEB_FONT_HEIGHT(font)), mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font); mpText[GetLineOffset(line+1)] = c; } // now draw the last line of text. DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)), mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font); // if we have the focus, draw the cursor if ((mFlags & DISPLAY_FLAG_FOCUS) && !(mFlags & DISPLAY_FLAG_DISABLED)) { // now render the selected portion in reverse video (if we have one) if (mEditFlags & EDIT_FLAG_HAS_SELECTION) { long begin = EBSMIN(miCursorPos, miSelectBegin); long end = EBSMAX(miCursorPos, miSelectBegin); long beginLine = FindLine(begin), endLine = FindLine(end); DISPLAY_INT textLeft; long currentBegin, currentEnd; for (line=beginLine; line<=endLine; line++) { currentBegin = EBSMAX(begin, GetLineOffset(line)); if (line == endLine) { currentEnd = end; } else { currentEnd = EBSMIN(end, GetLineOffset(line+1)); } textLeft = gc->TextWidthLen(mpText + GetLineOffset(line), font, EBSMAX(0, begin - GetLineOffset(line))); c = mpText[currentEnd]; mpText[currentEnd] = 0; DrawText(gc, box.left - miXOffset + textLeft, box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)), mpText + currentBegin, GetBgColor(gc), GetSelectColor(gc), 1, font); mpText[currentEnd] = c; } } DISPLAY_INT cursorX = box.left - miXOffset + gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) ; box.Set(cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*miCurrentLine, cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*(miCurrentLine+1)); gc->Rectangle(&box, GetSelectColor(gc), GetSelectColor(gc), 1); } } gc->SetClip(&clipSave); // restore the clip rectangle } // if clip overlaps /* if (mpVScroll && mpHScroll) { GetCornerRect(&box); box.Shift(x,y); gc->Rectangle(&box, LIGHTGRAY, LIGHTGRAY, 1); }*/ // gc->EndBuffer(); // send all buffered commands to the display }
void DisplayManager::Draw(DISPLAY_INT x, DISPLAY_INT y, WebRect *pViewport, WebGraphics *pGC) { if (mNoRefresh) { DisplayManager* parentDisplayManager = GetManager(); if (parentDisplayManager) { // This handles the case where a DisplayManager that is NOT the root // DisplayManager has a positive refresh lock, prohibiting its being // drawn, but the parent DisplayManager does not (otherwise we would // not even be in our Draw method); in this case: // // IF this element is within the collective invalid region being // painted, THEN we want to re-invalidate the invalid part of (this), // which will cause said region to re-paint when the refresh lock // is removed from this element and this->Refresh is eventually called. WebRect clipRect; pGC->GetClip(&clipRect); WebRect screenRect(mRect); screenRect.MoveTo(x,y); if (clipRect.Overlaps(&screenRect)) { SetManagerFlag(MANAGER_FLAG_TRIED_TO_DRAW); //screenRect.And(&clipRect); //screenRect.Shift(-pViewport->left, -pViewport->top); //parentDisplayManager->InvalidateViewportRegion(&screenRect); } } return; } FormatResult result; switch (GetScrollMode()) { case SCROLL_MODE_NONE: if (mpVScroll || mpHScroll) { DetachVScroll(); DetachHScroll(); UpdateViewport(); } break; case SCROLL_MODE_HSCROLL: if (mpVScroll || !mpHScroll) { DetachVScroll(); AttachHScroll(); UpdateViewport(); } break; case SCROLL_MODE_VSCROLL: if (!mpVScroll || mpHScroll) { AttachVScroll(); DetachHScroll(); UpdateViewport(); } break; case SCROLL_MODE_BOTH: if (!mpVScroll || !mpHScroll) { AttachVScroll(); AttachHScroll(); UpdateViewport(); } break; case SCROLL_MODE_AUTO: break; } if (mRoot.Get()) { int i = 0; do { result = mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0)); if (GetScrollMode() == SCROLL_MODE_AUTO) { if (result == DISPLAY_FORMAT_NEEDS_VSCROLL) { // create a vscroll bar if (mpVScroll) { // what the... we already have a vscroll bar! break; } AttachVScroll(); // check for creation failure - may indicate low memory condition if (!mpVScroll) { // can't go on... break; } UpdateViewport(); } else if (result == DISPLAY_FORMAT_NEEDS_HSCROLL) { // create a hscroll bar if (mpHScroll) { // what the... we already have a hscroll bar! break; } AttachHScroll(); // check for creation failure - may indicate low memory condition if (!mpHScroll) { // can't go on... break; } UpdateViewport(); } } else { break; } // put a hard upper bound on the number of times we try to re-format // (4, since this means we've covered all combinations of horizontal // and vertical scroll bars on the window) i++; } while (result != DISPLAY_FORMAT_SUCCESS && i < 5); if (GetScrollMode() == SCROLL_MODE_AUTO) { WebRect rootBounds; GetRootBounds(&rootBounds); if (rootBounds.Height() <= mViewRect.Height() && mpVScroll) { DetachVScroll(); UpdateViewport(); mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0)); GetRootBounds(&rootBounds); } if (rootBounds.Width() <= mViewRect.Width() && mpHScroll) { DetachHScroll(); UpdateViewport(); mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0)); GetRootBounds(&rootBounds); } if (rootBounds.Height() <= mViewRect.Height() && mpVScroll) { DetachVScroll(); UpdateViewport(); mRoot.Get()->FormatForViewport(&mViewRect, (mpHScroll != 0), (mpVScroll != 0)); GetRootBounds(&rootBounds); } } mViewportChanged = WEBC_FALSE; CorrectViewportPosition(); if (mpFocus && (mpVScroll!=0) && (mpHScroll!=0)) { WebRect focusRect; WebRect elemRect; WEBC_BOOL ensureFocusVisible = mpFocus->GetFocusRect (&focusRect); if (ensureFocusVisible) { GetElementRect(&elemRect, mpFocus); focusRect.Shift(elemRect.left, elemRect.top); // this will adjust the scroll bars so that the given rect is in view EnsureRectVisible(&focusRect); } } } DisplayElement::Draw(x, y, pViewport, pGC); }
void WebDropBox::Drop(void) { WEBC_ASSERT(GetManager()); if (mState == DROPBOX_STATE_DROPPED) { return; } int spaceUp, spaceDown; CalculateAvailableSpace(&spaceUp, &spaceDown); int neededSpace = mListbox.GetTotalTextHeight() + mListbox.GetMargin() + mListbox.GetPadding() * 2 + mListbox.GetBorder() * 2; WebRect rect; if (spaceDown >= neededSpace || spaceDown > spaceUp) { DISPLAY_INT space = EBSMIN(spaceDown, neededSpace); rect.top = Height() - DROPBOX_MARGIN; rect.left = DROPBOX_MARGIN; rect.right = Width() - DROPBOX_MARGIN - 1; rect.bottom = rect.top + space - 1; } else { DISPLAY_INT space = EBSMIN(spaceUp, neededSpace); rect.top = -space; rect.left = DROPBOX_MARGIN; rect.right = Width() - DROPBOX_MARGIN - 1; rect.bottom = DROPBOX_MARGIN - 1; } SetFlag(DISPLAY_FLAG_DIRTY); Invalidate(); mState = DROPBOX_STATE_DROPPED; if (mpParent) { DISPLAY_INT left,top; mpParent->GetDisplayPosition(this, &left, &top); rect.Shift(left,top); } mListbox.Move(&rect); DisplayManager *m = GetManager(); WebGraphics *gc = m? m->GetGraphics() : 0; if (gc) { mListbox.SetupScrollBars(gc); } // we need to make sure the list box appears on top of everything. DisplayElement *parent = this; while (parent->mpParent) { parent = parent->mpParent; } parent->InsertLast(&mListbox); mListbox.Invalidate(); }
void WebDropBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc) { WEBC_BOOL focused = (mFlags & DISPLAY_FLAG_FOCUS) || (mState == DROPBOX_STATE_DROPPED); mListbox.CalculateTextMetrics(gc); WebRect oldClip; gc->GetClip(&oldClip); WebRect clip; clip.top = y; clip.left = x; clip.bottom = y + Height() - 1; clip.right = x + Width() - 1; clip.And(&oldClip); gc->SetClip(&clip); WebRect rect; rect.top = y; rect.left = x; rect.bottom = y + Height() - 1; rect.right = x + Width() - 1; // gc->StartBuffer(); WebColor hilite, lolite, blue, white, black; HTMLColor col = HTML_RGBAToColor(0,0,0,0); black = hilite = gc->RGBToColor(col); col = HTML_RGBAToColor(0xff,0xff,0xff,0); white = lolite = gc->RGBToColor(col); col = HTML_RGBAToColor(0,0,0xff,0); blue = gc->RGBToColor(col); if (focused) { gc->Rectangle(&rect, black, black, WEBC_FALSE); } GetFrameRect(&rect); rect.Shift(x,y); DrawFrame(&rect, gc); GetContentRect(&rect); rect.Shift(x,y); if (focused) { gc->Rectangle(&rect, GetSelectColor(gc), GetSelectColor(gc), WEBC_TRUE); } else { gc->Rectangle(&rect, GetBgColor(gc), GetBgColor(gc), WEBC_TRUE); } if (mpText && mFont.GetFont()) { DISPLAY_INT offset = (rect.Height() - gc->TextHeight(mpText, mFont.GetFont())) / 2; clip.Set(&rect); clip.And(&oldClip); gc->SetClip(&clip); gc->Text(rect.left + DROPBOX_PADDING, rect.top + DROPBOX_PADDING + offset, mpText, (focused) ? GetBgColor(gc) : GetTextColor(gc), 0, WEBC_FALSE, mFont.GetFont()); } // gc->EndBuffer(); gc->SetClip(&oldClip); }