Ejemplo n.º 1
0
void CurveWnd::onSize(HWND hwnd, UINT state, int cx, int cy){
	int nMax, nPos;

	nPos = getScrollPos(SB_HORZ);
	nMax = canvas.cx - 1;

	if(cx > canvas.cx - nPos){
		if(cx >= canvas.cx)
			nPos = 0;
		else
			nPos = canvas.cx - cx;
	}

	setScrollInfo(SB_HORZ, 0, nMax, cx, nPos);

	nPos = getScrollPos(SB_VERT);
	nMax = canvas.cy - 1;

	if(cy > canvas.cy - nPos){
		if(cy >= canvas.cy)
			nPos = 0;
		else
			nPos = canvas.cy - cy;
	}

	setScrollInfo(SB_VERT, 0, nMax, cy, nPos);
}
Ejemplo n.º 2
0
void areaMouseEvent(HWND hwnd, void *data, DWORD button, BOOL up, uintptr_t heldButtons, LPARAM lParam)
{
	int xpos, ypos;

	// mouse coordinates are relative to control; make them relative to Area
	getScrollPos(hwnd, &xpos, &ypos);
	xpos += GET_X_LPARAM(lParam);
	ypos += GET_Y_LPARAM(lParam);
	finishAreaMouseEvent(data, button, up, heldButtons, xpos, ypos);
}
Ejemplo n.º 3
0
void LLTabContainer::updateMaxScrollPos()
{
	BOOL no_scroll = TRUE;
	if (mIsVertical)
	{
		S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount();
		S32 available_height = getRect().getHeight() - getTopBorderHeight();
		if( tab_total_height > available_height )
		{
			S32 available_height_with_arrows = getRect().getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD);
			S32 additional_needed = tab_total_height - available_height_with_arrows;
			setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
			no_scroll = FALSE;
		}
	}
	else
	{
		S32 tab_space = 0;
		S32 available_space = 0;
		tab_space = mTotalTabWidth;
		available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD);

		if( tab_space > available_space )
		{
			S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE  + TABCNTR_ARROW_BTN_SIZE + 1);
			// subtract off reserved portion on left
			available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH;

			S32 running_tab_width = 0;
			setMaxScrollPos(getTabCount());
			for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it)
			{
				running_tab_width += (*tab_it)->mButton->getRect().getWidth();
				if (running_tab_width > available_width_with_arrows)
				{
					break;
				}
				setMaxScrollPos(getMaxScrollPos()-1);
			}
			// in case last tab doesn't actually fit on screen, make it the last scrolling position
			setMaxScrollPos(llmin(getMaxScrollPos(), getTabCount() - 1));
			no_scroll = FALSE;
		}
	}
	if (no_scroll)
	{
		setMaxScrollPos(0);
		setScrollPos(0);
	}
	if (getScrollPos() > getMaxScrollPos())
	{
		setScrollPos(getMaxScrollPos()); // maybe just enforce this via limits in setScrollPos instead?
	}
}
Ejemplo n.º 4
0
void areaOpenTextField(HWND area, HWND textfield, int x, int y, int width, int height)
{
	int sx, sy;
	int baseX, baseY;
	LONG unused;

	getScrollPos(area, &sx, &sy);
	x += sx;
	y += sy;
	calculateBaseUnits(textfield, &baseX, &baseY, &unused);
	width = MulDiv(width, baseX, 4);
	height = MulDiv(height, baseY, 8);
	if (MoveWindow(textfield, x, y, width, height, TRUE) == 0)
		xpanic("error moving Area TextField in Area.OpenTextFieldAt()", GetLastError());
	ShowWindow(textfield, SW_SHOW);
	if (SetFocus(textfield) == NULL)
		xpanic("error giving Area TextField focus", GetLastError());
}
Ejemplo n.º 5
0
// virtual
void LLTabContainer::draw()
{
	S32 target_pixel_scroll = 0;
	S32 cur_scroll_pos = getScrollPos();
	if (cur_scroll_pos > 0)
	{
		if (!mIsVertical)
		{
			S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE  + TABCNTR_ARROW_BTN_SIZE + 1);
			for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
			{
				if (cur_scroll_pos == 0)
				{
					break;
				}
				target_pixel_scroll += (*iter)->mButton->getRect().getWidth();
				cur_scroll_pos--;
			}

			// Show part of the tab to the left of what is fully visible
			target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH;
			// clamp so that rightmost tab never leaves right side of screen
			target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll);
		}
		else
		{
			S32 available_height_with_arrows = getRect().getHeight() - getTopBorderHeight() - (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
			for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
			{
				if (cur_scroll_pos==0)
				{
					break;
				}
				target_pixel_scroll += (*iter)->mButton->getRect().getHeight();
				cur_scroll_pos--;
			}
			S32 total_tab_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount() + TABCNTRV_PAD;
			// clamp so that the bottom tab never leaves bottom of panel
			target_pixel_scroll = llmin(total_tab_height - available_height_with_arrows, target_pixel_scroll);
		}
	}

	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)));

	BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0);
	if (!mIsVertical)
	{
		mJumpPrevArrowBtn->setVisible( has_scroll_arrows );
		mJumpNextArrowBtn->setVisible( has_scroll_arrows );
	}
	mPrevArrowBtn->setVisible( has_scroll_arrows );
	mNextArrowBtn->setVisible( has_scroll_arrows );

	S32 left = 0, top = 0;
	if (mIsVertical)
	{
		top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0);
		top += getScrollPosPixels();
	}
	else
	{
		// Set the leftmost position of the tab buttons.
		left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD);
		left -= getScrollPosPixels();
	}
	
	// Hide all the buttons
	for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
	{
		LLTabTuple* tuple = *iter;
		tuple->mButton->setVisible( FALSE );
	}

	LLPanel::draw();

	// if tabs are hidden, don't draw them and leave them in the invisible state
	if (!getTabsHidden())
	{
		// Show all the buttons
		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
		{
			LLTabTuple* tuple = *iter;
			tuple->mButton->setVisible( TRUE );
		}

		// Draw some of the buttons...
		LLRect clip_rect = getLocalRect();
		if (has_scroll_arrows)
		{
			// ...but clip them.
			if (mIsVertical)
			{
				clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
				clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
			}
			else
			{
				clip_rect.mLeft = mPrevArrowBtn->getRect().mRight;
				clip_rect.mRight = mNextArrowBtn->getRect().mLeft;
			}
		}
		LLLocalClipRect clip(clip_rect);

		S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos();
		S32 idx = 0;
		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
		{
			LLTabTuple* tuple = *iter;

			tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0,
									   top ? top - tuple->mButton->getRect().mTop : 0 );
			if (top) top -= BTN_HEIGHT + TABCNTRV_PAD;
			if (left) left += tuple->mButton->getRect().getWidth();

			if (!mIsVertical)
			{
				if( idx < getScrollPos() )
				{
					if( tuple->mButton->getFlashing() )
					{
						mPrevArrowBtn->setFlashing( TRUE );
					}
				}
				else if( max_scroll_visible < idx )
				{
					if( tuple->mButton->getFlashing() )
					{
						mNextArrowBtn->setFlashing( TRUE );
					}
				}
			}
			LLUI::pushMatrix();
			{
				LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f);
				tuple->mButton->draw();
			}
			LLUI::popMatrix();

			idx++;
		}


		if( mIsVertical && has_scroll_arrows )
		{
			// Redraw the arrows so that they appears on top.
			gGL.pushMatrix();
			gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
			mPrevArrowBtn->draw();
			gGL.popMatrix();

			gGL.pushMatrix();
			gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
			mNextArrowBtn->draw();
			gGL.popMatrix();
		}
	}

	mPrevArrowBtn->setFlashing(FALSE);
	mNextArrowBtn->setFlashing(FALSE);
}
Ejemplo n.º 6
0
BOOL LLTabContainer::setTab(S32 which)
{
	if (which == -1)
	{
		if (mNextTabIdx == -1)
		{
			return FALSE;
		}
		which = mNextTabIdx;
		mNextTabIdx = -1;
	}

	LLTabTuple* selected_tuple = getTab(which);
	if (!selected_tuple)
	{
		return FALSE;
	}

	BOOL is_visible = FALSE;
	if (selected_tuple->mButton->getEnabled())
	{
		setCurrentPanelIndex(which);

		S32 i = 0;
		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
		{
			LLTabTuple* tuple = *iter;
			BOOL is_selected = ( tuple == selected_tuple );
			tuple->mTabPanel->setVisible( is_selected );
// 			tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
			tuple->mButton->setToggleState( is_selected );
			// RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
			tuple->mButton->setTabStop( is_selected );
			
			if( is_selected && (mIsVertical || (getMaxScrollPos() > 0)))
			{
				// Make sure selected tab is within scroll region
				if (mIsVertical)
				{
					S32 num_visible = getTabCount() - getMaxScrollPos();
					if( i >= getScrollPos() && i <= getScrollPos() + num_visible)
					{
						setCurrentPanelIndex(which);
						is_visible = TRUE;
					}
					else
					{
						is_visible = FALSE;
					}
				}
				else
				{
					if( i < getScrollPos() )
					{
						setScrollPos(i);
					}
					else
					{
						S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE  + TABCNTR_ARROW_BTN_SIZE + 1);
						S32 running_tab_width = tuple->mButton->getRect().getWidth();
						S32 j = i - 1;
						S32 min_scroll_pos = i;
						if (running_tab_width < available_width_with_arrows)
						{
							while (j >= 0)
							{
								LLTabTuple* other_tuple = getTab(j);
								running_tab_width += other_tuple->mButton->getRect().getWidth();
								if (running_tab_width > available_width_with_arrows)
								{
									break;
								}
								j--;
							}
							min_scroll_pos = j + 1;
						}
						setScrollPos(llclamp(getScrollPos(), min_scroll_pos, i));
						setScrollPos(llmin(getScrollPos(), getMaxScrollPos()));
					}
					is_visible = TRUE;
				}
			}
			i++;
		}
		if( selected_tuple->mOnChangeCallback )
		{
			selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false );
		}
	}
	if (mIsVertical && getCurrentPanelIndex() >= 0)
	{
		LLTabTuple* tuple = getTab(getCurrentPanelIndex());
		tuple->mTabPanel->setVisible( TRUE );
		tuple->mButton->setToggleState( TRUE );
	}
	return is_visible;
}
Ejemplo n.º 7
0
void CurveWnd::onPaint(HWND hwnd){
	PAINTSTRUCT ps;
	int xpos, ypos;
	int save;
	HDC hdc;
	xpos = getScrollPos(SB_HORZ);
	ypos = getScrollPos(SB_VERT);

	hdc = BeginPaint(hwnd, &ps);
	save = SaveDC(hdc);
	if(ypx == NULL){
		EndPaint(hwnd, &ps);
		return;
	}
	SelectObject(hdc, gridPen);

	double gridmax, gridmin;
			double rem;
	if(cs->gridy > 0.0){

		rem = fabs(fmod(maxy, cs->gridy));
		if(fabs(rem - cs->gridy) < 1.0e-10)
			gridmax = maxy;
		else
			gridmax = maxy - rem;

		rem = fabs(fmod(miny, cs->gridy));
		if(rem < 1.0e-10 || fabs(rem - cs->gridy) < 1.0e-10)
			gridmin = miny;
		else
			gridmin = miny + (cs->gridy - rem);

		int maxypx = (int)(maxy * ysf);
		int gridypx;
		for(double y = gridmin; y <= gridmax; y += cs->gridy){
			gridypx = maxypx - (int)(y * ysf);
			MoveToEx(hdc, MARGIN - xpos, MARGIN + gridypx - ypos, NULL);
			LineTo(hdc, gwidth + MARGIN - xpos, MARGIN + gridypx - ypos);
		}
	}

	if(cs->gridx > 0.0){
		rem = fabs(fmod(cs->x2, cs->gridx));
		if(fabs(rem - cs->gridx) < 1.0e-10)
			gridmax = cs->x2;
		else
			gridmax = cs->x2 - rem;

		rem = fabs(fmod(cs->x2, cs->gridx));
		if(rem < 1.0e-10 || fabs(rem - cs->gridx) < 1.0e-10)
			gridmin = cs->x1;
		else
			gridmin = cs->x1 + (cs->gridx - rem);

		int gridxpx;

		for(double x = gridmin; x <= gridmax; x += cs->gridx){
			gridxpx = (int)((x - cs->x1) * xsf);
			MoveToEx(hdc, MARGIN + gridxpx - xpos, MARGIN - ypos, NULL);
			LineTo(hdc, MARGIN + gridxpx - xpos, MARGIN + gheight - ypos);
		}
	}
	SelectObject(hdc, GetStockObject(BLACK_PEN));
	MoveToEx(hdc, MARGIN - xpos, ypx[0] + MARGIN - ypos, NULL);
	for(int xpx = 1; xpx <= gwidth; xpx++)
		LineTo(hdc, xpx + MARGIN - xpos, ypx[xpx] + MARGIN - ypos);
	RestoreDC(hdc, save);
	EndPaint(hwnd, &ps);
}
Ejemplo n.º 8
0
static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	void *data;
	DWORD which;
	uintptr_t heldButtons = (uintptr_t) wParam;
	LRESULT lResult;

	data = getWindowData(hwnd, uMsg, wParam, lParam, &lResult);
	if (data == NULL)
		return lResult;
	switch (uMsg) {
	case WM_PAINT:
		paintArea(hwnd, data);
		return 0;
	case WM_ERASEBKGND:
		// don't draw a background; we'll do so when painting
		// this is to make things flicker-free; see http://msdn.microsoft.com/en-us/library/ms969905.aspx
		return 1;
	case WM_HSCROLL:
		scrollArea(hwnd, data, wParam, SB_HORZ);
		return 0;
	case WM_VSCROLL:
		scrollArea(hwnd, data, wParam, SB_VERT);
		return 0;
	case WM_SIZE:
		adjustAreaScrollbars(hwnd, data);
		return 0;
	case WM_ACTIVATE:
		// don't keep the double-click timer running if the user switched programs in between clicks
		areaResetClickCounter(data);
		return 0;
	case WM_MOUSEMOVE:
		areaMouseEvent(hwnd, data, 0, FALSE, heldButtons, lParam);
		return 0;
	case WM_LBUTTONDOWN:
		SetFocus(hwnd);
		areaMouseEvent(hwnd, data, 1, FALSE, heldButtons, lParam);
		return 0;
	case WM_LBUTTONUP:
		areaMouseEvent(hwnd, data, 1, TRUE, heldButtons, lParam);
		return 0;
	case WM_MBUTTONDOWN:
		SetFocus(hwnd);
		areaMouseEvent(hwnd, data, 2, FALSE, heldButtons, lParam);
		return 0;
	case WM_MBUTTONUP:
		areaMouseEvent(hwnd, data, 2, TRUE, heldButtons, lParam);
		return 0;
	case WM_RBUTTONDOWN:
		SetFocus(hwnd);
		areaMouseEvent(hwnd, data, 3, FALSE, heldButtons, lParam);
		return 0;
	case WM_RBUTTONUP:
		areaMouseEvent(hwnd, data, 3, TRUE, heldButtons, lParam);
		return 0;
	case WM_XBUTTONDOWN:
		SetFocus(hwnd);
		// values start at 1; we want them to start at 4
		which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
		heldButtons = (uintptr_t) GET_KEYSTATE_WPARAM(wParam);
		areaMouseEvent(hwnd, data, which, FALSE, heldButtons, lParam);
		return TRUE;		// XBUTTON messages are different!
	case WM_XBUTTONUP:
		which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
		heldButtons = (uintptr_t) GET_KEYSTATE_WPARAM(wParam);
		areaMouseEvent(hwnd, data, which, TRUE, heldButtons, lParam);
		return TRUE;
	case msgAreaKeyDown:
		return (LRESULT) areaKeyEvent(data, FALSE, wParam, lParam);
	case msgAreaKeyUp:
		return (LRESULT) areaKeyEvent(data, TRUE, wParam, lParam);
	case msgAreaSizeChanged:
		adjustAreaScrollbars(hwnd, data);
		repaintArea(hwnd, NULL);		// this calls for an update
		return 0;
	case msgAreaGetScroll:
		getScrollPos(hwnd, (int *) wParam, (int *) lParam);
		return 0;
	case msgAreaRepaint:
		repaintArea(hwnd, (RECT *) lParam);
		return 0;
	case msgAreaRepaintAll:
		repaintArea(hwnd, NULL);
		return 0;
	default:
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	}
	xmissedmsg("Area", "areaWndProc()", uMsg);
	return 0;			// unreached
}
Ejemplo n.º 9
0
static void paintArea(HWND hwnd, void *data)
{
	RECT xrect;
	PAINTSTRUCT ps;
	HDC hdc;
	HDC rdc;
	HBITMAP rbitmap, prevrbitmap;
	RECT rrect;
	BITMAPINFO bi;
	VOID *ppvBits;
	HBITMAP ibitmap;
	HDC idc;
	HBITMAP previbitmap;
	BLENDFUNCTION blendfunc;
	void *i;
	intptr_t dx, dy;
	int hscroll, vscroll;

	// FALSE here indicates don't send WM_ERASEBKGND
	if (GetUpdateRect(hwnd, &xrect, FALSE) == 0)
		return;		// no update rect; do nothing

	getScrollPos(hwnd, &hscroll, &vscroll);

	hdc = BeginPaint(hwnd, &ps);
	if (hdc == NULL)
		xpanic("error beginning Area repaint", GetLastError());

	// very big thanks to Ninjifox for suggesting this technique and helping me go through it

	// first let's create the destination image, which we fill with the windows background color
	// this is how we fake drawing the background; see also http://msdn.microsoft.com/en-us/library/ms969905.aspx
	rdc = CreateCompatibleDC(hdc);
	if (rdc == NULL)
		xpanic("error creating off-screen rendering DC", GetLastError());
	// the bitmap has to be compatible with the window
	// if we create a bitmap compatible with the DC we just created, it'll be monochrome
	// thanks to David Heffernan in http://stackoverflow.com/questions/23033636/winapi-gdi-fillrectcolor-btnface-fills-with-strange-grid-like-brush-on-window
	rbitmap = CreateCompatibleBitmap(hdc, xrect.right - xrect.left, xrect.bottom - xrect.top);
	if (rbitmap == NULL)
		xpanic("error creating off-screen rendering bitmap", GetLastError());
	prevrbitmap = (HBITMAP) SelectObject(rdc, rbitmap);
	if (prevrbitmap == NULL)
		xpanic("error connecting off-screen rendering bitmap to off-screen rendering DC", GetLastError());
	rrect.left = 0;
	rrect.right = xrect.right - xrect.left;
	rrect.top = 0;
	rrect.bottom = xrect.bottom - xrect.top;
	if (FillRect(rdc, &rrect, areaBackgroundBrush) == 0)
		xpanic("error filling off-screen rendering bitmap with the system background color", GetLastError());

	i = doPaint(&xrect, hscroll, vscroll, data, &dx, &dy);
	if (i == NULL)			// cliprect empty
		goto nobitmap;		// we need to blit the background no matter what

	// now we need to shove realbits into a bitmap
	// technically bitmaps don't know about alpha; they just ignore the alpha byte
	// AlphaBlend(), however, sees it - see http://msdn.microsoft.com/en-us/library/windows/desktop/dd183352%28v=vs.85%29.aspx
	ZeroMemory(&bi, sizeof (BITMAPINFO));
	bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = (LONG) dx;
	bi.bmiHeader.biHeight = -((LONG) dy);			// negative height to force top-down drawing
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 32;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = (DWORD) (dx * dy * 4);
	// this is all we need, but because this confused me at first, I will say the two pixels-per-meter fields are unused (see http://blogs.msdn.com/b/oldnewthing/archive/2013/05/15/10418646.aspx and page 581 of Charles Petzold's Programming Windows, Fifth Edition)
	// now for the trouble: CreateDIBSection() allocates the memory for us...
	ibitmap = CreateDIBSection(NULL,		// Ninjifox does this, so do some wine tests (http://source.winehq.org/source/dlls/gdi32/tests/bitmap.c#L725, thanks vpovirk in irc.freenode.net/#winehackers) and even Raymond Chen (http://blogs.msdn.com/b/oldnewthing/archive/2006/11/16/1086835.aspx), so.
		&bi, DIB_RGB_COLORS, &ppvBits, 0, 0);
	if (ibitmap == NULL)
		xpanic("error creating HBITMAP for image returned by AreaHandler.Paint()", GetLastError());

	// now we have to do TWO MORE things before we can finally do alpha blending
	// first, we need to load the bitmap memory, because Windows makes it for us
	// the pixels are arranged in RGBA order, but GDI requires BGRA
	// this turns out to be just ARGB in little endian; let's convert into this memory
	dotoARGB(i, (void *) ppvBits, FALSE);		// FALSE = not NRGBA

	// the second thing is... make a device context for the bitmap :|
	// Ninjifox just makes another compatible DC; we'll do the same
	idc = CreateCompatibleDC(hdc);
	if (idc == NULL)
		xpanic("error creating HDC for image returned by AreaHandler.Paint()", GetLastError());
	previbitmap = (HBITMAP) SelectObject(idc, ibitmap);
	if (previbitmap == NULL)
		xpanic("error connecting HBITMAP for image returned by AreaHandler.Paint() to its HDC", GetLastError());

	// AND FINALLY WE CAN DO THE ALPHA BLENDING!!!!!!111
	blendfunc.BlendOp = AC_SRC_OVER;
	blendfunc.BlendFlags = 0;
	blendfunc.SourceConstantAlpha = 255;		// only use per-pixel alphas
	blendfunc.AlphaFormat = AC_SRC_ALPHA;	// premultiplied
	if (AlphaBlend(rdc, 0, 0, (int) dx, (int) dy,		// destination
		idc, 0, 0, (int) dx, (int)dy,				// source
		blendfunc) == FALSE)
		xpanic("error alpha-blending image returned by AreaHandler.Paint() onto background", GetLastError());

	// clean up after idc/ibitmap here because of the goto nobitmap
	if (SelectObject(idc, previbitmap) != ibitmap)
		xpanic("error reverting HDC for image returned by AreaHandler.Paint() to original HBITMAP", GetLastError());
	if (DeleteObject(ibitmap) == 0)
		xpanic("error deleting HBITMAP for image returned by AreaHandler.Paint()", GetLastError());
	if (DeleteDC(idc) == 0)
		xpanic("error deleting HDC for image returned by AreaHandler.Paint()", GetLastError());

nobitmap:
	// and finally we can just blit that into the window
	if (BitBlt(hdc, xrect.left, xrect.top, xrect.right - xrect.left, xrect.bottom - xrect.top,
		rdc, 0, 0,			// from the rdc's origin
		SRCCOPY) == 0)
		xpanic("error blitting Area image to Area", GetLastError());

	// now to clean up
	if (SelectObject(rdc, prevrbitmap) != rbitmap)
		xpanic("error reverting HDC for off-screen rendering to original HBITMAP", GetLastError());
	if (DeleteObject(rbitmap) == 0)
		xpanic("error deleting HBITMAP for off-screen rendering", GetLastError());
	if (DeleteDC(rdc) == 0)
		xpanic("error deleting HDC for off-screen rendering", GetLastError());

	EndPaint(hwnd, &ps);
}
Ejemplo n.º 10
0
void MainWindow::setZoomLevel(int zoom)
{
    off_t sample = getCenterSample();
    spectrogram.setZoomLevel(zoom);
    scrollArea.verticalScrollBar()->setValue(getScrollPos(sample));
}
Ejemplo n.º 11
0
void MainWindow::setFFTSize(int size)
{
    off_t sample = getCenterSample();
    spectrogram.setFFTSize(size);
    scrollArea.verticalScrollBar()->setValue(getScrollPos(sample));
}