예제 #1
0
static joy_char_t *
LoadJoystickAlpha (STRING String, int *count)
{
	UNICODE *str;
	int c;
	int i;
	joy_char_t *chars;
	UNICODE *cur;

	*count = 0;
	str = GetStringAddress (String);
	if (!str)
		return 0;

	c = utf8StringCount (str);
	chars = HMalloc (c * sizeof (*chars));
	if (!chars)
		return 0;

	for (i = 0, cur = str; i < c; ++i)
	{
		int len = ReadOneChar (chars + i, cur);
		cur += len;
	}

	*count = c;
	return chars;
}
예제 #2
0
void
DrawLabelAsWindow(WIDGET_LABEL *label)
{
	COLOR oldfg = SetContextForeGroundColor (WIDGET_DIALOG_TEXT_COLOR);
	FONT  oldfont = SetContextFont (StarConFont);
	FRAME oldFontEffect = SetContextFontEffect (NULL);
	RECT r;
	TEXT t;
	int i, win_w, win_h;

	/* Compute the dimensions of the label */
	win_h = label->height ((WIDGET *)label) + 16;
	win_w = 0;
	for (i = 0; i < label->line_count; i++)
	{
		int len = utf8StringCount (label->lines[i]);
		if (len > win_w)
		{
			win_w = len;
		}
	}
	win_w = (win_w * 6) + 16;

	BatchGraphics ();
	r.corner.x = (SCREEN_WIDTH - win_w) >> 1;
	r.corner.y = (SCREEN_HEIGHT - win_h) >> 1;
	r.extent.width = win_w;
	r.extent.height = win_h;
	DrawShadowedBox (&r, SHADOWBOX_BACKGROUND_COLOR, 
			SHADOWBOX_DARK_COLOR, SHADOWBOX_MEDIUM_COLOR);

	t.baseline.x = r.corner.x + (r.extent.width >> 1);
	t.baseline.y = r.corner.y + 16;
	for (i = 0; i < label->line_count; i++)
	{
		t.pStr = label->lines[i];
		t.align = ALIGN_CENTER;
		t.CharCount = (COUNT)~0;
		font_DrawText (&t);
		t.baseline.y += 8;
	}

	UnbatchGraphics ();

	SetContextFontEffect (oldFontEffect);
	SetContextFont (oldfont);
	SetContextForeGroundColor (oldfg);
}
예제 #3
0
// windowRect, if not NULL, will be filled with the dimensions of the
// window drawn.
void
DrawLabelAsWindow (WIDGET_LABEL *label, RECT *windowRect)
{
	Color oldfg = SetContextForeGroundColor (WIDGET_DIALOG_TEXT_COLOR);
	FONT  oldfont = 0;
	FRAME oldFontEffect = SetContextFontEffect (NULL);
	RECT r;
	TEXT t;
	int i, win_w, win_h;

	if (cur_font)
		oldfont = SetContextFont (cur_font);

	/* Compute the dimensions of the label */
	win_h = label->height ((WIDGET *)label) + (16 << RESOLUTION_FACTOR); // JMS_GFX
	win_w = 0;
	for (i = 0; i < label->line_count; i++)
	{
		int len = utf8StringCount (label->lines[i]);
		if (len > win_w)
		{
			win_w = len;
		}
	}
	win_w = (win_w * (6 << RESOLUTION_FACTOR)) + (16 << RESOLUTION_FACTOR); // JMS_GFX

	BatchGraphics ();
	r.corner.x = (ScreenWidth - win_w) >> 1;
	r.corner.y = (ScreenHeight - win_h) >> 1;
	r.extent.width = win_w;
	r.extent.height = win_h;
	DrawShadowedBox (&r, win_bg_clr, win_dark_clr, win_medium_clr);

	t.baseline.x = r.corner.x + (r.extent.width >> 1);
	t.baseline.y = r.corner.y + (16 << RESOLUTION_FACTOR); // JMS_GFX
	for (i = 0; i < label->line_count; i++)
	{
		t.pStr = label->lines[i];
		t.align = ALIGN_CENTER;
		t.CharCount = (COUNT)~0;
		font_DrawText (&t);
		t.baseline.y += (8 << RESOLUTION_FACTOR); // JMS_GFX
	}

	UnbatchGraphics ();

	SetContextFontEffect (oldFontEffect);
	if (oldfont)
		SetContextFont (oldfont);
	SetContextForeGroundColor (oldfg);

	if (windowRect != NULL) {
		// Add the outer border added by DrawShadowedBox.
		// XXX: It may be nicer to add a border size parameter to
		// DrawShadowedBox, instead of assuming 2 here.
		windowRect->corner.x = r.corner.x - 2 * (1 + RESOLUTION_FACTOR);
		windowRect->corner.y = r.corner.y - 2 * (1 + RESOLUTION_FACTOR);
		windowRect->extent.width = r.extent.width + 4 * (1 + RESOLUTION_FACTOR);
		windowRect->extent.height = r.extent.height + 4 * (1 + RESOLUTION_FACTOR);
	}
}
예제 #4
0
void
Widget_DrawTextEntry (WIDGET *_self, int x, int y)
{
	WIDGET_TEXTENTRY *self = (WIDGET_TEXTENTRY *)_self;
	Color oldtext;
	Color inactive, default_color, selected;
	FONT  oldfont = 0;
	FRAME oldFontEffect = SetContextFontEffect (NULL);
	TEXT t;

	if (cur_font)
		oldfont = SetContextFont (cur_font);
	
	default_color = WIDGET_INACTIVE_SELECTED_COLOR;
	selected = WIDGET_ACTIVE_COLOR;
	inactive = WIDGET_INACTIVE_COLOR;

	BatchGraphics ();

	t.baseline.x = x + 64 * RESOLUTION_FACTOR; // JMS_GFX
	t.baseline.y = y;
	t.align = ALIGN_LEFT;
	t.CharCount = ~0;
	t.pStr = self->category;
	if (widget_focus == _self)
	{
		oldtext = SetContextForeGroundColor (selected);
	}
	else
	{
		oldtext = SetContextForeGroundColor (default_color);
	}
	font_DrawText (&t);
	
	t.baseline.x -= 64 * RESOLUTION_FACTOR; // JMS_GFX

	/* Force string termination */
	self->value[WIDGET_TEXTENTRY_WIDTH-1] = 0;

	t.baseline.y = y;
	t.CharCount = utf8StringCount (self->value);
	t.pStr = self->value;

	if (!(self->state & WTE_EDITING))
	{	// normal or selected state
		t.baseline.x = 160 << RESOLUTION_FACTOR; // JMS_GFX
		t.align = ALIGN_CENTER;

		if (widget_focus == _self)
		{
			oldtext = SetContextForeGroundColor (selected);
		}
		else
		{
			oldtext = SetContextForeGroundColor (inactive);
		}
		font_DrawText (&t);
	}
	else
	{	// editing state
		COUNT i;
		RECT text_r;
		BYTE char_deltas[WIDGET_TEXTENTRY_WIDTH];
		BYTE *pchar_deltas;
		RECT r;
		SIZE leading;

		t.baseline.x = 90 << RESOLUTION_FACTOR; // JMS_GFX
		t.align = ALIGN_LEFT;

		// calc background box dimensions
		// XXX: this may need some tuning, especially if a
		//   different font is used. The font 'leading' values
		//   are not what they should be.
#define BOX_VERT_OFFSET 2
		GetContextFontLeading (&leading);
		r.corner.x = t.baseline.x - 1;
		r.corner.y = t.baseline.y - leading + BOX_VERT_OFFSET;
		r.extent.width = ScreenWidth - r.corner.x - 10;
		r.extent.height = leading + 2;

		TextRect (&t, &text_r, char_deltas);
#if 0
		// XXX: this should potentially be used in ChangeCallback
		if ((text_r.extent.width + 2) >= r.extent.width)
		{	// the text does not fit the input box size and so
			// will not fit when displayed later
			UnbatchGraphics ();
			// disallow the change
			return (FALSE);
		}
#endif

		oldtext = SetContextForeGroundColor (selected);
		DrawFilledRectangle (&r);

		// calculate the cursor position and draw it
		pchar_deltas = char_deltas;
		for (i = self->cursor_pos; i > 0; --i)
			r.corner.x += (SIZE)*pchar_deltas++;
		if (self->cursor_pos < t.CharCount) /* cursor mid-line */
			--r.corner.x;
		if (self->state & WTE_BLOCKCUR)
		{	// Use block cursor for keyboardless systems
			if (self->cursor_pos == t.CharCount)
			{	// cursor at end-line -- use insertion point
				r.extent.width = 1;
			}
			else if (self->cursor_pos + 1 == t.CharCount)
			{	// extra pixel for last char margin
				r.extent.width = (SIZE)*pchar_deltas + 2;
			}
			else
			{	// normal mid-line char
				r.extent.width = (SIZE)*pchar_deltas + 1;
			}
		}
		else
		{	// Insertion point cursor
			r.extent.width = 1;
		}
		// position cursor within input field rect
		++r.corner.x;
		++r.corner.y;
		r.extent.height -= 2;
		SetContextForeGroundColor (WIDGET_CURSOR_COLOR);
		DrawFilledRectangle (&r);

		SetContextForeGroundColor (inactive);
		font_DrawText (&t);
	}
	
	UnbatchGraphics ();
	SetContextFontEffect (oldFontEffect);
	if (oldfont)
		SetContextFont (oldfont);
	SetContextForeGroundColor (oldtext);
}
예제 #5
0
BOOLEAN
DoTextEntry (PTEXTENTRY_STATE pTES)
{
	wchar_t ch;
	UNICODE *pStr;
	UNICODE *CacheInsPt;
	int CacheCursorPos;
	int len;
	BOOLEAN changed = FALSE;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		return (FALSE);

	if (!pTES->Initialized)
	{	// init basic vars
		int lwlen;

		pTES->InputFunc = DoTextEntry;
		pTES->Success = FALSE;
		pTES->Initialized = TRUE;
		pTES->JoystickMode = FALSE;
		pTES->UpperRegister = TRUE;
	
		// init insertion point
		if ((size_t)pTES->CursorPos > utf8StringCount (pTES->BaseStr))
			pTES->CursorPos = utf8StringCount (pTES->BaseStr);
		pTES->InsPt = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos);

		// load joystick alphabet
		pTES->JoyAlphaString = CaptureStringTable (
				LoadStringTable (JOYSTICK_ALPHA_STRTAB));
		pTES->JoyAlpha = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 0),
				&pTES->JoyAlphaLength);
		pTES->JoyUpper = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 1),
				&pTES->JoyRegLength);
		pTES->JoyLower = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 2),
				&lwlen);
		if (lwlen != pTES->JoyRegLength)
		{
			if (lwlen < pTES->JoyRegLength)
				pTES->JoyRegLength = lwlen;
			log_add (log_Warning, "Warning: Joystick upper-lower registers"
					" size mismatch; using the smallest subset (%d)",
					pTES->JoyRegLength);
		}

		pTES->CacheStr = HMalloc (pTES->MaxSize * sizeof (*pTES->CacheStr));
		
		DoInput (pTES, TRUE);

		if (pTES->CacheStr)
			HFree (pTES->CacheStr);
		if (pTES->JoyLower)
			HFree (pTES->JoyLower);
		if (pTES->JoyUpper)
			HFree (pTES->JoyUpper);
		if (pTES->JoyAlpha)
			HFree (pTES->JoyAlpha);
		DestroyStringTable ( ReleaseStringTable (pTES->JoyAlphaString));

		return pTES->Success;
	}

	pStr = pTES->InsPt;
	len = strlen (pStr);
	// save a copy of string
	CacheInsPt = pTES->InsPt;
	CacheCursorPos = pTES->CursorPos;
	memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize);

	// process the pending character buffer
	ch = GetNextCharacter ();
	if (!ch && PulsedInputState.menu[KEY_MENU_ANY])
	{	// keyboard repeat, but only when buffer empty
		ch = GetLastCharacter ();
	}
	while (ch)
	{
		UNICODE chbuf[8];
		int chsize;

		pTES->JoystickMode = FALSE;

		chsize = getStringFromChar (chbuf, sizeof (chbuf), ch);
		if (isWidePrintChar (ch) && chsize > 0)
		{
			if (pStr + len - pTES->BaseStr + chsize < pTES->MaxSize)
			{	// insert character, when fits
				memmove (pStr + chsize, pStr, len + 1);
				memcpy (pStr, chbuf, chsize);
				pStr += chsize;
				++pTES->CursorPos;
				changed = TRUE;
			}
			else
			{	// does not fit
				PlayMenuSound (MENU_SOUND_FAILURE);
			}
		}
		ch = GetNextCharacter ();
	}

	if (PulsedInputState.menu[KEY_MENU_DELETE])
	{
		if (len)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			memmove (pStr, pStr + ch.len, len - ch.len + 1);
			len -= ch.len;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_BACKSPACE])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);
			
			memmove (prev, pStr, len + 1);
			pStr = prev;
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);

			pStr = prev;
			len += (prev - pStr);
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_RIGHT])
	{
		if (len > 0)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			pStr += ch.len;
			len -= ch.len;
			++pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_HOME])
	{
		if (pStr > pTES->BaseStr)
		{
			pStr = pTES->BaseStr;
			len = strlen (pStr);
			pTES->CursorPos = 0;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_END])
	{
		if (len > 0)
		{
			pTES->CursorPos += utf8StringCount (pStr);
			pStr += len;
			len = 0;
			changed = TRUE;
		}
	}
	
	if (pTES->JoyAlpha && (
			PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN] ||
			PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
			PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) )
	{	// do joystick text
		joy_char_t ch;
		joy_char_t newch;
		joy_char_t cmpch;
		int i;

		pTES->JoystickMode = TRUE;

		if (len)
			ReadOneChar (&ch, pStr);
		else
			ch = pTES->JoyAlpha[0];
		
		newch = ch;
		JoyCharToUpper (&cmpch, &ch, pTES);

		// find current char in the alphabet
		i = JoyCharFindIn (&cmpch, pTES->JoyAlpha, pTES->JoyAlphaLength);

		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			--i;
			if (i < 0)
				i = pTES->JoyAlphaLength - 1;
			newch = pTES->JoyAlpha[i];
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			++i;
			if (i >= pTES->JoyAlphaLength)
				i = 0;
			newch = pTES->JoyAlpha[i];
		}

		if (PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
				PulsedInputState.menu[KEY_MENU_PAGE_DOWN])
		{
			if (len)
			{	// single char change
				if (JoyCharIsLower (&newch, pTES))
					JoyCharToUpper (&newch, &newch, pTES);
				else
					JoyCharToLower (&newch, &newch, pTES);
			}
			else
			{	// register change
				pTES->UpperRegister = !pTES->UpperRegister;
			}
		}
		else
		{	// check register
			if (pTES->UpperRegister)
				JoyCharToUpper (&newch, &newch, pTES);
			else
				JoyCharToLower (&newch, &newch, pTES);
		}

		if (strcmp (newch.enc, ch.enc) != 0)
		{	// new char is different, put it in
			if (len)
			{	// change current -- this is messy with utf8
				int l = len - ch.len;
				if (pStr + l - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					// adjust other chars if necessary
					if (newch.len != ch.len)
						memmove (pStr + newch.len, pStr + ch.len, l + 1);

					memcpy (pStr, newch.enc, newch.len);
					len = l + newch.len;
					changed = TRUE;
				}
			}
			else
			{	// append
				if (pStr + len - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					memcpy (pStr, newch.enc, newch.len);
					pStr[newch.len] = '\0';
					len += newch.len;
					changed = TRUE;
				}
				else
				{	// does not fit
					PlayMenuSound (MENU_SOUND_FAILURE);
				}
			}
		}
	}
	
	if (PulsedInputState.menu[KEY_MENU_SELECT])
	{	// done entering
		pTES->Success = TRUE;
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_EDIT_CANCEL])
	{	// canceled entering
		pTES->Success = FALSE;
		return FALSE;
	}

	pTES->InsPt = pStr;

	if (changed && pTES->ChangeCallback)
	{
		if (!pTES->ChangeCallback (pTES))
		{	// changes not accepted - revert
			memcpy (pTES->BaseStr, pTES->CacheStr, pTES->MaxSize);
			pTES->InsPt = CacheInsPt;
			pTES->CursorPos = CacheCursorPos;

			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
		
	if (pTES->FrameCallback)
		return pTES->FrameCallback (pTES);

	return TRUE;
}