示例#1
0
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);
	}
 }
示例#2
0
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

}
示例#3
0
void DisplayManager::UpdateScrollBuffer (void)
{
	if ((GetManagerFlags() & MANAGER_FLAG_DIRTY) &&
	    mRoot.Get() &&
		mScrollBuffer)
	{
		WebRect* dirty;

		ClearManagerFlag(MANAGER_FLAG_BUFFER_DIRTY);

		// move the dirty rectangle list onto the stack so it can't be corrupted
		vector dirtyListCopy = mDirtyList;

		mDirtyList.first = 0;
		mDirtyList.last = 0;

		vector_iterator vi;

		DISPLAY_INT viewWidth  = mViewRect.Width();
		DISPLAY_INT viewHeight = mViewRect.Height();

		PresetWebRect viewCorner(&mViewRect);
		viewCorner.MoveTo(0,0);

		PresetWebRect bufferView(&mViewRect);
		bufferView.MoveTo(mViewRect.left % viewWidth, mViewRect.top % viewHeight);

		DISPLAY_INT bufferLeft = mViewRect.left - (mViewRect.left % viewWidth);
		DISPLAY_INT bufferTop  = mViewRect.top  - (mViewRect.top  % viewHeight);

		dirty = (WebRect*) vector_get_first(&dirtyListCopy, &vi);
		while (dirty)
		{
			if (mViewRect.Overlaps(dirty))
			{
				WebRect bufferDirty;
				bufferDirty.left = dirty->left - bufferLeft;
				bufferDirty.top  = dirty->top  - bufferTop;
				bufferDirty.SizeTo(dirty->Width(), dirty->Height());
				bufferDirty.And(&bufferView);

				mScrollBuffer->SetClip(&bufferDirty);

				DISPLAY_INT x = mRoot.Get()->mRect.left - bufferLeft;
				DISPLAY_INT y = mRoot.Get()->mRect.top  - bufferTop;

				mRoot.Get()->Draw (x, y, &bufferView, mScrollBuffer);

				PresetWebRect defaultClip(0, 0, viewWidth * 2 - 1, viewHeight * 2 - 1);
				mScrollBuffer->SetClip(&defaultClip);

				// copy bufferDirty 3 times, split if necessary
				PresetWebRect northwest (0, 0, viewWidth - 1, viewHeight - 1);
				PresetWebRect northeast (viewWidth, 0, viewWidth * 2 - 1, viewHeight - 1);
				PresetWebRect southeast (viewWidth, viewHeight, viewWidth * 2 - 1, viewHeight * 2 - 1);
				PresetWebRect southwest (0, viewHeight, viewWidth - 1, viewHeight * 2 - 1);

				if (bufferDirty.Overlaps(&northwest))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&northwest);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftOver(mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&northeast))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&northeast);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&southeast))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&southeast);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(-mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}

				if (bufferDirty.Overlaps(&southwest))
				{
					PresetWebRect copyFrom (&bufferDirty);
					copyFrom.And(&southwest);

					PresetWebRect copyTo (&copyFrom);

					copyTo.ShiftDown(-mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftOver(mViewRect.Width());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);

					copyTo.ShiftDown(mViewRect.Height());
					mScrollBuffer->CopyBufferRegion(&copyTo, mScrollBuffer, copyFrom.left, copyFrom.top);
				}
			}

			dirty = (WebRect*) vector_get_next(&vi);
		}

		// this ensures the dirty list is just the same as when we entered
		vector_delete(&mDirtyList);

		if (!this->GetManager())
		{
			// if we're the root manager, we'll need this list in a sec.
			mDirtyList = dirtyListCopy;
		}
		else
		{
			ClearManagerFlag(MANAGER_FLAG_DIRTY);
			vector_delete(&dirtyListCopy);
		}
	}
}
示例#4
0
void DisplayManager::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	DISPLAY_INT scrollLeft = (mpHScroll)? mpHScroll->GetPosition() : mViewRect.left;
	DISPLAY_INT scrollTop  = (mpVScroll)? mpVScroll->GetPosition() : mViewRect.top;

	mViewRect.MoveTo(scrollLeft, scrollTop);

	WebRect padding;
	GetPaddingWidth(&padding);

	// find our viewport rect in screen coordinates
	WebRect screenRect(mRect);
	screenRect.MoveTo(x,y);

	WebRect screenView(screenRect);
	screenView.Shift(padding.left, padding.top);
	screenView.SizeTo(mViewRect.Width(), mViewRect.Height());

	WebRect saveClip;
	gc->GetClip(&saveClip);

	WebRect screenDirty(screenView);
	if (saveClip.Overlaps(&screenDirty))
	{
		screenDirty.And(&saveClip);

	  #ifdef WEBC_BUFFER_SCROLLING

		if ((GetManagerFlags() & MANAGER_FLAG_BUFFER_SCROLL) &&
		    mScrollBuffer)
		{
			if (GetManagerFlags() & MANAGER_FLAG_BUFFER_DIRTY)
			{
				UpdateScrollBuffer();
			}

			// instead of invoking the Draw method of mRoot, just copy the contents of the
			//  buffer at this location.
			gc->CopyBufferRegion (
					&screenDirty,
					mScrollBuffer,
					screenDirty.left - screenView.left + (mViewRect.left % mViewRect.Width()),
					screenDirty.top  - screenView.top  + (mViewRect.top  % mViewRect.Height()));
		}
		else
		{

	  #endif

			gc->SetClip(&screenDirty);

			if (mRoot.Get())
			{
				mRoot.Get()->Draw(screenView.left + mRoot.Get()->mRect.left - scrollLeft,
				                  screenView.top  + mRoot.Get()->mRect.top  - scrollTop,
								  &screenView, gc);
			}

	  #ifdef WEBC_BUFFER_SCROLLING
		}
	  #endif

		gc->SetClip(&saveClip);
	}

	// draw the little gray rectangle
	if (mpVScroll && mpHScroll && webc_GetDefaultBoolean(WEBC_DEFAULT_DRAW_SCROLL_CORNER))
	{
		WebRect box;
		WebColor c = gc->RGBToColor(webc_GetDefaultColor(WEBC_DEFAULT_SCROLL_CORNER_COLOR));
		box.SetSizeAndPosition(screenView.right + 1, screenView.bottom + 1, mpVScroll->Width(), mpHScroll->Height());
		gc->Rectangle(&box, c, c, 1);
	}
}
示例#5
0
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);
}