/*!	\brief		Sets all items of all menus in this view to send messages to "this".
 *		\details		This is a recursive function; it receives the menu to work on. It
 *						starts with NULL, in which case it calls itself recursively on
 *						fDateSelector menu.
 */
void CalendarControl::UpdateTargets( BMenu* menuIn )
{
	BMenuItem* item = NULL;
	int i, limit;
	
	if ( !menuIn )
	{
		// First run. Search the children and run recursively on each.
		UpdateTargets( fDateSelector );
	}
	else
	{
		// Some of the internal runs. Updating subsequent targets.
		limit = menuIn->CountItems();
		for ( i = 0; i < limit; ++i )
		{
			if ( ( item = menuIn->ItemAt( i ) ) != NULL )
			{
				if ( item->Submenu() ) {
					// If the item controls a submenu, descending there
					UpdateTargets( item->Submenu() );
				} else {
					item->SetTarget( this );
				}
			}
		}	// <-- end of "for (all items in the submenu)"
	}
}	// <-- end of function CalendarControl::UpdateTargets
Пример #2
0
void DynamicObject::Create(Unit* caster, Spell* pSpell, float x, float y, float z, uint32 duration, float radius)
{
	Object::_Create(caster->GetMapId(), x, y, z, 0);
	if(pSpell->g_caster)
	{
		m_parentSpell = pSpell;
	}
	if(pSpell->p_caster == NULL)
	{
		// try to find player caster here
		if(caster->IsPlayer())
			p_caster = TO< Player* >(caster);
	}
	else
		p_caster = pSpell->p_caster;

	m_spellProto = pSpell->GetProto();
	SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());

	SetEntry(m_spellProto->Id);
	m_uint32Values[DYNAMICOBJECT_BYTES] = 0x01eeeeee;
	m_uint32Values[DYNAMICOBJECT_SPELLID] = m_spellProto->Id;

	m_floatValues[DYNAMICOBJECT_RADIUS] = radius;
	m_position.x = x; //m_floatValues[DYNAMICOBJECT_POS_X]  = x;
	m_position.y = y; //m_floatValues[DYNAMICOBJECT_POS_Y]  = y;
	m_position.z = z; //m_floatValues[DYNAMICOBJECT_POS_Z]  = z;


	m_aliveDuration = duration;
	u_caster = caster;
	m_faction = caster->m_faction;
	m_factionDBC = caster->m_factionDBC;
	m_phase = caster->GetPhase();

	if(pSpell->g_caster)
		PushToWorld(pSpell->g_caster->GetMapMgr());
	else
		PushToWorld(caster->GetMapMgr());

	if(caster->dynObj != NULL)
	{
		//expires
		caster->dynObj->Remove();
	}
	caster->dynObj = this;

	//sEventMgr.AddEvent(this, &DynamicObject::UpdateTargets, EVENT_DYNAMICOBJECT_UPDATE, 100, 0,EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);
	UpdateTargets();
}
Пример #3
0
//-----------------------------------------------
void CSingleTG::Serialize(TSerialize ser)
{
	//workaround serialization requested by design & RnD
	m_idSerializeTarget = m_lockedTarget;
	m_fSerializeProgress = m_fStareTime;
	ser.Value("m_idSerializeTarget", m_idSerializeTarget);
	ser.Value("m_fSerializeProgress", m_fSerializeProgress);

	if(ser.IsReading())
	{
		m_iSerializeIgnoreUpdate = 3;
		UpdateTargets();
	}
}
/*!	
 *	\brief			Internal function that creates a menu with month names.
 *	\param[in]	listOfMonths	List of months for a given year.
 *	\returns		The created BMenu.
 *	\remarks		Deletion and deallocation of the created menu is in
 *					responcibility of the caller.
 */
BPopUpMenu* CalendarControl::CreateMonthsMenu( map<int, DoubleNames> &listOfMonths )
{
	BMessage* message = NULL;
	BMenuItem* item = NULL;
	BString monthName;
	BPopUpMenu* toReturn = new BPopUpMenu("Months list");
	
	if (!toReturn) {
		/* Panic! */
		fLastError = B_NO_MEMORY; 
		return NULL;
	}
	toReturn->SetLabelFromMarked(true);
	toReturn->SetRadioMode(true);
	BFont font(be_plain_font);
	toReturn->SetFont(&font, B_FONT_FAMILY_AND_STYLE);
		
	int limit = listOfMonths.size();
	
	for (int i = 1; i <= limit; ++i ) {
		message = new BMessage( kMonthChanged );
		if ( !message ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return NULL;
		}
		if ( B_OK != message->AddInt8( "Month", ( int8 )i ) ) { 	//< Number of selected month in the year
			// Panic!
			exit(5);
		}
		monthName = listOfMonths[ i ].longName;
		item = new BMenuItem( monthName.String(), message );
		if (!item) { 
			/* Panic! */ 
			fLastError = B_NO_MEMORY; 
			return NULL;
		}
		if ( i == this->fRepresentedTime.tm_mon )
		{
			item->SetMarked(true);
		}
		toReturn->AddItem(item);
	}
	UpdateTargets( toReturn );
	return toReturn;
}
/*!	
 *	\brief
 *	\param[in]	year	The current year
 *	\returns		The created BMenu.
 *	\remarks		It's up to the caller to delete this menu!
 */
BPopUpMenu* CalendarControl::CreateYearsMenu( int yearIn )
{
	BPopUpMenu* toReturn = new BPopUpMenu("Years list");
	BMessage* message = NULL;
	BMenuItem* item = NULL;
	BString yearName;
	if (!toReturn) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return NULL;
	}
	toReturn->SetLabelFromMarked(true);
	toReturn->SetRadioMode(true);
	for ( int i = yearIn - YEARS_UP_AND_DOWN; 
			i <= yearIn + YEARS_UP_AND_DOWN; 
			++i )
	{
		message = new BMessage( kYearChanged );
		if ( !message )
		{
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return NULL;
		}
		if ( B_OK != message->AddInt32( "Year", i ) )
		{
			exit(5);	
		}
		yearName.Truncate( 0 );
		yearName << i;
		item = new BMenuItem( yearName.String(), message );
		if ( !item ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return NULL;
		}
		item->SetTarget( this );
		if ( i == yearIn ) {
			item->SetMarked( true );
		}
		toReturn->AddItem( item );
	}
	UpdateTargets( toReturn );
	return toReturn;
}	// <-- end of function CalendarControl::CreateYearsMenu
/*!	
	\brief			Sets up the view color and calls this view's children.
*/
void CalendarControl::AttachedToWindow() {
	
	// Get the view color of the father
	if ( Parent() ) {
		SetViewColor( Parent()->ViewColor() );
	}
	// Attach to window both current view and all of its children
	BControl::AttachedToWindow();
	
	// This view should respond to the messages - thus the Looper must know it
	BLooper* looper = ( BLooper* )Looper();
	if ( looper && looper->LockLooper() ) {
		looper->AddHandler( ( BHandler* )this );
		looper->UnlockLooper();
	}
	
	UpdateTargets( fDateSelector );
	
	this->InvalidateLayout();
	this->Relayout();
	this->Invalidate();
}
Пример #7
0
void DynamicObject::Create(Object* caster, Spell* pSpell, float x, float y, float z, int32 duration, float radius)
{
    // Call the object create function
    Object::_Create(caster->GetMapId(), x, y, z, 0.0f);
    casterGuid = caster->GetGUID();
    if(!caster->IsPlayer() && pSpell->p_caster)
        casterGuid = pSpell->p_caster->GetGUID();

    m_spellProto = pSpell->m_spellInfo;
    SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());

    m_uint32Values[DYNAMICOBJECT_BYTES] = 0x01;
    m_uint32Values[OBJECT_FIELD_ENTRY] = m_spellProto->Id;
    m_uint32Values[DYNAMICOBJECT_SPELLID] = m_spellProto->Id;

    m_floatValues[DYNAMICOBJECT_RADIUS] = radius;
    m_position.x = x; //m_floatValues[DYNAMICOBJECT_POS_X]  = x;
    m_position.y = y; //m_floatValues[DYNAMICOBJECT_POS_Y]  = y;
    m_position.z = z; //m_floatValues[DYNAMICOBJECT_POS_Z]  = z;
    m_uint32Values[DYNAMICOBJECT_CASTTIME] = getMSTime();

    m_aliveDuration = duration;
    m_factionTemplate = caster->m_factionTemplate;
    m_faction = caster->m_faction;
    SetPhaseMask(caster->GetPhaseMask());

    if(pSpell->g_caster)
        PushToWorld(pSpell->g_caster->GetMapMgr());
    else
        PushToWorld(caster->GetMapMgr());

    if(caster->IsUnit() && m_spellProto->IsChannelSpell())
    {
        TO_UNIT(caster)->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, GetGUID());
        TO_UNIT(caster)->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellProto->Id);
    }
    UpdateTargets(0);
}
Пример #8
0
//------------------------------------------------------
void CSingleTG::UpdateAutoAim(float frameTime)
{
	static IGameObjectSystem *pGameObjectSystem = gEnv->pGame->GetIGameFramework()->GetIGameObjectSystem();

	CActor *pOwner = m_pWeapon->GetOwnerActor();

	if(!pOwner || !pOwner->IsPlayer())
		return;

	// todo: use crosshair/aiming dir
	IMovementController *pMC = pOwner->GetMovementController();

	if(!pMC)
		return;

	// re-get targets from gametokens
	UpdateTargets();

	if(m_iSerializeIgnoreUpdate) 	//workaround serialization requested by design & RnD
	{
		m_iSerializeIgnoreUpdate--;

		if(m_iSerializeIgnoreUpdate <= 0)
		{
			m_iSerializeIgnoreUpdate = 0;
			StartLocking(m_idSerializeTarget, 0);
			m_fStareTime = m_fSerializeProgress;
		}

		return;
	}

	SMovementState state;
	pMC->GetMovementState(state);

	Vec3 aimDir = state.eyeDirection;
	Vec3 aimPos = state.eyePosition;

	float maxDistance = m_pShared->fireparams.autoaim_distance;

	ray_hit ray;

	IPhysicalEntity *pSkipEnts[10];
	int nSkipEnts = GetSkipEntities(m_pWeapon, pSkipEnts, 10);

	const int objects = ent_all;
	const int flags = rwi_stop_at_pierceable|rwi_ignore_back_faces;

	int result = gEnv->pPhysicalWorld->RayWorldIntersection(aimPos, aimDir * 2.f * maxDistance,
				 objects, flags, &ray, 1, pSkipEnts, nSkipEnts);

	bool hitValidTarget = false;
	IEntity *pEntity = 0;

	if(result && ray.pCollider)
	{
		pEntity = (IEntity *)ray.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);

		if(pEntity && IsValidAutoAimTarget(pEntity,ray.partid))
			hitValidTarget = true;
	}

	if(m_bLocked)
		m_autoaimTimeOut -= frameTime;

	if(hitValidTarget && (m_bLocked || m_bLocking))
	{
		int value = (int)((m_fStareTime / m_pShared->fireparams.autoaim_locktime)*100.0f);
	}

	if(hitValidTarget && ray.dist <= maxDistance)
	{
		if(m_bLocked)
		{
			if((m_lockedTarget != pEntity->GetId()) &&
					(m_lockedTarget != pEntity->UnmapAttachedChild(ray.partid)->GetId()) && m_autoaimTimeOut<=0.0f)
				StartLocking(pEntity->GetId(),ray.partid);
		}
		else
		{
			if(!m_bLocking || (m_lockedTarget!=pEntity->GetId()) && (m_lockedTarget!=pEntity->UnmapAttachedChild(ray.partid)->GetId()))
				StartLocking(pEntity->GetId(),ray.partid);
			else
				m_fStareTime += frameTime;
		}
	}
	else if(!hitValidTarget && m_bLocking)
	{
		m_pWeapon->RequestUnlock();
		Unlock();
	}
	else
	{
		// check if we're looking far away from our locked target
		if((m_bLocked && !(ray.dist<=maxDistance && CheckAutoAimTolerance(aimPos, aimDir))) || (!m_bLocked && m_lockedTarget && m_fStareTime != 0.0f))
		{
			if(!m_pShared->fireparams.autoaim_timeout)
			{
				m_pWeapon->RequestUnlock();
				Unlock();
			}
		}
	}

	if(m_bLocking && !m_bLocked && m_fStareTime >= m_pShared->fireparams.autoaim_locktime && m_lockedTarget)
		m_pWeapon->RequestLock(m_lockedTarget);
	else if(m_bLocked && hitValidTarget && m_lockedTarget!=pEntity->GetId() &&
			(m_lockedTarget != pEntity->UnmapAttachedChild(ray.partid)->GetId()))
		m_pWeapon->RequestLock(pEntity->GetId(),ray.partid);
	else if(m_bLocked)
	{
		// check if target still valid (can e.g. be killed)
		pEntity = gEnv->pEntitySystem->GetEntity(m_lockedTarget);

		if((pEntity && !IsValidAutoAimTarget(pEntity)) || (m_pShared->fireparams.autoaim_timeout && m_autoaimTimeOut<=0.0f))
		{
			m_pWeapon->RequestUnlock();
			Unlock();
		}
	}
}
/**
 * InitTree
 * initialize the instance tree for the first time: get all necessary 
 * information from the kad and construct root and classes group nodes
 *
 * @return          TRUE: on success
 *                  FALSE: else
 * @exception       -
 * @see             
*/
BOOL CInstanceTree::InitTree()
{
    GetStaticInfos();

    // create project node
    CXMLNode docRoot;
    CXMLNode projectNode;

    PROJ_MAN_ASSERT(m_pProjectManager);

    CString strProjNodeId;
    strProjNodeId = m_pProjectManager->GetProjectName()+_T(".")+ID_PATH_INSTANCEVIEW;
    CString strVersion;
    strVersion.Format(_T("%i"), PRODUCT_BUILD);
    if (  (!m_domDocument.GetDocNode(docRoot))
        ||(!m_domDocument.CreateNode(projectNode, CE_XMLTAG_NODE))
        ||(!docRoot.AppendChild(projectNode))
        ||(!projectNode.SetAttribute(CE_XMLATTR_TEXT, m_pProjectManager->GetProjectName()))
        ||(!projectNode.SetAttribute(CE_XMLATTR_ID, strProjNodeId))
        ||(!projectNode.SetAttribute(CE_XMLATTR_PARSERSOURCE, m_pProjectManager->GetProjectFileName()))
        ||(!projectNode.SetAttribute(CE_XMLATTR_TYPE, m_strInstancesType))
        ||(!projectNode.SetAttribute(PRJMAN_VERSION, strVersion))    )
    {
        return FALSE;
    }

    Reparse4CPAttributes(&projectNode);

    // add project file to source file list
    TSourceFileInfo* pProjFileInfo;
    CString strProjFileName = m_pProjectManager->GetProjectFileName();
    pProjFileInfo = CreateSourceFileInfo(strProjFileName,
                                         projectNode,  _T(""));
    PROJ_MAN_ASSERT(pProjFileInfo);
    pProjFileInfo->strIdPath = CE_XML_IDPATH_SEP + strProjNodeId;
    SetSourceTime(pProjFileInfo, m_pProjectManager->GetProjectFileNameWithPath());
    SourceFileMap_SetAt(strProjFileName, pProjFileInfo, m_mapSourceFiles);

    // update targets
    UpdateTargets();

    Reparse(FALSE);

    ExpandFromViewData();

    IXMLDOMDocument *pXMLDoc;
    m_domDocument.GetIXMLDocument(&pXMLDoc);
    m_pProjectManager->Fire_InitInstanceTree((IUnknown*)pXMLDoc);
    pXMLDoc->Release();

    m_bInit = FALSE;

    POSITION pos = m_mapInstanceTargets.GetStartPosition();
    while(pos)
    {
        CString strId;
        TInstanceTargetInfo* pInfo;
        m_mapInstanceTargets.GetNextAssoc(pos, strId, pInfo);
        if (pInfo)
        {
            CComBSTR sId = pInfo->strTargetId;
            CComBSTR sIdPath = pInfo->strIdPath;
            m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath);
        }
    }

    return TRUE;
}
/*!	
 *	\brief			Main function in this control.
 *	\param[in]	in	The BMessage which was sent to this control.
 */
void CalendarControl::MessageReceived(BMessage* in) {
	int8 month;
	int year;
	bool dontSendMessage = false;
	BMessage reply(B_REPLY);

	if (!in) { return; }	// Sanity check

	BString sb;
	
	CalendarModule* from = NULL, *to = NULL;
	time_t	moment;
	TimeRepresentation toSet;
	
	if ( !fCalModule ) {
		return BControl::MessageReceived( in );
	}
	map<int, DoubleNames> monthNames = fCalModule->GetMonthNamesForLocalYear(
			this->fRepresentedTime.tm_year);
	map<int, BString> dayNames;
	DayItem* dayItem1 = NULL;
	BPoint point;
	uint32 command = in->what;
	bool changePerformed = false;
	int prevYear = 0;
	
	switch ( command )
	{
		case ( kMonthChanged ):
			in->FindInt8( "Month", &month );
			this->fRepresentedTime.tm_mon = month;
			UpdateText();
			fMenuBar->RemoveItem( fDateSelector );
//			delete fDateSelector;
			CreateMenu();
			fMenuBar->AddItem( fDateSelector );
			UpdateTargets( fDateSelector );
			break;

		case ( kTodayModified ):
			sb.Truncate( 0 );
			fRepresentedTime.tm_mday < 10 ? 
				sb << ' ' << fRepresentedTime.tm_mday :
				sb << fRepresentedTime.tm_mday;
			
			dayItem1 = dynamic_cast< DayItem* >(fDateSelector->FindItem(sb.String()));
			if (dayItem1) {
				dayItem1->SetToday( false );
				dayItem1->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
				dayItem1->SetMarked(false);
			}
			sb.Truncate( 0 );
			if ( B_OK != in->FindInt32( "Date", ( int32* )&prevYear ) ||
				  B_OK != in->FindPointer( "Item", ( void** )&dayItem1 ) ) {
				// Panic!
				exit(6);
			}
			prevYear < 10 ?
				sb << ' ' << prevYear :
				sb << prevYear;
			dayItem1 = dynamic_cast< DayItem* >( fDateSelector->FindItem( sb.String() ) );
			if ( dayItem1 ) 
			{
				dayItem1->SetBackColor( fColorForServiceItems );				
				dayItem1->SetMarked( true );
			}
			this->fRepresentedTime.tm_mday = prevYear;

			// Get list of dates after update of the month and year
			dayNames = fCalModule->GetDayNamesForLocalYearMonth(
				this->fRepresentedTime.tm_year,
				this->fRepresentedTime.tm_mon);
			if ( ( unsigned int )fRepresentedTime.tm_mday > dayNames.size() )
			{
				fRepresentedTime.tm_mday = dayNames.size();	
			}
			fDateSelector->Invalidate();			
			UpdateText();
			UpdateTargets(fDateSelector);
			break;
		case ( kReturnToToday ):
			this->fRepresentedTime = fCalModule->FromTimeTToLocalCalendar( time( NULL ) );			
			UpdateText();
			fMenuBar->RemoveItem(fDateSelector);
			CreateMenu();
			fMenuBar->AddItem( fDateSelector );
			UpdateTargets( fDateSelector );
			break;
		case (kYearIncreased):
		case (kYearDecreased):
		case (kYearChanged):
			prevYear = this->fRepresentedTime.tm_year;
			if (command == kYearIncreased) {				
				++(this->fRepresentedTime).tm_year;
			} else if (command == kYearDecreased) {
				--(this->fRepresentedTime).tm_year;
			} else {
				year = in->FindInt32("Year");
				prevYear = year;
				this->fRepresentedTime.tm_year = year;
				in->RemoveName("Year");
			};
			// Get list of dates after update of the month and year
			dayNames = fCalModule->GetDayNamesForLocalYearMonth(
				this->fRepresentedTime.tm_year,
				this->fRepresentedTime.tm_mon);
			if ( ( unsigned int )fRepresentedTime.tm_mday > dayNames.size() ) {
				fRepresentedTime.tm_mday = dayNames.size();	
			}
			UpdateText();
//			UpdateYearsMenu(prevYear, fRepresentedTime.tm_year);
			fMenuBar->RemoveItem(fDateSelector);
			CreateMenu();
			fMenuBar->AddItem(fDateSelector);
			UpdateTargets(fDateSelector);
			break;
		case (kMonthDecreased):
		case (kMonthIncreased):
		
			sb.Truncate(0);
			sb << monthNames[fRepresentedTime.tm_mon].longName;
			if (command == kMonthDecreased) {
				--fRepresentedTime.tm_mon;				
				if (fRepresentedTime.tm_mon == 0) {
					changePerformed = true;
					prevYear = fRepresentedTime.tm_year;
					--fRepresentedTime.tm_year;
					monthNames = fCalModule->GetMonthNamesForLocalYear(
						this->fRepresentedTime.tm_year);
					fRepresentedTime.tm_mon = monthNames.size();
				}
			} else {
				++fRepresentedTime.tm_mon;
				if ( ( unsigned int )fRepresentedTime.tm_mon > monthNames.size() ) {
					changePerformed = true;
					fRepresentedTime.tm_mon = 1;
					prevYear = fRepresentedTime.tm_year;
					++fRepresentedTime.tm_year;
					monthNames = fCalModule->GetMonthNamesForLocalYear(
						this->fRepresentedTime.tm_year);
				}
			}
			// Get list of dates after update of the month and year
			dayNames = fCalModule->GetDayNamesForLocalYearMonth(
				this->fRepresentedTime.tm_year,
				this->fRepresentedTime.tm_mon);
			if ( ( unsigned int )fRepresentedTime.tm_mday > dayNames.size() ) {
				fRepresentedTime.tm_mday = dayNames.size();	
			}
			UpdateText();
			fMenuBar->RemoveItem(fDateSelector);
			CreateMenu();
			fMenuBar->AddItem(fDateSelector);
			UpdateTargets(fDateSelector);
			break;
			
		case kCalendarModuleChosen:
			if ( B_OK != in->FindString( "Calendar Module", &sb ) ) {
				break;
			}
			
			from = fCalModule;
			to   = utl_FindCalendarModule( sb );
			
			if ( !from || !to || from == to || sb == fRepresentedTime.GetCalendarModule() ) {
				// Nothing to do - user selected the same module
				break;
			}
			
			// Convert the time representation
			moment = from->FromLocalCalendarToTimeT( fRepresentedTime );
			toSet = to->FromTimeTToLocalCalendar( moment );
			fRepresentedTime = toSet;
			fRepresentedTime.SetCalendarModule( sb );
			
			// Set the new calendar module as control's calendar module
			fCalModule = to;
			
			// Update the preferences
			ParsePreferences();
			
			// Update UI
			UpdateText();
			fMenuBar->RemoveItem(fDateSelector);
			CreateMenu();
			fMenuBar->AddItem(fDateSelector);
			UpdateTargets(fDateSelector);
			break;

		default:
			dontSendMessage = true;
			BControl::MessageReceived(in);
			break;
	}
	
	if ( !dontSendMessage ) {
		if ( this->Invoke() != B_OK ) {
//			utl_Deb = new DebuggerPrintout( "Didn't send message!" );	
		}
	}

}
/*!	\brief		This function creates and updates the BPopUpMenu.
 *		\details		The created menu is updated every time the TimeRepresentation
 *						changes.
 */
void CalendarControl::CreateMenu( void ) {

	// The whole menu will be created in fixed font.
	BFont fixedFont(be_fixed_font);
	BFont plainFont(be_plain_font);
	BRect rectangle;
	BPoint	topLeftCorner( 0, 0 );
	BSize	rectSize;
	BString sb;
	
	// Which month shall we represent?
	map<int, BString> dayNames = fCalModule->GetDayNamesForLocalYearMonth(
			this->fRepresentedTime.tm_year,
			this->fRepresentedTime.tm_mon);
	map<int, DoubleNames> monthNames = fCalModule->GetMonthNamesForLocalYear(
			this->fRepresentedTime.tm_year);			
	
	int daysInMonth = dayNames.size();
	int daysInWeek = ( int )fCalModule->GetDaysInWeek();
	
	// We need to determine the bounding rectangle for the menu.
	// For this, we need to obtain the maximum bounding rectangle for a string.
	font_height fontHeightStruct;
	fixedFont.GetHeight( &fontHeightStruct );
	float fixedFontHeightString = fontHeightStruct.ascent + 
											fontHeightStruct.descent +
											fontHeightStruct.leading + SPACING;
	plainFont.GetHeight( &fontHeightStruct );
	float plainFontHeightString = fontHeightStruct.ascent + 
											fontHeightStruct.descent +
											fontHeightStruct.leading + SPACING;
	// Now fixedFontHeightString is surely big enough to enclose every string in 
	// height. How many lines will we need? One for name of month and year,
	// one for weekday names, and several more for the dates themselves. At the
	// bottom, there is an additional line for "Return to today" option.
	
	
	// tempDay is a running date in current month. Each day item will be initialized
	// from the tempDay.
	TimeRepresentation tempDay( this->fRepresentedTime );
	tempDay.tm_mday = 1;
	
	int firstDayOfMonthWD = fCalModule->GetWeekDayForLocalDateAsInt( tempDay );
	int firstDayOfWeek = ( int )fFirstDayOfEveryWeek;
	
	int firstDayOfMonthInFirstWeek =
		(firstDayOfMonthWD + daysInWeek - firstDayOfWeek) % daysInWeek;
	
	// This is the menu we're adding items to.
	if ( fDateSelector ) {
		BMenuItem* item = NULL;
		while ( fDateSelector->ItemAt( 0 ) ) {
			item = fDateSelector->RemoveItem( ( int32 )0 );
			delete item;
		}
	} else {
		fDateSelector = new BMenu("⇩", B_ITEMS_IN_MATRIX );
	}
	// Sanity check
	if ( !fDateSelector )
	{
		// Panic!
		fLastError = B_NO_MEMORY;
		return;
	}
	
	fDateSelector->SetViewColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	fDateSelector->SetFont( &fixedFont );
	
	topLeftCorner.x = SPACING + 5;
	topLeftCorner.y = SPACING;	
	
	// Build the list of months.
	BPopUpMenu* listOfMonths = CreateMonthsMenu(monthNames);
	
	//-----------------------------------------------------
	// FIRST ROW.
	//-----------------------------------------------------
	
	/*----------------------------------------------------------------------------
	 *			Adding months menu with option to scroll forward and backward
	 *----------------------------------------------------------------------------*/
	
	// Add the item to scroll list of months back
	BMessage* messageOfItem = new BMessage( kMonthDecreased );
	DayItem* itemToAdd = new DayItem("‹", messageOfItem);
	if ( !itemToAdd ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	itemToAdd->SetServiceItem( true );
	itemToAdd->SetFrontColor( fColorForServiceItems );
	itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	itemToAdd->SetEnabled( true );
	rectSize.SetHeight( fixedFontHeightString );
	rectSize.SetWidth( 25 );
//	rectSize.SetWidth( ( float )fixedFont.StringWidth("‹") + SPACING );
	fDateSelector->AddItem(	itemToAdd, 
									BRect( topLeftCorner, rectSize ) );
	itemToAdd->SetTarget( this );

	topLeftCorner.x += rectSize.Width() + SPACING;

	// Add the list of months
	BString longestMonth = monthNames[ 1 ].longName;
	for ( int i = 2; i < ( int )monthNames.size(); i++ )
	{
		if ( ( ( BString )( monthNames[ i ].longName ) ).Length() > longestMonth.Length() )
		{
			longestMonth = monthNames[i].longName;
		}	
	}
	rectSize.SetHeight( plainFontHeightString );
	rectSize.SetWidth( (float)plainFont.StringWidth( longestMonth.String() ) + 10 + SPACING );
	fDateSelector->AddItem( listOfMonths, 
									BRect(topLeftCorner, rectSize) );
	topLeftCorner.x += rectSize.Width() + SPACING;

	// Add the item to scroll list of months forward.
	messageOfItem = new BMessage( kMonthIncreased );
	if ( !messageOfItem ) {
		// Panic! 
		fLastError = B_NO_MEMORY;
		return;
	}		
	itemToAdd = new DayItem( "›", messageOfItem );
	if ( !itemToAdd ) {
		/* Panic! */ 
		fLastError = B_NO_MEMORY; 
		return;
	}
	itemToAdd->SetServiceItem(true);
	itemToAdd->SetFrontColor( fColorForServiceItems );
	itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	itemToAdd->SetEnabled( true );
	rectSize.SetHeight( fixedFontHeightString );
	rectSize.SetWidth( 25 );
//	rectSize.SetWidth( ( float )fixedFont.StringWidth("›") + SPACING );
	fDateSelector->AddItem( itemToAdd, 
									BRect( topLeftCorner, rectSize ) );
	itemToAdd->SetTarget( this );

	topLeftCorner.x += rectSize.Width() + 10 + SPACING;


	/*----------------------------------------------------------------------------
	 *			Adding years menu with option to scroll forward and backward
	 *----------------------------------------------------------------------------*/

	// Add the item to scroll list of years down.
	messageOfItem = new BMessage( kYearDecreased );
	if ( !messageOfItem ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	itemToAdd = new DayItem( "‒", messageOfItem );
	if ( !itemToAdd ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	itemToAdd->SetServiceItem(true);
	itemToAdd->SetFrontColor( fColorForServiceItems );
	itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	itemToAdd->SetEnabled( true );
	rectSize.SetHeight( fixedFontHeightString );
	rectSize.SetWidth( 25 );
//	rectSize.SetWidth( ( float )fixedFont.StringWidth("‒") + SPACING );
	fDateSelector->AddItem( itemToAdd, 
									BRect( topLeftCorner, rectSize ) );
	itemToAdd->SetTarget( this );
	
	topLeftCorner.x += rectSize.Width() + SPACING;
	
	// Add year
	sb.Truncate( 0 );
	sb << fRepresentedTime.tm_year;
	rectSize.SetHeight( plainFontHeightString );
	rectSize.SetWidth( ( float )plainFont.StringWidth( sb.String() ) + 10 + SPACING );
	BPopUpMenu* listOfYears = CreateYearsMenu(this->fRepresentedTime.tm_year);
	if ( !listOfYears ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fDateSelector->AddItem( listOfYears,
									BRect( topLeftCorner, rectSize ) );
	topLeftCorner.x += rectSize.Width() + SPACING;

	// Add item to scroll list of years up.
	messageOfItem = new BMessage( kYearIncreased );
	if ( !messageOfItem ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	itemToAdd = new DayItem( "+", messageOfItem );
	if ( !itemToAdd ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	itemToAdd->SetServiceItem(true);
	itemToAdd->SetFrontColor( fColorForServiceItems );
	itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	itemToAdd->SetEnabled(true);
	rectSize.SetHeight( fixedFontHeightString );
	rectSize.SetWidth( 25 );
//	rectSize.SetWidth( ( float )fixedFont.StringWidth( "+" ) + SPACING );
	fDateSelector->AddItem( itemToAdd, 
									BRect( topLeftCorner, rectSize ) );

	//-----------------------------------------------------
	// SECOND ROW.	WEEKDAY NAMES
	//-----------------------------------------------------
	sb.Truncate( 0 );
	rectSize.SetHeight( fixedFontHeightString );
	sb << ( int )fCalModule->GetLongestMonthLength();
	rectSize.SetWidth( fixedFont.StringWidth( sb.String() ) + SPACING );
	float rowHeight = rectSize.Height() + SPACING;
	float itemWidth = rectSize.Width() + 15 + SPACING;
	rectSize.SetWidth( itemWidth  );
	rectSize.SetHeight( rowHeight );
	
	topLeftCorner.x = SPACING; 
	topLeftCorner.y += rowHeight + ( SPACING * 2 );
	
	map<uint32, DoubleNames> weekdayNames = fCalModule->GetWeekdayNames();
	uint32 limit = ( uint32 )fCalModule->GetDaysInWeek();
	uint32 curDay;
	
	for (uint32 i = firstDayOfWeek; i < limit+firstDayOfWeek; ++i) {	
		curDay = ( (i - 1) % limit ) + 1;
		
		itemToAdd = new DayItem( weekdayNames[ curDay ].shortName.String(), NULL );
		if (!itemToAdd) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		itemToAdd->SetServiceItem( true );
			// If this is a weekend, we shold display it in another color
		if ( fWeekends.HasItem( (void*)i ) ||
			  fWeekends.HasItem( (void*)( i % daysInWeek ) ) )
		{
			itemToAdd->SetFrontColor( fColorForWeekends );
		} else {
			itemToAdd->SetFrontColor( fColorForServiceItems );;
		}
		itemToAdd->SetEnabled(false);
		itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
		fDateSelector->AddItem( itemToAdd, 
										BRect( topLeftCorner, rectSize ) );
		topLeftCorner.x += itemWidth + SPACING;
	}
	
	topLeftCorner.x = SPACING;
	topLeftCorner.y += rowHeight + SPACING;
	
	//-----------------------------------------------------------------------
	// THIRD ROW AND DOWN - THE WEEK INDIVIDUAL DAYS.
	//----------------------------------------------------------------------
	uint32 currentWeekday = ( uint32 )firstDayOfMonthInFirstWeek;
	topLeftCorner.x += ( itemWidth + SPACING ) * firstDayOfMonthInFirstWeek;
	
	for (int day = 1; day <= daysInMonth; ++day )
	{
		messageOfItem = new BMessage(kTodayModified);
		if ( !messageOfItem ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		messageOfItem->AddInt32( "Date", day );

		sb.Truncate( 0 );
		char padding = ' ';	// <-- For proper aligning of the items
		( day < 10 ) ? sb << padding << day : sb << day;
		itemToAdd = new DayItem( sb.String(), messageOfItem );
		if ( !itemToAdd ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		itemToAdd->SetEnabled( true );
		itemToAdd->SetServiceItem( false );
		messageOfItem->AddPointer( "Item", &itemToAdd );
		if ( fWeekends.HasItem( ( void* )( ( fFirstDayOfEveryWeek + currentWeekday ) % daysInWeek ) ) ||
		     fWeekends.HasItem( ( void* )( ( fFirstDayOfEveryWeek + currentWeekday ) ) ) )
		{
			itemToAdd->SetFrontColor( weekendDateColor );
		} else {
			itemToAdd->SetFrontColor( ui_color( B_MENU_ITEM_TEXT_COLOR ) );
		}
		// Does this item represent today?
		if ( fRepresentedTime.tm_mday == day ) {
			itemToAdd->SetToday( true );
			itemToAdd->SetBackColor( fColorForServiceItems );
			itemToAdd->SetMarked( true );
		}
		fDateSelector->AddItem( itemToAdd,
										BRect( topLeftCorner, rectSize ) );
		itemToAdd->SetTarget( this );
		
		topLeftCorner.x += itemWidth + SPACING;
	
		++currentWeekday;
		if ( ( currentWeekday % daysInWeek == 0 ) &&
		     ( day < daysInMonth ) )
		{
			topLeftCorner.x = SPACING;
			topLeftCorner.y += rowHeight+SPACING;
			currentWeekday = 0;
		}	
	}
	
	//-----------------------------------------------------------------------
	// LAST ROW - The option to return to current date.
	//----------------------------------------------------------------------
	topLeftCorner.y += rowHeight + SPACING;
	messageOfItem = new BMessage( kReturnToToday );
	if ( !messageOfItem ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	sb.Truncate( 0 );
	sb << "Go to today";		// Label
	itemToAdd = new DayItem( sb.String(), messageOfItem );
	if ( !itemToAdd ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	// Setting the color to blue
	itemToAdd->SetServiceItem(true);
	itemToAdd->SetFrontColor( fColorForServiceItems );
	itemToAdd->SetBackColor( ui_color( B_MENU_BACKGROUND_COLOR ) );
	itemToAdd->SetEnabled( true );
	itemToAdd->SetTarget( this );
	// The new v-alignment was already set above. Now it's time to set the
	// x-alignment. I'd like to align this item to the center of Menu's rec-
	// tangle, which require some additional calculations.
	float currentWidth = itemWidth * daysInWeek + ( SPACING * 2 );
	float desiredWidth = plainFont.StringWidth( sb.String()) ;
	topLeftCorner.x = SPACING + 0.5 * ( currentWidth - desiredWidth );
	rectSize.SetHeight( plainFontHeightString );
	rectSize.SetWidth( desiredWidth + 30 ); 
	fDateSelector->AddItem( itemToAdd,
									BRect( topLeftCorner, rectSize ) );
	
	fDateSelector->SetTargetForItems( this );
	
	UpdateTargets( fDateSelector );
}