void ElementDataGridRow::RemoveChildren(int first_row_removed, int num_rows_removed)
{
	if (num_rows_removed == -1)
	{
		num_rows_removed = (int)children.size() - first_row_removed;
	}

	// prevent relayout of the document while removing rows
	Core::ElementDocument* document = parent_grid->GetOwnerDocument();
	document->LockLayout(true);

	for (int i = num_rows_removed - 1; i >= 0; i--)
	{
		children[first_row_removed + i]->RemoveChildren();
		parent_grid->RemoveRows(children[first_row_removed + i]->GetTableRelativeIndex());
	}

	children.erase(children.begin() + first_row_removed, children.begin() + (first_row_removed + num_rows_removed));
    for (int i = first_row_removed; i < (int) children.size(); i++)
	{
		children[i]->SetChildIndex(i);
		children[i]->DirtyTableRelativeIndex();
	}

	document->LockLayout(false);

	Rocket::Core::Dictionary parameters;
	parameters.Set("first_row_removed", GetChildTableRelativeIndex(first_row_removed));
	parameters.Set("num_rows_removed", num_rows_removed);
	parent_grid->DispatchEvent("rowremove", parameters);
}
void ElementDataGridRow::RemoveChildren(int first_row_removed, int num_rows_removed)
{
	if (num_rows_removed == -1)
	{
		num_rows_removed = (int)children.size() - first_row_removed;
	}

	for (int i = num_rows_removed - 1; i >= 0; i--)
	{
		children[first_row_removed + i]->RemoveChildren();
		parent_grid->RemoveRows(children[first_row_removed + i]->GetTableRelativeIndex());
	}

	children.erase(children.begin() + first_row_removed, children.begin() + (first_row_removed + num_rows_removed));
    for (int i = first_row_removed; i < (int) children.size(); i++)
	{
		children[i]->SetChildIndex(i);
		children[i]->DirtyTableRelativeIndex();
	}

	Rocket::Core::Dictionary parameters;
	parameters.Set("first_row_removed", GetChildTableRelativeIndex(first_row_removed));
	parameters.Set("num_rows_removed", num_rows_removed);
	parent_grid->DispatchEvent("rowremove", parameters);
}
void ElementDataGridRow::ChangeChildren(int first_row_changed, int num_rows_changed)
{
	for (int i = first_row_changed; i < first_row_changed + num_rows_changed; i++)
		children[i]->DirtyCells();

	Rocket::Core::Dictionary parameters;
	parameters.Set("first_row_changed", GetChildTableRelativeIndex(first_row_changed));
	parameters.Set("num_rows_changed", num_rows_changed);
	parent_grid->DispatchEvent("rowchange", parameters);
}
// Adds children underneath this row, and fetches their contents (and possible
// children) from the row's data source.
void ElementDataGridRow::AddChildren(int first_row_added, int num_rows_added)
{
	if (first_row_added == -1)
	{
		first_row_added = (int)children.size();
	}

	// prevent relayout of the document while adding rows
	Core::ElementDocument* document = parent_grid->GetOwnerDocument();
	document->LockLayout(true);

	// We need to make a row for each new child, then pass through the cell
	// information and the child's data source (if one exists.)
	if (data_source)
	{
		for (int i = 0; i < num_rows_added; i++)
		{
			int row_index = first_row_added + i;

			// Make a new row:
			ElementDataGridRow* new_row = parent_grid->AddRow(this, row_index);
			children.insert(children.begin() + row_index, new_row);

			if (!row_expanded)
			{
				new_row->SetProperty("display", "none");
			}
		}

		for (int i = first_row_added + num_rows_added; i < (int)children.size(); i++)
		{
			children[i]->SetChildIndex(i);
			children[i]->DirtyTableRelativeIndex();
		}

		if (parent_row)
		{
			parent_row->ChildChanged(child_index);
		}
	}

	document->LockLayout(false);

	RefreshChildDependentCells();
	DirtyRow();

	Rocket::Core::Dictionary parameters;
	parameters.Set("first_row_added", GetChildTableRelativeIndex(first_row_added));
	parameters.Set("num_rows_added", num_rows_added);
	parent_grid->DispatchEvent("rowadd", parameters);
}
Example #5
0
// Sets the index of the selection. If the new index lies outside of the bounds, it will be clamped.
void WidgetDropDown::SetSelection(int selection, bool force)
{
	Rocket::Core::String new_value;

	if (selection < 0 ||
		selection >= (int) options.size())
	{
		selection = -1;
	}
	else
	{
		new_value = options[selection].GetValue();
	}

	if (force ||
		selection != selected_option ||
		value != new_value)
	{
		selected_option = selection;
		value = new_value;

		Rocket::Core::String value_rml;
		if (selected_option >= 0)
			options[selected_option].GetElement()->GetInnerRML(value_rml);

		value_element->SetInnerRML(value_rml);
		value_layout_dirty = true;

		Rocket::Core::Dictionary parameters;
		parameters.Set("value", value);
		parent_element->DispatchEvent("change", parameters);
	}
}
void ElementTabSet::SetActiveTab(int tab_index)
{
	// Update display if the tab has changed
	if (tab_index != active_tab)
	{
		Core::Element* tabs = GetChildByTag("tabs");
		Core::Element* old_tab = tabs->GetChild(active_tab);
		Core::Element* new_tab = tabs->GetChild(tab_index);

		if (old_tab)
			old_tab->SetPseudoClass("selected", false);
		if (new_tab)
			new_tab->SetPseudoClass("selected", true);

		Core::Element* windows = GetChildByTag("panels");
		Core::Element* old_window = windows->GetChild(active_tab);
		Core::Element* new_window = windows->GetChild(tab_index);

		if (old_window)
			old_window->SetProperty("display", "none");
		if (new_window)
			new_window->SetProperty("display", "inline-block");

		active_tab = tab_index;

		Rocket::Core::Dictionary parameters;
		parameters.Set("tab_index", active_tab);
		DispatchEvent("tabchange", parameters);
	}
}
// Submits the form.
void ElementForm::Submit(const Rocket::Core::String& name, const Rocket::Core::String& submit_value)
{
	Rocket::Core::Dictionary values;
	if (name.Empty())
		values.Set("submit", submit_value);
	else
		values.Set(name, submit_value);

	Core::ElementList form_controls;
	Core::ElementUtilities::GetElementsByTagName(form_controls, this, "input");
	Core::ElementUtilities::GetElementsByTagName(form_controls, this, "textarea");
	Core::ElementUtilities::GetElementsByTagName(form_controls, this, "select");
	Core::ElementUtilities::GetElementsByTagName(form_controls, this, "dataselect");

	for (size_t i = 0; i < form_controls.size(); i++)
	{
		ElementFormControl* control = rocket_dynamic_cast< ElementFormControl* >(form_controls[i]);
		if (!control)
			continue;

		// Skip disabled controls.
		if (control->IsDisabled())
			continue;

		// Only process controls that should be submitted.
		if (!control->IsSubmitted())
			continue;

		Rocket::Core::String control_name = control->GetName();
		Rocket::Core::String control_value = control->GetValue();

		// Skip over unnamed form controls.
		if (control_name.Empty())
			continue;

		// If the item already exists, append to it.
		Rocket::Core::Variant* value = values.Get(control_name);
		if (value != NULL)
			value->Set(value->Get< Rocket::Core::String >() + ", " + control_value);
		else
			values.Set< Rocket::Core::String >(control_name, control_value);					
	}

	DispatchEvent("submit", values);
}
Example #8
0
// Checks for necessary functional changes in the control as a result of changed attributes.
bool InputTypeCheckbox::OnAttributeChange(const Core::AttributeNameList& changed_attributes)
{
	// Check if maxlength has been defined.
	if (changed_attributes.find("checked") != changed_attributes.end())
	{
		bool checked = element->HasAttribute("checked");
		element->SetPseudoClass("checked", checked);

		Rocket::Core::Dictionary parameters;
		parameters.Set("value", Rocket::Core::String(checked ? GetValue() : ""));
		element->DispatchEvent("change", parameters);
	}

	return true;
}
// Adds a column to the table.
void ElementDataGrid::AddColumn(const Rocket::Core::String& fields, const Rocket::Core::String& formatter, float initial_width, Core::Element* header_element)
{
	Column column;
	Rocket::Core::StringUtilities::ExpandString(column.fields, fields);
	column.formatter = DataFormatter::GetDataFormatter(formatter);
	column.header = header;
	column.current_width = initial_width;
	column.refresh_on_child_change = false;

	// The header elements are added to the header row at the top of the table.
	if (header_element)
	{
		header_element->SetProperty("display", "inline-block");

		// Push all the width properties from the column onto the header element.
		Rocket::Core::String width = header_element->GetAttribute<Rocket::Core::String>("width", "100%");
		header_element->SetProperty("width", width);

		header->AppendChild(header_element);
	}

	// Add the fields that this column requires to the concatenated string of all column fields.
	for (size_t i = 0; i < column.fields.size(); i++)
	{
		// Don't append the depth or num_children fields, as they're handled by the row.
		if (column.fields[i] == Rocket::Controls::DataSource::NUM_CHILDREN)
		{
			column.refresh_on_child_change = true;
		}
		else if (column.fields[i] != Rocket::Controls::DataSource::DEPTH)
		{
			if (!column_fields.Empty())
			{
				column_fields.Append(",");
			}
			column_fields.Append(column.fields[i]);
		}
	}

	columns.push_back(column);

	Rocket::Core::Dictionary parameters;
	parameters.Set("index", (int)(columns.size() - 1)); 
	DispatchEvent("columnadd", parameters);
}
Example #10
0
void RocketModule::keyEvent( int contextId, int key, bool pressed )
{
	// DEBUG
#if 0
	if( key >= 32 && key <= 126 )
		Com_Printf("**KEYEVENT CHAR %c\n", key & 0xff );
	else
		Com_Printf("**KEYEVENT KEY %d\n", key );
#endif

	if( key == K_MOUSE1DBLCLK )
		return; // Rocket handles double click internally

	auto *context = contextForId( contextId );
	Element *element = context->GetFocusElement();

	int mod = KeyConverter::getModifiers();

	// send the blur event, to the current focused element, when ESC key is pressed
	if( ( key == K_ESCAPE ) && element )
		element->Blur();

	if( element && ( element->GetTagName() == "keyselect" ) )
	{
		if( pressed )
		{
			Rocket::Core::Dictionary parameters;
			parameters.Set( "key", key );
			element->DispatchEvent( "keyselect", parameters );
		}
	}
	else if( key >= K_MOUSE1 && key <= K_MOUSE8 ) // warsow sends mousebuttons as keys
	{
		if( pressed )
			context->ProcessMouseButtonDown( key-K_MOUSE1, mod );
		else
			context->ProcessMouseButtonUp( key-K_MOUSE1, mod );
	}
	else if( key == K_MWHEELDOWN ) // and ditto for wheel
	{
		context->ProcessMouseWheel( 1, mod );
	}
	else if( key == K_MWHEELUP )
	{
		context->ProcessMouseWheel( -1, mod );
	}
	else
	{
		if( ( key == K_A_BUTTON ) || ( key == K_DPAD_CENTER ) )
		{
			if( pressed )
				context->ProcessMouseButtonDown( 0, mod );
			else
				context->ProcessMouseButtonUp( 0, mod );
		}
		else
		{
			int rkey = KeyConverter::toRocketKey( key );

			if( key == K_B_BUTTON )
			{
				rkey = Rocket::Core::Input::KI_ESCAPE;
				if( element )
					element->Blur();
			}

			if( rkey != 0 )
			{
				if( pressed )
					context->ProcessKeyDown( Rocket::Core::Input::KeyIdentifier( rkey ), mod );
				else
					context->ProcessKeyUp( Rocket::Core::Input::KeyIdentifier( rkey ), mod );
			}
		}
	}
}
Example #11
0
void RocketModule::keyEvent( int key, bool pressed )
{
	KeyConverter keyconv;
	int mod;

	// DEBUG
#if 0
	if( key >= 32 && key <= 126 )
		Com_Printf("**KEYEVENT CHAR %c\n", key & 0xff );
	else
		Com_Printf("**KEYEVENT KEY %d\n", key );
#endif

	mod = keyconv.getModifiers();

	// warsow sends mousebuttons as keys
	if( key >= K_MOUSE1 && key <= K_MOUSE8 )
	{
		if( pressed )
			context->ProcessMouseButtonDown( key-K_MOUSE1, mod );
		else
			context->ProcessMouseButtonUp( key-K_MOUSE1, mod );
	}
	// and ditto for wheel
	else if( key == K_MWHEELDOWN )
	{
		context->ProcessMouseWheel( KI_MWHEELDOWN, mod );
	}
	else if( key == K_MWHEELUP )
	{
		context->ProcessMouseWheel( KI_MWHEELUP, mod );
	}
	else
	{
		Element *element = context->GetFocusElement();

		// send the blur event, to the current focused element,
		// when ESC key is pressed
		if( ( key == K_ESCAPE ) && element )
			element->Blur();

		if( pressed && element && ( element->GetTagName() == "keyselect" ) )
		{
			Rocket::Core::Dictionary parameters;
			parameters.Set( "key", key );
			element->DispatchEvent( "keyselect", parameters );
		}
		else
		{
			int rkey = keyconv.toRocketKey( key );

			if( rkey != 0 )
			{
				if( pressed )
					context->ProcessKeyDown( Rocket::Core::Input::KeyIdentifier( rkey ), keyconv.getModifiers() );
				else
					context->ProcessKeyUp( Rocket::Core::Input::KeyIdentifier( rkey ), keyconv.getModifiers() );
			}
		}
	}
}
TEST_F( libRocketDataGridTest, UIDataViewList )
{
  Point2i pos1(60,25);
  std::string doc_file1 = "dataview.rml";

  UIDataViewList store1;
  EXPECT_EQ( true, store1.set_context(&this->desktop) );
  EXPECT_EQ( true, store1.load_document_file( doc_file1 ) )
  << this->test_set() << " object should not be invalid; is the context and document file valid?";

  // Ensure that the visual debugger's beacon (err icon) appears on-screen.
  Rocket::Core::Log::Message( Rocket::Core::Log::LT_ASSERT, "Hello, world!" );

  this->model.reset( new CardsPageDataSource("cards_db") );
  this->db.reset( new CardCollection() );
  EXPECT_TRUE( model != nullptr );
  EXPECT_TRUE( db != nullptr );

  EXPECT_EQ( true, db->load_db() )
  << "Could not initialize nom::CardsPageDataSource data interface.";

  CardList deck;
  CardList cards = db->cards();

  // Load in the entire cards database
  for( auto itr = cards.begin(); itr != cards.end(); ++itr )
  {
    deck.push_back( *itr );
  }

  // Deck of cards for the data source
  model->append_cards( deck );

  store1.show();

  EXPECT_TRUE( store1.set_column_title(1, "CARDS P. " + std::to_string(model->page() + 1) ) );

  EXPECT_EQ( true, store1.visible() );
  EXPECT_EQ( pos1, store1.position() );

  // Default values sanity

  EXPECT_EQ( "cards", model->table_name() );

  EXPECT_EQ( 11, model->per_page() );
  EXPECT_EQ( 0, model->page() );

  EXPECT_EQ( 10, model->map_page_row( 10, 0 ) )
  << "Selection should be between 0..11";

  EXPECT_EQ( 2, model->map_page_row( 13, 1 ) )
  << "Selection should be between 0..11";

  EXPECT_EQ( 10, model->map_page_row( 21, 1 ) )
  << "Selection should be between 0..11";

  EXPECT_EQ( "CARDS P. 1", store1.column_title(1) );
  EXPECT_EQ( "NUM.", store1.column_title(2) );

  store1.register_event_listener( store1.document(), "keydown", new nom::UIEventListener( [&]
    ( Rocket::Core::Event& ev ) { on_keydown( ev, &store1, db, model, this->phand ); }
  ));

  store1.register_event_listener( store1.document(), "mouseup", new nom::UIEventListener( [&]
    ( Rocket::Core::Event& ev ) { on_mouseup( ev, &store1, db, model, this->phand ); }
  ));

  // Synthesized user input events; we hope to capture these before the end of
  // the first frame
  Rocket::Core::Element* target = nullptr;
  Rocket::Core::Dictionary lclick;
  Rocket::Core::Dictionary rclick;
  lclick.Set("button","0"); // Left click
  rclick.Set("button","1"); // Left click

  // We must update the context before our cards model is filled
  this->desktop.update();

  target = store1.document()->GetElementById("Geezard");
  if( target ) {
    target->DispatchEvent("mouseup", lclick);
    // Should have zero cards remaining
  }

  target = store1.document()->GetElementById("Red Bat");
  if( target ) {
    target->DispatchEvent("mouseup", lclick);
    target->DispatchEvent("mouseup", lclick);
    target->DispatchEvent("mouseup", lclick);
    // Should have one cards remaining
  }

  target = store1.document()->GetElementById("Red Bat");
  if( target ) {
    target->DispatchEvent("mouseup", rclick);
    // Should have two cards remaining
  }

  target = store1.document()->GetElementById("Cockatrice");
  if( target ) {
    target->DispatchEvent("mouseup", lclick);
    target->DispatchEvent("mouseup", lclick);
    target->DispatchEvent("mouseup", lclick);
    // Should have zero cards remaining
  }

  // NOM_LOG_INFO( NOM_LOG_CATEGORY_TEST, store1.dump() );

  EXPECT_EQ( NOM_EXIT_SUCCESS, this->on_run() );
  EXPECT_TRUE( this->compare() );
}