SidebarLibrary.Menus.MenuControl.Recalculate C# (CSharp) Method

Recalculate() protected method

protected Recalculate ( ) : void
return void
		protected void Recalculate()
		{
			int length;

			if (_direction == Direction.Horizontal)
				length = this.Width;
			else
				length = this.Height;

			// Is there space for any commands?
			if (length > 0)
			{
				// Count the number of rows needed
				int rows = 0;

				// Number of items on this row
				int columns = 0;

				// Create a collection of drawing objects
				_drawCommands = new ArrayList();

				// Minimum length is a gap on either side of the text
				int cellMinLength = _lengthGap * 2;

				// Each cell is as broad as the whole control
				// int cellBreadth = this.Height;

				// Accumulate starting position of each cell
				int lengthStart = 0;

				// If the chevron is already displayed then reduce length by its length
				if (_chevronStartCommand != null)
					length -= cellMinLength + _chevronLength;

				// Assume chevron is not needed by default
				_chevronStartCommand = null;

				using(Graphics g = this.CreateGraphics())
				{
					// Count the item we are processing
					int index = 0;

					foreach(MenuCommand command in _menuCommands)
					{
						// Give the command a chance to update its state
						command.OnUpdate(EventArgs.Empty);

						// Ignore items that are marked as hidden
						if (!command.Visible)
							continue;

						int cellLength = 0;

						// Is this a separator?
						if (command.Text == "-")
							cellLength = _separatorWidth;
						else
						{
							// Calculate the text width of the cell
							SizeF dimension = g.MeasureString(command.Text, this.Font);

							// Always add 1 to ensure that rounding is up and not down
							cellLength = cellMinLength + (int)dimension.Width + 1;
						}

						Rectangle cellRect;

						// Create a new position rectangle
						if (_direction == Direction.Horizontal)
							cellRect = new Rectangle(lengthStart, _rowHeight * rows, cellLength, _rowHeight);
						else
							cellRect = new Rectangle(_rowWidth * rows, lengthStart, _rowWidth, cellLength);

						lengthStart += cellLength;
						columns++;

						// If this item is overlapping the control edge and it is not the first
						// item on the line then we should wrap around to the next row.
						if ((lengthStart > length) && (columns > 1))
						{
							if (_multiLine)
							{
								// Move to next row
								rows++;

								// Reset number of items on this column
								columns = 1;

								// Reset starting position of next item
								lengthStart = cellLength;

								// Reset position of this item
								if (_direction == Direction.Horizontal)
								{
									cellRect.X = 0;
									cellRect.Y += _rowHeight;
								}
								else
								{
									cellRect.X += _rowWidth;
									cellRect.Y = 0;
								}
							}
							else
							{
								// Is a tracked item being make invisible
								if (index <= _trackItem)
								{
									// Need to remove tracking of this item
									_trackItem = -1;
								}

								// Remember which item is first for the chevron submenu
								_chevronStartCommand = command;

								if (_direction == Direction.Horizontal)
								{
									cellRect.Y = 0;
									cellRect.Width = cellMinLength + _chevronLength;
									cellRect.X = this.Width - cellRect.Width;
									cellRect.Height = _rowHeight;
								}
								else
								{
									cellRect.X = 0;
									cellRect.Height = cellMinLength + _chevronLength;
									cellRect.Y = this.Height - (cellMinLength + _chevronLength);
									cellRect.Width = _rowWidth;
								}

								// Create a draw command for this chevron
								_drawCommands.Add(new DrawCommand(cellRect));

								// Exit, do not add the current item or any afterwards
								break;
							}
						}

						// Create a drawing object
						_drawCommands.Add(new DrawCommand(command, cellRect));

						index++;
					}
				}

				if (_direction == Direction.Horizontal)
				{
					int controlHeight = (rows + 1) * _rowHeight;

					// Ensure the control is the correct height
					if (this.Height != controlHeight)
						this.Height = controlHeight;
				}
				else
				{
					int controlWidth = (rows + 1) * _rowWidth;

					// Ensure the control is the correct width
					if (this.Width != controlWidth)
						this.Width = controlWidth;
				}
			}
		}