示例#1
0
void SFZReader::read(const char* text, unsigned int length)
{
	const char* p = text;
	const char* end = text + length;
	char c;

	SFZRegion curGroup;
	SFZRegion curRegion;
	SFZRegion* buildingRegion = NULL;
	bool inControl = false;
    std::string defaultPath;

	while (p < end) {
		// We're at the start of a line; skip any whitespace.
		while (p < end) {
			c = *p;
			if (c != ' ' && c != '\t')
				break;
			p += 1;
			}
		if (p >= end)
			break;

		// Check if it's a comment line.
		if (c == '/') {
			// Skip to end of line.
			while (p < end) {
				c = *++p;
				if (c == '\n' || c == '\r')
					break;
				}
			p = handleLineEnd(p);
			continue;
			}

		// Check if it's a blank line.
		if (c == '\r' || c == '\n') {
			p = handleLineEnd(p);
			continue;
			}

		// Handle elements on the line.
		while (p < end) {
			c = *p;

			// Tag.
			if (c == '<')
            {
				p += 1;
				const char* tagStart = p;
                
				while (p < end)
                {
					c = *p++;
					if (c == '\n' || c == '\r')
                    {
						error("Unterminated tag");
						goto fatalError;
                    }
					else if (c == '>')
						break;
					}
				if (p >= end) {
					error("Unterminated tag");
					goto fatalError;
					}
				StringSlice tag(tagStart, p - 1);
				if (tag == "region")
                {
					if (buildingRegion && buildingRegion == &curRegion)
						finishRegion(&curRegion);
                    
					curRegion = curGroup;
					buildingRegion = &curRegion;
					inControl = false;
                }
				else if (tag == "group")
                {
					if (buildingRegion && buildingRegion == &curRegion)
						finishRegion(&curRegion);
                    
					curGroup.clear();
					buildingRegion = &curGroup;
					inControl = false;
                }
				else if (tag == "control")
                {
					if (buildingRegion && buildingRegion == &curRegion)
						finishRegion(&curRegion);
                    
					curGroup.clear();
					buildingRegion = NULL;
					inControl = true;
					}
				else
					error("Illegal tag");
				}

			// Comment.
			else if (c == '/')
            {
				// Skip to end of line.
				while (p < end)
                {
					c = *p;
					if (c == '\r' || c == '\n')
						break;
					p += 1;
                }
            }

			// Parameter.
			else {
				// Get the parameter name.
				const char* parameterStart = p;
				while (p < end) {
					c = *p++;
					if (c == '=' || c == ' ' || c == '\t' || c == '\r' || c == '\n')
						break;
					}
				if (p >= end || c != '=')
                {
					error("Malformed parameter");
					goto nextElement;
                }
				StringSlice opcode(parameterStart, p - 1);
				if (inControl) {
					if (opcode == "default_path")
						p = readPathInto(&defaultPath, p, end);
					else {
						const char* valueStart = p;
						while (p < end) {
							c = *p;
							if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
								break;
							p++;
							}
						std::string value(valueStart, p - valueStart);
						std::string fauxOpcode = std::string(opcode.start, opcode.length()) + std::string(" (in <control>)");
						sound->addUnsupportedOpcode(fauxOpcode);
						}
					}
				else if (opcode == "sample") {
                    std::string path;
					p = readPathInto(&path, p, end);
					if (path != "") {
						if (buildingRegion)
							buildingRegion->sample = sound->addSample(path, defaultPath);
						else
							error("Adding sample outside a group or region");
						}
					else
						error("Empty sample path");
					}
				else {
					const char* valueStart = p;
					while (p < end) {
						c = *p;
						if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
							break;
						p++;
                    }
                    std::string value(valueStart, p - valueStart);
                    
                    std::istringstream ss(value);
                    
					if (buildingRegion == NULL)
						error("Setting a parameter outside a region or group");
					else if (opcode == "lokey")
						buildingRegion->lokey = keyValue(value);
					else if (opcode == "hikey")
						buildingRegion->hikey = keyValue(value);
					else if (opcode == "key") {
						buildingRegion->hikey =
						buildingRegion->lokey =
						buildingRegion->pitch_keycenter =
							keyValue(value);
						}
					else if (opcode == "lovel")
                    {
                        int i;
                        ss >> i;
						buildingRegion->lovel = i;
					} else if (opcode == "hivel") {
                        int i;
                        ss >> i;

						buildingRegion->hivel = i;
                    }
					else if (opcode == "trigger")
						buildingRegion->trigger = (SFZRegion::Trigger) triggerValue(value);
					else if (opcode == "group") {
                        unsigned long l;
                        ss >> l;
                        
						buildingRegion->group = l;
                    }
/*************************************************************************
	Handler for when non-printable keys are typed.
*************************************************************************/
void MultiLineEditbox::onKeyDown(KeyEventArgs& e)
{
	// base class processing
	Window::onKeyDown(e);

	if (hasInputFocus() && !isReadOnly())
	{
		WindowEventArgs args(this);
		switch (e.scancode)
		{
		case Key::LeftShift:
		case Key::RightShift:
			if (getSelectionLength() == 0)
			{
				d_dragAnchorIdx = getCaratIndex();
			}
			break;

		case Key::Backspace:
			handleBackspace();
			break;

		case Key::Delete:
			handleDelete();
			break;

		case Key::Return:
		case Key::NumpadEnter:
			handleNewLine(e.sysKeys);
			break;

		case Key::ArrowLeft:
			if (e.sysKeys & Control)
			{
				handleWordLeft(e.sysKeys);
			}
			else
			{
				handleCharLeft(e.sysKeys);
			}
			break;

		case Key::ArrowRight:
			if (e.sysKeys & Control)
			{
				handleWordRight(e.sysKeys);
			}
			else
			{
				handleCharRight(e.sysKeys);
			}
			break;

		case Key::ArrowUp:
			handleLineUp(e.sysKeys);
			break;

		case Key::ArrowDown:
			handleLineDown(e.sysKeys);
			break;

		case Key::Home:
			if (e.sysKeys & Control)
			{
				handleDocHome(e.sysKeys);
			}
			else
			{
				handleLineHome(e.sysKeys);
			}
			break;

		case Key::End:
			if (e.sysKeys & Control)
			{
				handleDocEnd(e.sysKeys);
			}
			else
			{
				handleLineEnd(e.sysKeys);
			}
			break;

        // default case is now to leave event as (possibly) unhandled.
        default:
            return;
		}

		e.handled = true;
	}

}