void idListWindow::UpdateList() {
	idStr str, strName;
	listItems.Clear();
	for( int i = 0; i < MAX_LIST_ITEMS; i++ ) {
		if( gui->State().GetString( va( "%s_item_%i", listName.c_str(), i ), "", str ) ) {
			if( str.Length() ) {
				listItems.Append( str );
			}
		} else {
			break;
		}
	}
	float vert = GetMaxCharHeight();
	int fit = textRect.h / vert;
	if( listItems.Num() < fit ) {
		scroller->SetRange( 0.0f, 0.0f, 1.0f );
	} else {
		scroller->SetRange( 0.0f, ( listItems.Num() - fit ) + 1.0f, 1.0f );
	}
	SetCurrentSel( gui->State().GetInt( va( "%s_sel_0", listName.c_str() ) ) );
	float value = scroller->GetValue();
	if( value > listItems.Num() - 1 ) {
		value = listItems.Num() - 1;
	}
	if( value < 0.0f ) {
		value = 0.0f;
	}
	scroller->SetValue( value );
	top = value;
	typedTime = 0;
	clickTime = 0;
	typed = "";
}
Esempio n. 2
0
const char *idListWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
	// need to call this to allow proper focus and capturing on embedded children
	const char *ret = idWindow::HandleEvent(event, updateVisuals);

	float vert = GetMaxCharHeight();
	int numVisibleLines = textRect.h / vert;

	int key = event->evValue;

	if ( event->evType == SE_KEY ) {
		if ( !event->evValue2 ) {
			// We only care about key down, not up
			return ret;
		}

		if ( key == K_MOUSE1 || key == K_MOUSE2 ) {
			// If the user clicked in the scroller, then ignore it
			if ( scroller->Contains(gui->CursorX(), gui->CursorY()) ) {
				return ret;
			}
		}

		if ( ( key == K_ENTER || key == K_KP_ENTER ) ) {
			RunScript( ON_ENTER );
			return cmd;
		}

		if ( key == K_MWHEELUP ) {
			key = K_UPARROW;
		} else if ( key == K_MWHEELDOWN ) {
			key = K_DOWNARROW;
		}

		if ( key == K_MOUSE1) {
			if (Contains(gui->CursorX(), gui->CursorY())) {
				int cur = ( int )( ( gui->CursorY() - actualY - pixelOffset ) / vert ) + top;
				if ( cur >= 0 && cur < listItems.Num() ) {
					if ( multipleSel && idKeyInput::IsDown( K_CTRL ) ) {
						if ( IsSelected( cur ) ) {
							ClearSelection( cur );
						} else {
							AddCurrentSel( cur );
						}
					} else {
						if ( IsSelected( cur ) && ( gui->GetTime() < clickTime + doubleClickSpeed ) ) {
							// Double-click causes ON_ENTER to get run
							RunScript(ON_ENTER);
							return cmd;
						}
						SetCurrentSel( cur );

						clickTime = gui->GetTime();
					}
				} else {
					SetCurrentSel( listItems.Num() - 1 );
				}
			}
		} else if ( key == K_UPARROW || key == K_PGUP || key == K_DOWNARROW || key == K_PGDN ) {
			int numLines = 1;

			if ( key == K_PGUP || key == K_PGDN ) {
				numLines = numVisibleLines / 2;
			}

			if ( key == K_UPARROW || key == K_PGUP ) {
				numLines = -numLines;
			}

			if ( idKeyInput::IsDown( K_CTRL ) ) {
				top += numLines;
			} else {
				SetCurrentSel( GetCurrentSel() + numLines );
			}
		} else {
			return ret;
		}
	} else if ( event->evType == SE_CHAR ) {
		if ( !idStr::CharIsPrintable(key) ) {
			return ret;
		}

		if ( gui->GetTime() > typedTime + 1000 ) {
			typed = "";
		}
		typedTime = gui->GetTime();
		typed.Append( key );

		for ( int i=0; i<listItems.Num(); i++ ) {
			if ( idStr::Icmpn( typed, listItems[i], typed.Length() ) == 0 ) {
				SetCurrentSel( i );
				break;
			}
		}

	} else {
		return ret;
	}

	if ( GetCurrentSel() < 0 ) {
		SetCurrentSel( 0 );
	}

	if ( GetCurrentSel() >= listItems.Num() ) {
		SetCurrentSel( listItems.Num() - 1 );
	}

	if ( scroller->GetHigh() > 0.0f ) {
		if ( !idKeyInput::IsDown( K_CTRL ) ) {
			if ( top > GetCurrentSel() - 1 ) {
				top = GetCurrentSel() - 1;
			}
			if ( top < GetCurrentSel() - numVisibleLines + 2 ) {
				top = GetCurrentSel() - numVisibleLines + 2;
			}
		}

		if ( top > listItems.Num() - 2 ) {
			top = listItems.Num() - 2;
		}
		if ( top < 0 ) {
			top = 0;
		}
		scroller->SetValue(top);
	} else {
		top = 0;
		scroller->SetValue(0.0f);
	}

	if ( key != K_MOUSE1 ) {
		// Send a fake mouse click event so onAction gets run in our parents
		const sysEvent_t ev = sys->GenerateMouseButtonEvent( 1, true );
		idWindow::HandleEvent(&ev, updateVisuals);
	}

	if ( currentSel.Num() > 0 ) {
		for ( int i = 0; i < currentSel.Num(); i++ ) {
			gui->SetStateInt( va( "%s_sel_%i", listName.c_str(), i ), currentSel[i] );
		}
	} else {
		gui->SetStateInt( va( "%s_sel_0", listName.c_str() ), 0 );
	}
	gui->SetStateInt( va( "%s_numsel", listName.c_str() ), currentSel.Num() );

	return ret;
}