/*! \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
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(); }
//----------------------------------------------- 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(); }
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); }
//------------------------------------------------------ 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 ); }