Example #1
0
void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
	#define gcw			((GCheckboxObject *)gw)
	coord_t				ep, ld, df;
	const GColorSet *	pcol;
	(void)				param;

	if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
	pcol = getCheckboxColors(gw);

	// Get the dimension of the check box (sans text)
	ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;

	// Get the position of the check box
	ep = gw->g.width-ld;

	// Draw the empty check box
	gdispGFillArea(gw->g.display, gw->g.x+ep-1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
	gdispGDrawBox(gw->g.display, gw->g.x+ep, gw->g.y, ld, ld, pcol->edge);

	// Draw the check
	df = ld < 4 ? 1 : 2;
	if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
		gdispGFillArea(gw->g.display, gw->g.x+ep+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);

	// Draw the text
	gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, ep-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyRight);
	#undef gcw
}
Example #2
0
void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
	#define gcw			((GRadioObject *)gw)
	coord_t				ld, df;
	const GColorSet *	pcol;
	(void)				param;

	if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
	pcol = getDrawColors(gw);

	ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;

	#if GDISP_NEED_CIRCLE
		df = (ld-1)/2;
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, ld, ld, gw->pstyle->background);
		gdispGDrawCircle(gw->g.display, gw->g.x+df, gw->g.y+df, df, pcol->edge);

		if (gw->g.flags & GRADIO_FLG_PRESSED)
			gdispGFillCircle(gw->g.display, gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->fill);
	#else
		gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
		gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, ld, ld, pcol->edge);

		df = ld < 4 ? 1 : 2;
		if (gw->g.flags & GRADIO_FLG_PRESSED)
			gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
	#endif

	gdispGFillStringBox(gw->g.display, gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
	#undef gcw
}
Example #3
0
void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param) {
	#define gsw			((GProgressbarObject *)gw)
	#define gi			((gdispImage *)param)
	const GColorSet *	pcol;
	coord_t				z, v;

	if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
		return;

	if ((gw->g.flags & GWIN_FLG_SYSENABLED))
		pcol = &gw->pstyle->pressed;
	else
		pcol = &gw->pstyle->disabled;

	if (gw->g.width < gw->g.height) {			// Vertical progressbar
		if (gsw->dpos != 0)							// The unfilled area
			gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress);	// Inactive area
		if (gsw->dpos != gw->g.height-1) {			// The filled area
			for(z=gw->g.height, v=gi->height; z > gsw->dpos;) {
				z -= v;
				if (z < gsw->dpos) {
					v -= gsw->dpos - z;
					z = gsw->dpos;
				}
				gdispGImageDraw(gw->g.display, gi, gw->g.x, gw->g.y+z, gw->g.width, v, 0, gi->height-v);
			}
		}
		gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);								// Edge
		gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge);	// Thumb

	// Horizontal progressbar
	} else {
		if (gsw->dpos != gw->g.width-1)				// The unfilled area
			gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress);	// Inactive area
		if (gsw->dpos != 0) {						// The filled area
			for(z=0, v=gi->width; z < gsw->dpos; z += v) {
				if (z+v > gsw->dpos)
					v -= z+v - gsw->dpos;
				gdispGImageDraw(gw->g.display, gi, gw->g.x+z, gw->g.y, v, gw->g.height, 0, 0);
			}
		}
		gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);								// Edge
		gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge);	// Thumb
	}
	gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);

	#undef gsw
}
Example #4
0
void gwinFrameDraw_Transparent(GWidgetObject *gw, void *param) {
	const GColorSet		*pcol;
	coord_t				pos;
	color_t				contrast;
	color_t				btn;
	(void)param;

	if (gw->g.vmt != (gwinVMT *)&frameVMT)
		return;

	pcol = 	(gw->g.flags & GWIN_FLG_SYSENABLED) ? &gw->pstyle->enabled : &gw->pstyle->disabled;
	contrast = gdispContrastColor(pcol->edge);
	btn = gdispBlendColor(pcol->edge, contrast, 128);

	// Render the frame
	gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, FRM_BORDER_T, gw->text, gw->g.font, contrast, pcol->edge, justifyCenter);
	gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+FRM_BORDER_T, FRM_BORDER_L, gw->g.height-(FRM_BORDER_T+FRM_BORDER_B), pcol->edge);
	gdispGFillArea(gw->g.display, gw->g.x+gw->g.width-FRM_BORDER_R, gw->g.y+FRM_BORDER_T, FRM_BORDER_R, gw->g.height-(FRM_BORDER_T+FRM_BORDER_B), pcol->edge);
	gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gw->g.height-FRM_BORDER_B, gw->g.width, FRM_BORDER_B, pcol->edge);

	// Add the buttons
	pos = gw->g.x+gw->g.width - (FRM_BORDER_R+FRM_BUTTON_X);

	if ((gw->g.flags & GWIN_FRAME_CLOSE_BTN)) {
		if ((gw->g.flags & GWIN_FRAME_CLOSE_PRESSED))
			gdispFillArea(pos, gw->g.y+FRM_BUTTON_T, FRM_BUTTON_X, FRM_BUTTON_Y, btn);
		gdispDrawLine(pos+FRM_BUTTON_I, gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I), pos+(FRM_BUTTON_X-FRM_BUTTON_I-1), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_Y-FRM_BUTTON_I-1), contrast);
		gdispDrawLine(pos+(FRM_BUTTON_X-FRM_BUTTON_I-1), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I), pos+FRM_BUTTON_I, gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_Y-FRM_BUTTON_I-1), contrast);
		pos -= FRM_BUTTON_X;
	}

	if ((gw->g.flags & GWIN_FRAME_MINMAX_BTN)) {
		if ((gw->g.flags & GWIN_FRAME_MAX_PRESSED))
			gdispFillArea(pos, gw->g.y+FRM_BUTTON_T, FRM_BUTTON_X, FRM_BUTTON_Y, btn);
		// the symbol
		gdispDrawBox(pos+FRM_BUTTON_I, gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I), FRM_BUTTON_X-2*FRM_BUTTON_I, FRM_BUTTON_Y-2*FRM_BUTTON_I, contrast);
		gdispDrawLine(pos+(FRM_BUTTON_I+1), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I+1), pos+(FRM_BUTTON_X-FRM_BUTTON_I-2), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I+1), contrast);
		gdispDrawLine(pos+(FRM_BUTTON_I+1), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I+2), pos+(FRM_BUTTON_X-FRM_BUTTON_I-2), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_I+2), contrast);
		pos -= FRM_BUTTON_X;
		if ((gw->g.flags & GWIN_FRAME_MIN_PRESSED))
			gdispFillArea(pos, gw->g.y+FRM_BUTTON_T, FRM_BUTTON_X, FRM_BUTTON_Y, btn);
		gdispDrawLine(pos+FRM_BUTTON_I, gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_Y-FRM_BUTTON_I-1), pos+(FRM_BUTTON_X-FRM_BUTTON_I-1), gw->g.y+(FRM_BUTTON_T+FRM_BUTTON_Y-FRM_BUTTON_I-1), contrast);
		pos -= FRM_BUTTON_X;
	}

	// Don't touch the client area
}
Example #5
0
void gwinTabsetDraw_Std(GWidgetObject *gw, void *param) {
	coord_t		y;
	(void)		param;

	if (gw->g.vmt != (gwinVMT *)&tabsetVMT)
		return;

	// Draw the frame
	y = drawtabs(gw);
	drawborder(gw, y);

	// Draw the client area
	if ((gw->g.flags & GWIN_CONTAINER_BORDER))
		gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+y, gw->g.width-2, gw->g.height-y-1, gw->pstyle->background);
	else
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+y, gw->g.width, gw->g.height-y, gw->pstyle->background);
}
Example #6
0
	static void ntarea(GWidgetObject *gw, coord_t y, coord_t x, coord_t w) {
		const GColorSet *	pcol;

		pcol = (gw->g.flags & GWIN_FLG_SYSENABLED) ? &gw->pstyle->pressed : &gw->pstyle->disabled;

		gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, w, GWIN_TABSET_TABHEIGHT-1, gw->g.bgcolor);
		gdispGDrawLine(gw->g.display, gw->g.x+x, gw->g.y+y+GWIN_TABSET_TABHEIGHT-1, gw->g.x+x+w-1, gw->g.y+y+GWIN_TABSET_TABHEIGHT-1, pcol->edge);
	}
Example #7
0
	static void HistoryuRedraw(GWindowObject *gh) {
		#define gcw		((GConsoleObject *)gh)

		// No redrawing if there is no history
		if (!gcw->buffer)
			return;

		// We are printing the buffer - don't store it again
		gh->flags |= GCONSOLE_FLG_NOSTORE;

		#if !GWIN_CONSOLE_USE_CLEAR_LINES
			// Clear the screen
			gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
		#endif

		// Reset the cursor
		gcw->cx = 0;
		gcw->cy = 0;

		// Reset the current attributes
		#if GWIN_CONSOLE_ESCSEQ
			gcw->currattr = gcw->startattr;
		#endif

		// Print the buffer
		gwinPutCharArray(gh, gcw->buffer, gcw->bufpos);

		#if GWIN_CONSOLE_USE_CLEAR_LINES
			// Clear the remaining space
			{
				coord_t		y;

				y = gcw->cy;
				if (gcw->cx)
					y += gdispGetFontMetric(gh->font, fontHeight);
				if (y < gh->height)
					gdispGFillArea(gh->display, gh->x, gh->y+y, gh->width, gh->height-y, gh->bgcolor);
			}
		#endif

		// Turn back on storing of buffer contents
		gh->flags &= ~GCONSOLE_FLG_NOSTORE;

		#undef gcw
	}
Example #8
0
void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param) {
	#define gcw			((GCheckboxObject *)gw)
	coord_t				ld, df;
	const GColorSet *	pcol;
	(void)				param;

	if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
	pcol = getDrawColors(gw);

	ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
	gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
	gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, ld, ld, pcol->edge);

	df = ld < 4 ? 1 : 2;
	if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
		gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);

	gdispGFillStringBox(gw->g.display, gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
	#undef gcw
}
Example #9
0
static void gwinFrameDraw_Std(GWidgetObject *gw, void *param) {
	const GColorSet		*pcol;
	(void)param;

	if (gw->g.vmt != (gwinVMT *)&frameVMT)
		return;

	pcol = _getDrawColors(gw);

	// Render the actual frame (with border, if any)
	if (gw->g.flags & GWIN_FRAME_BORDER) {
		gdispGFillArea(gw->g.display, gw->g.x + BORDER_X, gw->g.y + BORDER_Y, gw->g.width - 2*BORDER_X, gw->g.height - BORDER_Y - BORDER_X, gw->pstyle->background);
		gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, BORDER_Y, gw->text, gw->g.font, gdispContrastColor(pcol->edge), pcol->edge, justifyCenter);
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+BORDER_Y, BORDER_X, gw->g.height-(BORDER_Y+BORDER_X), pcol->edge);
		gdispGFillArea(gw->g.display, gw->g.x+gw->g.width-BORDER_X, gw->g.y+BORDER_Y, BORDER_X, gw->g.height-(BORDER_Y+BORDER_X), pcol->edge);
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gw->g.height-BORDER_X, gw->g.width, BORDER_X, pcol->edge);
	} else {
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
	}
}
Example #10
0
	void _gwinUpdate(GHandle gh) {
		if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
			if (gh->vmt->Redraw) {
				getLock(gh);
				gh->vmt->Redraw(gh);
				exitLock(gh);
			} else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
				getLock(gh);
				gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
				exitLock(gh);
				if (gh->vmt->AfterClear)
					gh->vmt->AfterClear(gh);
			}
		} else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
			getLock(gh);
			gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
			exitLock(gh);
		}
		gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW);
	}
Example #11
0
	void gwinButtonDraw_Ellipse(GWidgetObject *gw, void *param) {
		const GColorSet *	pcol;
		(void)				param;

		if (gw->g.vmt != (gwinVMT *)&buttonVMT)	return;
		pcol = getDrawColors(gw);

		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
		gdispGFillEllipse(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->fill);
		gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
		gdispGDrawEllipse(gw->g.display, gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->edge);
	}
Example #12
0
void gwinTexteditDefaultDraw(GWidgetObject* gw, void* param)
{
	const char*			p;
	coord_t				cpos, tpos;
	const GColorSet*	pcol;

	(void)param;

	// Is it a valid handle?
	if (gw->g.vmt != (gwinVMT*)&texteditVMT)
		return;

	// Retrieve colors
	if ((gw->g.flags & GWIN_FLG_SYSENABLED))
		pcol = &gw->pstyle->enabled;
	else
		pcol = &gw->pstyle->disabled;

	// Adjust the text position so the cursor fits in the window
	p = gw->text;
	if (!gw2obj->cursorPos)
		tpos = 0;
	else {
		for(cpos = gw2obj->cursorPos; ; p++, cpos--) {
			tpos = gdispGetStringWidthCount(p, gw->g.font, cpos);
			if (tpos < gw->g.width-(TEXT_PADDING_LEFT+CURSOR_PADDING_LEFT))
				break;
		}
	}

	// Render background and string
	#if TEXT_PADDING_LEFT
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, TEXT_PADDING_LEFT, gw->g.height, pcol->fill);
	#endif
	gdispGFillStringBox(gw->g.display, gw->g.x + TEXT_PADDING_LEFT, gw->g.y, gw->g.width-TEXT_PADDING_LEFT, gw->g.height, p, gw->g.font, pcol->text, pcol->fill, justifyLeft);

	// Render cursor (if focused)
	if (gwinGetFocus() == (GHandle)gw) {
		// Calculate cursor stuff

		// Draw cursor
		tpos += gw->g.x + CURSOR_PADDING_LEFT + TEXT_PADDING_LEFT + gdispGetFontMetric(gw->g.font, fontBaselineX)/2;
		cpos = (gw->g.height - gdispGetFontMetric(gw->g.font, fontHeight))/2 - CURSOR_EXTRA_HEIGHT;
		gdispGDrawLine(gw->g.display, tpos, gw->g.y + cpos, tpos, gw->g.y + gw->g.height - cpos, pcol->edge);
	}

	// Render border
	gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);

	// Render highlighted border if focused
	_gwidgetDrawFocusRect(gw, 0, 0, gw->g.width, gw->g.height);

}
Example #13
0
	void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param) {
		const GColorSet *	pcol;
		point				arw[7];
		
		(void)				param;

		if (gw->g.vmt != (gwinVMT *)&buttonVMT)	return;
		pcol = getButtonColors(gw);

		// Create the arrow polygon
		arw[0].y = (gw->g.height-1)/2;				// Point center
		arw[0].x = gw->g.width-1;					// Arrow start
		arw[3].x = 0;								// Arrow end
		#if BTN_ARROWHEAD_DIV == 0
			if (gw->g.width <= arw[0].y) {
				arw[1].x = arw[3].x;				// End of head
				arw[1].y = arw[0].y+arw[0].x;		// Width of head  (side 1)
				arw[2].y = arw[1].y;				// Width of shaft (side 1)
				arw[4].y = arw[0].y-arw[0].x;		// Width of head  (side 2)
				arw[6].y = arw[4].y;				// Width of shaft (side 2)
			} else {
				arw[1].x = arw[0].x - arw[0].y;
				arw[1].y = arw[0].y << 1;
				arw[2].y = arw[0].y + arw[0].y/BTN_ARROWBODY_DIV;
				arw[4].y = arw[0].y - arw[0].y/BTN_ARROWBODY_DIV;
				arw[6].y = 0;
			}
		#else
			arw[1].x = arw[0].x - gw->g.width/BTN_ARROWHEAD_DIV;
			arw[1].y = arw[0].y << 1;
			arw[2].y = arw[0].y + arw[0].y/BTN_ARROWBODY_DIV;
			arw[4].y = arw[0].y - arw[0].y/BTN_ARROWBODY_DIV;
			arw[6].y = 0;
		#endif

		// Fill in the rest from the special points
		/* arw[0].x set */											/* arw[0].y set */
		/* arw[1].x set */											/* arw[1].y set */
		arw[2].x = arw[1].x;										/* arw[2].y set */
		/* arw[3].y set */											arw[3].y = arw[2].y;
		arw[4].x = arw[3].x;										/* arw[4].y set */
		arw[5].x = arw[1].x;										arw[5].y = arw[4].y;
		arw[6].x = arw[1].x;										/* arw[6].y set */

		// Draw
		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
		gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
		gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
		gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
	}
Example #14
0
void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param) {
	#define gsw			((GProgressbarObject *)gw)

	const GColorSet *	pcol;
	(void)				param;

	if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
		return;

	// get the colors right
	if ((gw->g.flags & GWIN_FLG_SYSENABLED))
		pcol = &gw->pstyle->pressed;
	else
		pcol = &gw->pstyle->disabled;

	// Vertical progressbar
	if (gw->g.width < gw->g.height) {
		if (gsw->dpos != gw->g.height-1)
			gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress);				// Active Area
		if (gsw->dpos != 0)
			gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress);							// Inactive area
		gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);												// Edge
		gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge);					// Thumb

	// Horizontal progressbar
	} else {
		if (gsw->dpos != gw->g.width-1)
			gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress);	// Inactive area
		if (gsw->dpos != 0)
			gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress);										// Active Area
		gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);												// Edge
		gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge);					// Thumb
	}
	gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);

	#undef gsw
}
Example #15
0
void gwinFrameDraw_Std(GWidgetObject *gw, void *param) {
	(void)param;

	if (gw->g.vmt != (gwinVMT *)&frameVMT)
		return;

	// Draw the frame
	gwinFrameDraw_Transparent(gw, param);

	// Drop out if that is all we want to draw
	if ((gw->g.flags & GWIN_FRAME_REDRAW_FRAME))
		return;

	// Draw the client area
	gdispGFillArea(gw->g.display, gw->g.x + FRM_BORDER_L, gw->g.y + FRM_BORDER_T, gw->g.width - (FRM_BORDER_L+FRM_BORDER_R), gw->g.height - (FRM_BORDER_T+FRM_BORDER_B), gw->pstyle->background);
}
Example #16
0
	void gwinButtonDraw_Rounded(GWidgetObject *gw, void *param) {
		const GColorSet *	pcol;
		(void)				param;

		if (gw->g.vmt != (gwinVMT *)&buttonVMT)	return;
		pcol = getDrawColors(gw);

		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
		if (gw->g.width >= 2*RND_CNR_SIZE+10) {
			gdispGFillRoundedBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->fill);
			gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->text, gw->g.font, pcol->text, justifyCenter);
			gdispGDrawRoundedBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->edge);
		} else {
			gdispGFillStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
			gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
		}
	}
Example #17
0
	void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param) {
		const GColorSet *	pcol;
		(void)				param;
		point				arw[7];

		if (gw->g.vmt != (gwinVMT *)&buttonVMT)	return;
		pcol = getDrawColors(gw);

		arw[0].x = gw->g.width-1; arw[0].y = gw->g.height/2;
		arw[1].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[1].y = 0;
		arw[2].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[2].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2;
		arw[3].x = 0; arw[3].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2;
		arw[4].x = 0; arw[4].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2;
		arw[5].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2;
		arw[6].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1;

		gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
		gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
		gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
		gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
	}
Example #18
0
	static inline void _tsClearCross(const MousePoint *pp) {
		gdispGFillArea(MouseConfig.display, pp->x - 15, pp->y - 15, 42, 42, Blue);
	}
	static inline void CalibrationCrossClear(GMouse *m, const point *pp) {
		gdispGFillArea(m->display, pp->x - CALIBRATION_CROSS_RADIUS, pp->y - CALIBRATION_CROSS_RADIUS, CALIBRATION_CROSS_RADIUS*2+1, CALIBRATION_CROSS_RADIUS*2+1, CALIBRATION_BACKGROUND);
	}
Example #20
0
void gwinPutChar(GHandle gh, char c) {
	#define gcw		((GConsoleObject *)gh)
	uint8_t			width, fy;

	if (gh->vmt != &consoleVMT || !gh->font)
		return;

	fy = gdispGetFontMetric(gh->font, fontHeight);

	#if GWIN_CONSOLE_ESCSEQ
		/**
		 * Handle escape sequences
		 * 			ESC color		Change subsequent text color
		 * 							color:	"0" = black, "1" = red, "2" = green, "3" = yellow, "4" = blue,
		 * 									"5" = magenta, "6" = cyan, "7" = white
		 * 			ESC C			Revert subsequent text color to the window default
		 * 			ESC u			Turn on underline
		 * 			ESC U			Turn off underline
		 * 			ESC b			Turn on bold
		 * 			ESC B			Turn off bold
		 * 			ESC J			Clear the window
		 */
		switch (gcw->escstate) {
		case 1:
			gcw->escstate = 0;
			if (ESCtoAttr(c, &gcw->currattr)) {
				if (gcw->cx == 0 && gcw->cy == 0)
					gcw->startattr = gcw->currattr;
				else {
					putCharInBuffer(gcw, 27);
					putCharInBuffer(gcw, c);
				}
			} else {
				switch(c) {
				case 'J':
					// Clear the console and reset the cursor
					clearBuffer(gcw);
					if (DrawStart(gh)) {
						gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
						DrawEnd(gh);
					}
					gcw->cx = 0;
					gcw->cy = 0;
					gcw->startattr = gcw->currattr;
					break;
				}
			}
			return;
		}
	#endif

	/**
	 * Special Characters:
	 *
	 * Carriage returns and line feeds (\r & \n) are handled in unix terminal cooked mode; that is,
	 * line feeds perform both actions and carriage-returns are ignored.
	 *
	 * if GWIN_CONSOLE_ESCSEQ is turned on then ESC is trapped ready for the escape command.
	 *
	 * All other characters are treated as printable.
	 */
	switch (c) {
	case '\n':
		// clear to the end of the line
		#if GWIN_CONSOLE_USE_CLEAR_LINES
			if (gcw->cx == 0 && gcw->cy+fy < gh->height && DrawStart(gh)) {
				gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
				DrawEnd(gh);
			}
		#endif
		// update the cursor
		gcw->cx = 0;
		gcw->cy += fy;
		putCharInBuffer(gcw, '\n');
		// We use lazy scrolling here and only scroll when the next char arrives
		return;

	case '\r':
		// gcw->cx = 0;
		return;

	#if GWIN_CONSOLE_ESCSEQ
		case 27:		// ESC
			gcw->escstate = 1;
			return;
	#endif
	}

	// Characters with no width are ignored
	if (!(width = gdispGetCharWidth(c, gh->font)))
		return;

	// Allow space for (very crude) bold
	#if GWIN_CONSOLE_ESCSEQ
		if ((gcw->currattr & ESC_BOLD))
			width++;
	#endif

	// Do we need to go to the next line to fit this character?
	if (gcw->cx + width >= gh->width) {
		gcw->cx = 0;
		gcw->cy += fy;
		putCharInBuffer(gcw, '\n');
	}

	// Do we need to scroll to fit this character?
	if (gcw->cy + fy > gh->height) {
		#if GWIN_CONSOLE_USE_HISTORY && GWIN_CONSOLE_BUFFER_SCROLLING
			if (gcw->buffer) {
				// Scroll the buffer and then redraw using the buffer
				scrollBuffer(gcw);
				if (DrawStart(gh)) {
					HistoryuRedraw(gh);
					DrawEnd(gh);
				}
			} else
		#endif
		#if GDISP_NEED_SCROLL
			{
				// Scroll the console using hardware
				scrollBuffer(gcw);
				if (DrawStart(gh)) {
					gdispGVerticalScroll(gh->display, gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
					DrawEnd(gh);
				}

				// Set the cursor to the start of the last line
				gcw->cx = 0;
				gcw->cy = (((coord_t)(gh->height/fy))-1)*fy;
			}
		#else
			{
				// Clear the console and reset the cursor
				clearBuffer(gcw);
				if (DrawStart(gh)) {
					gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
					DrawEnd(gh);
				}
				gcw->cx = 0;
				gcw->cy = 0;
				#if GWIN_CONSOLE_ESCSEQ
					gcw->startattr = gcw->currattr;
				#endif
			}
		#endif
	}

	// Save the char
	putCharInBuffer(gcw, c);

	// Draw the character
	if (DrawStart(gh)) {

		// If we are at the beginning of a new line clear the line
		#if GWIN_CONSOLE_USE_CLEAR_LINES
			if (gcw->cx == 0)
				gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
		#endif

		#if GWIN_CONSOLE_USE_FILLED_CHARS
			gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw), gh->bgcolor);
		#else
			gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
		#endif

		#if GWIN_CONSOLE_ESCSEQ
			// Draw the underline
			if ((gcw->currattr & ESC_UNDERLINE))
				gdispGDrawLine(gh->display, gh->x + gcw->cx, gh->y + gcw->cy + fy - gdispGetFontMetric(gh->font, fontDescendersHeight),
											gh->x + gcw->cx + width + gdispGetFontMetric(gh->font, fontCharPadding), gh->y + gcw->cy + fy - gdispGetFontMetric(gh->font, fontDescendersHeight),
											ESCPrintColor(gcw));
			// Bold (very crude)
			if ((gcw->currattr & ESC_BOLD))
				gdispGDrawChar(gh->display, gh->x + gcw->cx + 1, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
		#endif

		DrawEnd(gh);
	}

	// Update the cursor
	gcw->cx += width + gdispGetFontMetric(gh->font, fontCharPadding);

	#undef gcw
}
Example #21
0
static void WM_Redraw(GHandle gh) {
	#if GWIN_NEED_CONTAINERS
		redo_redraw:
	#endif
	if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
		if (gh->vmt->Redraw)
			gh->vmt->Redraw(gh);
		else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
			// We can't redraw but we want full coverage so just clear the area
			gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);

			// Only do an after clear if this is not a parent reveal
			if (!(gh->flags & GWIN_FLG_PARENTREVEAL) && gh->vmt->AfterClear)
				gh->vmt->AfterClear(gh);
		}

		#if GWIN_NEED_CONTAINERS
			// If this is container but not a parent reveal, mark any visible children for redraw
			//	We redraw our children here as we have overwritten them in redrawing the parent
			//	as GDISP/GWIN doesn't support complex clipping regions.
			if ((gh->flags & (GWIN_FLG_CONTAINER|GWIN_FLG_PARENTREVEAL)) == GWIN_FLG_CONTAINER) {

				// Container redraw is done
				gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);

				for(gh = gwinGetFirstChild(gh); gh; gh = gwinGetSibling(gh))
					_gwinUpdate(gh);
				return;
			}
		#endif

	} else {
		if ((gh->flags & GWIN_FLG_BGREDRAW)) {
			GHandle		gx;

			#if GWIN_NEED_CONTAINERS
				if (gh->parent) {
					// Child redraw is done
					gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);


					// Get the parent to redraw the area
					gh = gh->parent;

					// The parent is already marked for redraw - don't do it now.
					if ((gh->flags & GWIN_FLG_NEEDREDRAW))
						return;

					// Use the existing clipping region and redraw now
					gh->flags |= (GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
					goto redo_redraw;
				}
			#endif

			// Clear the area to the background color
			gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());

			// Now loop over all windows looking for overlaps. Redraw them if they overlap the newly exposed area.
			for(gx = gwinGetNextWindow(0); gx; gx = gwinGetNextWindow(gx)) {
				if ((gx->flags & GWIN_FLG_SYSVISIBLE)
						&& gx->display == gh->display
						&& gx->x < gh->x+gh->width && gx->y < gh->y+gh->height && gx->x+gx->width >= gh->x && gx->y+gx->height >= gh->y) {
					if (gx->vmt->Redraw)
						gx->vmt->Redraw(gx);
					else
						// We can't redraw this window but we want full coverage so just clear the area
						gdispGFillArea(gx->display, gx->x, gx->y, gx->width, gx->height, gx->bgcolor);
				}
			}

		}
	}

	// Redraw is done
	gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
}
Example #22
0
static void ImageRedraw(GHandle gh) {
	coord_t		x, y, w, h, dx, dy;
	color_t		bg;
	#if GWIN_NEED_IMAGE_ANIMATION
		delaytime_t	delay;
	#endif

	// The default display area
	dx = 0;
	dy = 0;
	x = gh->x;
	y = gh->y;
	w = gh->width;
	h = gh->height;
	bg = gwinGetDefaultBgColor();

	// If the image isn't open just clear the area
	if (!gdispImageIsOpen(&gw->image)) {
		gdispGFillArea(gh->display, x, y, w, h, bg);
		return;
	}

	// Center horizontally if the area is larger than the image
	if (gw->image.width < w) {
		w = gw->image.width;
		dx = (gh->width-w)/2;
		x += dx;
		if (dx)
			gdispGFillArea(gh->display, gh->x, y, dx, h, bg);
		gdispGFillArea(gh->display, x+w, y, gh->width-dx-w, h, bg);
		dx = 0;
	}

	// Center image horizontally if the area is smaller than the image
	else if (gw->image.width > w) {
		dx = (gw->image.width - w)/2;
	}

	// Center vertically if the area is larger than the image
	if (gw->image.height < h) {
		h = gw->image.height;
		dy = (gh->height-h)/2;
		y += dy;
		if (dy)
			gdispGFillArea(gh->display, x, gh->y, w, dy, bg);
		gdispGFillArea(gh->display, x, y+h, w, gh->height-dy-h, bg);
		dy = 0;
	}

	// Center image vertically if the area is smaller than the image
	else if (gw->image.height > h) {
		dy = (gw->image.height - h)/2;
	}

	// Reset the background color in case it has changed
	gdispImageSetBgColor(&gw->image, bg);

	// Display the image
	gdispGImageDraw(gh->display, &gw->image, x, y, w, h, dx, dy);

	#if GWIN_NEED_IMAGE_ANIMATION
		// read the delay for the next frame
		delay = gdispImageNext(&gw->image);

		// Wait for that delay if required
		switch(delay) {
		case TIME_INFINITE:
			// Everything is done
			break;
		case TIME_IMMEDIATE:
			// We can't allow a continuous loop here as it would lock the system up so we delay for the minimum period
			delay = 1;
			// Fall through
		default:
			// Start the timer to draw the next frame of the animation
			gtimerStart(&gw->timer, ImageTimer, (void*)gh, FALSE, delay);
			break;
		}
	#endif
}
Example #23
0
bool_t ginputCalibrateMouse(uint16_t instance) {
	#if !GINPUT_MOUSE_NEED_CALIBRATION
		(void) instance;
		
		return FALSE;
	#else

		const coord_t height  =  gdispGGetHeight(MouseConfig.display);
		const coord_t width  =  gdispGGetWidth(MouseConfig.display);
		#if GINPUT_MOUSE_CALIBRATE_EXTREMES
			const MousePoint cross[]  =  {{0, 0},
									{(width - 1) , 0},
									{(width - 1) , (height - 1)},
									{(width / 2), (height / 2)}}; /* Check point */
		#else
			const MousePoint cross[]  =  {{(width / 4), (height / 4)},
									{(width - (width / 4)) , (height / 4)},
									{(width - (width / 4)) , (height - (height / 4))},
									{(width / 2), (height / 2)}}; /* Check point */
		#endif
		MousePoint points[GINPUT_MOUSE_CALIBRATION_POINTS];
		const MousePoint	*pc;
		MousePoint *pt;
		int32_t px, py;
		unsigned i, j;
		font_t	font1, font2;
		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
			unsigned	err;
		#endif

		if (instance || (MouseConfig.flags & FLG_IN_CAL))
			return FALSE;

		font1 = gdispOpenFont(GINPUT_MOUSE_CALIBRATION_FONT);
		font2 = gdispOpenFont(GINPUT_MOUSE_CALIBRATION_FONT2);

		MouseConfig.flags |= FLG_IN_CAL;
		gtimerStop(&MouseTimer);
		MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);

		#if GDISP_NEED_CLIP
			gdispGSetClip(MouseConfig.display, 0, 0, width, height);
		#endif

		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
			while(1) {
		#endif
				gdispGClear(MouseConfig.display, Blue);

				gdispGFillStringBox(MouseConfig.display, 0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, font1,  White, Blue, justifyCenter);

				for(i = 0, pt = points, pc = cross; i < GINPUT_MOUSE_CALIBRATION_POINTS; i++, pt++, pc++) {
					_tsDrawCross(pc);

					do {

						/* Wait for the mouse to be pressed */
						while(get_raw_reading(&MouseConfig.t), !(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT))
							gfxSleepMilliseconds(20);

						/* Average all the samples while the mouse is down */
						for(px = py = 0, j = 0;
								gfxSleepMilliseconds(20),			/* Settling time between readings */
								get_raw_reading(&MouseConfig.t),
								(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT);
								j++) {
							px += MouseConfig.t.x;
							py += MouseConfig.t.y;
						}

					} while(!j);

					pt->x = px / j;
					pt->y = py / j;

					_tsClearCross(pc);

					if (i >= 1 && pt->x == (pt-1)->x && pt->y == (pt-1)->y) {
						gdispGFillStringBox(MouseConfig.display, 0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_SAME_TEXT, font2,  Red, Yellow, justifyCenter);
						gfxSleepMilliseconds(5000);
						gdispGFillArea(MouseConfig.display, 0, 35, width, 40, Blue);
					}

				}

				/* Apply 3 point calibration algorithm */
				_tsDo3PointCalibration(cross, points, MouseConfig.display, &MouseConfig.caldata);

				 /* Verification of correctness of calibration (optional) :
				 *  See if the 4th point (Middle of the screen) coincides with the calibrated
				 *  result. If point is within +/- Squareroot(ERROR) pixel margin, then successful calibration
				 *  Else, start from the beginning.
				 */
		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
				/* Transform the co-ordinates */
				MouseConfig.t.x = points[3].x;
				MouseConfig.t.y = points[3].y;
				_tsTransform(&MouseConfig.t, &MouseConfig.caldata);
				_tsOrientClip(&MouseConfig.t, MouseConfig.display, FALSE);

				/* Calculate the delta */
				err = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +
					(MouseConfig.t.y - cross[3].y) * (MouseConfig.t.y - cross[3].y);

				if (err <= GINPUT_MOUSE_MAX_CALIBRATION_ERROR * GINPUT_MOUSE_MAX_CALIBRATION_ERROR)
					break;

				gdispGFillStringBox(MouseConfig.display, 0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_ERROR_TEXT, font2,  Red, Yellow, justifyCenter);
				gfxSleepMilliseconds(5000);
			}
		#endif

		// Restart everything
		gdispCloseFont(font1);
		gdispCloseFont(font2);
		MouseConfig.flags |= FLG_CAL_OK;
		MouseConfig.last_buttons = 0;
		get_calibrated_reading(&MouseConfig.t);
		MouseConfig.flags &= ~FLG_IN_CAL;
		if ((MouseConfig.flags & FLG_INIT_DONE))
			gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
		
		// Save the calibration data (if possible)
		if (MouseConfig.fnsavecal) {
			MouseConfig.fnsavecal(instance, (const uint8_t *)&MouseConfig.caldata, sizeof(MouseConfig.caldata));
			MouseConfig.flags |= FLG_CAL_SAVED;
		}

		// Clear the screen using the GWIN default background color
		#if GFX_USE_GWIN
			gdispGClear(MouseConfig.display, gwinGetDefaultBgColor());
		#else
			gdispGClear(MouseConfig.display, Black);
		#endif
	
		return TRUE;
	#endif
}
Example #24
0
void gwinListDefaultDraw(GWidgetObject* gw, void* param) {
	const gfxQueueASyncItem*	qi;
	int							i;
	coord_t						x, y, iheight, iwidth;
	color_t						fill;
	const GColorSet *			ps;
	#if GWIN_NEED_LIST_IMAGES
		coord_t					sy;
	#endif
	#if GDISP_NEED_CONVEX_POLYGON
		static const point upArrow[] = { {0, LST_ARROW_SZ}, {LST_ARROW_SZ, LST_ARROW_SZ}, {LST_ARROW_SZ/2, 0} };
		static const point downArrow[] = { {0, 0}, {LST_ARROW_SZ, 0}, {LST_ARROW_SZ/2, LST_ARROW_SZ} };
	#endif

	(void)param;

	// is it a valid handle?
	if (gw->g.vmt != (gwinVMT *)&listVMT)
		return;

	// don't render if render has been disabled
	if (!(gw->g.flags & GLIST_FLG_ENABLERENDER))
		return;

	ps = (gw->g.flags & GWIN_FLG_SYSENABLED) ? &gw->pstyle->enabled : &gw->pstyle->disabled;
	iheight = gdispGetFontMetric(gw->g.font, fontHeight) + LST_VERT_PAD;
	x = 1;

	// the scroll area
	if (gw->g.flags & GLIST_FLG_SCROLLSMOOTH) {
		iwidth = gw->g.width - 2 - 4;
		if (gw2obj->cnt > 0) {
			int max_scroll_value = gw2obj->cnt * iheight - gw->g.height-2;
			if (max_scroll_value > 0) {
				int bar_height = (gw->g.height-2) * (gw->g.height-2) / (gw2obj->cnt * iheight);
				gdispGFillArea(gw->g.display, gw->g.x + gw->g.width-4, gw->g.y + 1, 2, gw->g.height-1, gw->pstyle->background);
				gdispGFillArea(gw->g.display, gw->g.x + gw->g.width-4, gw->g.y + gw2obj->top * ((gw->g.height-2)-bar_height) / max_scroll_value, 2, bar_height, ps->edge);
			}
		}
	} else if ((gw2obj->cnt > (gw->g.height-2) / iheight) || (gw->g.flags & GLIST_FLG_SCROLLALWAYS)) {
		iwidth = gw->g.width - (LST_SCROLLWIDTH+3);
		gdispGFillArea(gw->g.display, gw->g.x+iwidth+2, gw->g.y+1, LST_SCROLLWIDTH, gw->g.height-2, gdispBlendColor(ps->fill, gw->pstyle->background, 128));
		gdispGDrawLine(gw->g.display, gw->g.x+iwidth+1, gw->g.y+1, gw->g.x+iwidth+1, gw->g.y+gw->g.height-2, ps->edge);
		#if GDISP_NEED_CONVEX_POLYGON
			gdispGFillConvexPoly(gw->g.display, gw->g.x+iwidth+((LST_SCROLLWIDTH-LST_ARROW_SZ)/2+2), gw->g.y+(LST_ARROW_SZ/2+1), upArrow, 3, ps->fill);
			gdispGFillConvexPoly(gw->g.display, gw->g.x+iwidth+((LST_SCROLLWIDTH-LST_ARROW_SZ)/2+2), gw->g.y+gw->g.height-(LST_ARROW_SZ+LST_ARROW_SZ/2+1), downArrow, 3, ps->fill);
		#else
			#warning "GWIN: Lists display better when GDISP_NEED_CONVEX_POLYGON is turned on"
			gdispGFillArea(gw->g.display, gw->g.x+iwidth+((LST_SCROLLWIDTH-LST_ARROW_SZ)/2+2), gw->g.y+(LST_ARROW_SZ/2+1), LST_ARROW_SZ, LST_ARROW_SZ, ps->fill);
			gdispGFillArea(gw->g.display, gw->g.x+iwidth+((LST_SCROLLWIDTH-LST_ARROW_SZ)/2+2), gw->g.y+gw->g.height-(LST_ARROW_SZ+LST_ARROW_SZ/2+1), LST_ARROW_SZ, LST_ARROW_SZ, ps->fill);
		#endif
	} else
		iwidth = gw->g.width - 2;

	#if GWIN_NEED_LIST_IMAGES
		if ((gw->g.flags & GLIST_FLG_HASIMAGES)) {
			x += iheight;
			iwidth -= iheight;
		}
	#endif


	// Find the top item
	for (qi = gfxQueueASyncPeek(&gw2obj->list_head), i = iheight - 1; i < gw2obj->top && qi; qi = gfxQueueASyncNext(qi), i+=iheight);

	// the list frame
	gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, ps->edge);

	// Set the clipping region so we do not override the frame.
	#if GDISP_NEED_CLIP
		gdispGSetClip(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2);
	#endif

	// Draw until we run out of room or items
	for (y = 1-(gw2obj->top%iheight); y < gw->g.height-2 && qi; qi = gfxQueueASyncNext(qi), y += iheight) {
		fill = (qi2li->flags & GLIST_FLG_SELECTED) ? ps->fill : gw->pstyle->background;
		gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+y, iwidth, iheight, fill);
		#if GWIN_NEED_LIST_IMAGES
			if ((gw->g.flags & GLIST_FLG_HASIMAGES)) {
				// Clear the image area
				if (qi2li->pimg && gdispImageIsOpen(qi2li->pimg)) {
					// Calculate which image
					sy = (qi2li->flags & GLIST_FLG_SELECTED) ? 0 : (iheight-LST_VERT_PAD);
					if (!(gw->g.flags & GWIN_FLG_SYSENABLED))
						sy += 2*(iheight-LST_VERT_PAD);
					while (sy > qi2li->pimg->height)
						sy -= iheight-LST_VERT_PAD;
					// Draw the image
					gdispImageSetBgColor(qi2li->pimg, fill);
					gdispGImageDraw(gw->g.display, qi2li->pimg, gw->g.x+1, gw->g.y+y, iheight-LST_VERT_PAD, iheight-LST_VERT_PAD, 0, sy);
				}
			}
		#endif
		gdispGFillStringBox(gw->g.display, gw->g.x+x+LST_HORIZ_PAD, gw->g.y+y, iwidth-LST_HORIZ_PAD, iheight, qi2li->text, gw->g.font, ps->text, fill, justifyLeft);
	}

	// Fill any remaining item space
	if (y < gw->g.height-1)
		gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+y, iwidth, gw->g.height-1-y, gw->pstyle->background);
}