/*! \brief Constructor of CategoryPreferencesView * \details It's a descendant of BView. * \param[in] frame The frame rectangle of the view. */ CategoryPreferencesView::CategoryPreferencesView( BRect frame ) : BView( frame, "Category Preferences", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE ) { BLayoutItem* layoutItem = NULL; BMessage* toSend = NULL; menuField = NULL; this->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); /*! \note Layout of the view * The view has a grid layout. It's arranged in the following way: * 1) Left column - list of Categories (CategoryList) that * contains all categories currently available. * 2) Right column - three buttons, from top to bottom: * 2a) Edit currently selected category - guess what it's doing * 2b) Add a new category * 2c) Merge a current directory into another one + menu with * all categories. The category selected in the list is disabled. * \note Restrictions: * a) The list of categories is scrolled. * b) If no category is selected, then * i) "Edit" button is disabled * ii) "Merge to" field is disabled * */ BGridLayout* gridLayout = new BGridLayout(); if ( !gridLayout ) { /* Panic! */ exit( 1 ); } // Margins from the sides of the view and spacing between the elements gridLayout->SetInsets( 5, 5, 5, 5 ); gridLayout->SetHorizontalSpacing( 10 ); gridLayout->SetVerticalSpacing( 10 ); this->SetLayout( gridLayout ); gridLayout->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT ) ); gridLayout->SetExplicitMinSize( BSize( (this->Bounds()).Width(), (this->Bounds()).Height() ) ); BRect rect = gridLayout->Frame(); printf ( "The frame is %d pixels wide and %d pixels high.\n", (int )rect.Width(), (int )rect.Height() ); /* Creating the CategoryListView with its scroller */ BRect r( this->Bounds() ); r.InsetBySelf( 5, 10 ); // Margins near the border of the view r.right = (int)(r.right / 2) - B_V_SCROLL_BAR_WIDTH; r.bottom -= 0; listView = new CategoryListView( r, "List View" ); if ( ! listView ) { /* Panic! */ exit( 1 ); } BLooper* looper = this->Looper(); if ( looper && looper->LockLooper() ) { looper->AddHandler( ( BHandler* )this ); looper->UnlockLooper(); } scroller = new BScrollView( "Scroller", listView, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, // Flags true, true ); if ( !scroller ) { /* Panic! */ exit( 1 ); } layoutItem = gridLayout->AddView( scroller, 0, 0, 1, 3 ); if ( !layoutItem ) { /* Panic! */ exit( 1 ); } layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_USE_FULL_HEIGHT ) ); toSend = new BMessage( kCategoryInvoked ); if ( !toSend ) { /* Panic! */ exit( 1 ); } listView->SetInvocationMessage( toSend ); toSend = new BMessage( kCategorySelected ); if ( !toSend ) { /* Panic! */ exit( 1 ); } listView->SetSelectionMessage( toSend ); r = listView->Bounds(); r.bottom += B_H_SCROLL_BAR_HEIGHT + 3; r.right -= ( B_V_SCROLL_BAR_WIDTH + 10 ); layoutItem->SetExplicitMinSize( BSize( ( B_V_SCROLL_BAR_WIDTH * 2 ), r.Height() ) ); gridLayout->SetMaxColumnWidth( 0, r.Width()-70 ); gridLayout->SetMaxColumnWidth( 1, r.Width()-66 ); // Add categories to the list PopulateCategoriesView(); /* Creating the buttons */ // Add new category button toSend = new BMessage( kAddNewCategory ); addButton = new BButton( BRect( 0, 0, 1, 1), "Add category", "Add category", toSend, B_FOLLOW_H_CENTER | B_FOLLOW_V_CENTER ); if ( !toSend || !addButton ) { /* Panic! */ exit( 1 ); } addButton->ResizeToPreferred(); addButton->SetTarget( this ); layoutItem = gridLayout->AddView( addButton, 1, 0, 1, 1 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER ) ); // Edit old category button toSend = new BMessage( kCategoryInvoked ); editButton = new BButton( BRect( 0, 0, 1, 1), "Edit category", "Edit category", toSend, B_FOLLOW_H_CENTER | B_FOLLOW_V_CENTER ); if ( !toSend || !editButton ) { /* Panic! */ exit( 1 ); } editButton->ResizeToPreferred(); editButton->SetTarget( this ); layoutItem = gridLayout->AddView( editButton, 1, 1, 1, 1 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER ) ); // Edit category button is disabled by default; // it's enabled when user chooses a category in the list. editButton->SetEnabled( false ); /* Creating the menu of merging a category */ // Create a label BGroupLayout* groupLayout = new BGroupLayout( B_VERTICAL ); if ( !groupLayout ) { /* Panic! */ exit( 1 ); } gridLayout->AddItem( groupLayout, 1, 2, 1, 1 ); groupLayout->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) ); mergeToLabel = new BStringView( BRect( 0, 0, 1, 1 ), "Merge to label", "Merge selected category into:" ); if ( !mergeToLabel ) { /* Panic! */ exit( 1 ); } mergeToLabel->ResizeToPreferred(); layoutItem = groupLayout->AddView( mergeToLabel ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) ); // Create the menu BMessage templateMessage( kMergeIntoCategory ); listMenu = new CategoryMenu( "Select category to merge to:", true, &templateMessage ); if ( !listMenu ) { /* Panic! */ exit( 1 ); } menuField = new BMenuField( mergeToLabel->Bounds(), "Merge to field", NULL, listMenu ); if ( !menuField ) { /* Panic! */ exit( 1 ); } menuField->SetDivider( 0 ); // Just like the "Edit" button above, the menu is initially disabled. menuField->SetEnabled( false ); layoutItem = groupLayout->AddView( menuField ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_TOP ) ); for ( int index = 0; index < gridLayout->CountColumns(); ++index ) { gridLayout->SetColumnWeight( index, 1 ); } for ( int index = 0; index < gridLayout->CountRows(); ++index ) { gridLayout->SetRowWeight( index, 1 ); } gridLayout->InvalidateLayout(); } // <-- end of constructor of CategoryPreferencesView
/*! * \brief The constructor of CalendarControl. * \param[in] frame The outer bounds of the control. * \param[in] name Name of the control. * \param[in] labelInForCalendar The label of the calendar part of control. * \param[in] calModuleName ID of the calendar module used. * \param[in] initialTime The initial time to be set, passed in seconds. * If 0, current time is set. * \param[in] toSend Message sent when the control's value is changed. * \attention It's assumed that calendar modules were already initialized prior * to calling this function. */ CalendarControl::CalendarControl(BRect frame, const char* name, const BString& labelInForCalendar, const BString& calModuleName, time_t initialTime, BMessage* toSend ) : BControl( frame, name, labelInForCalendar.String(), toSend, B_FOLLOW_ALL_SIDES, B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS ), fLabel(NULL), fDateLabel(NULL), fDateSelector( NULL ), fLastError( B_OK ) { // Firstly, set the calendar module this->fCalModule = utl_FindCalendarModule( calModuleName ); if ( this->fCalModule == NULL ) { fLastError = B_BAD_VALUE; return; } // Load the preferences of this calendar module ParsePreferences(); // Init the internal data to submitted time representation InitTimeRepresentation( initialTime ); // Create the UI elements fLabel = new BStringView( BRect( 0, 0, 1, 1 ), "label", labelInForCalendar.String() ); if ( !fLabel) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fLabel->ResizeToPreferred(); fDateLabel = new BStringView( BRect( 0, 0, 1, 1 ), "dateLabel", NULL ); if ( !fDateLabel ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fCalendarModuleLabel = new BStringView( BRect( 0, 0, 1, 1 ), "label for the calendar module selector", "Calendar:" ); if ( !fCalendarModuleLabel ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fCalendarModuleLabel->ResizeToPreferred(); fCalendarsMenu = CreateMenuOfCalendarModules(); if ( !fCalendarsMenu ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fCalendarModuleSelector = new BMenuField( BRect( 0, 0, 1, 1 ), "calendar module selector", NULL, // Label is created separately fCalendarsMenu ); if ( !fCalendarModuleSelector ) { /* Panic! */ fLastError = B_NO_MEMORY; return; } fCalendarModuleSelector->ResizeToPreferred(); // Create the menu CreateMenu(); BRect stringViewFrame = fLabel->Frame(); BPoint topLeftCorner = stringViewFrame.RightTop(); BSize size( BUTTON_WIDTH, stringViewFrame.Height() + SPACING ); fMenuBar = new BMenuBar( BRect(topLeftCorner, size), "menuBar", B_FOLLOW_RIGHT | B_FOLLOW_TOP, B_ITEMS_IN_ROW, false); if (! fMenuBar) { // Panic! fLastError = B_NO_MEMORY; return; } fMenuBar->SetBorder( B_BORDER_EACH_ITEM ); fMenuBar->AddItem( fDateSelector ); // Update the selected date label to currently selected moment of time UpdateText(); // Initializing the layout BGridLayout* lay = new BGridLayout( ); if (!lay) { // Panic! fLastError = B_NO_MEMORY; return; } lay->SetInsets(0, 5, 0, 0); lay->SetSpacing( 10, 5 ); lay->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_MIDDLE ) ); this->SetLayout(lay); BLayoutItem* layoutItem; layoutItem = lay->AddView( fLabel, 0, 0 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) ); layoutItem = lay->AddView( fDateLabel, 1, 0 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_TOP ) ); layoutItem = lay->AddView( fMenuBar, 2, 0 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_RIGHT, B_ALIGN_TOP ) ); layoutItem->SetExplicitMaxSize( size ); layoutItem = lay->AddView( fCalendarModuleLabel, 0, 1 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_MIDDLE ) ); layoutItem = lay->AddView( fCalendarModuleSelector, 1, 1 ); layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_TOP ) ); lay->SetColumnWeight( 0, 0 ); lay->SetColumnWeight( 1, 1000 ); lay->SetColumnWeight( 2, 0 ); lay->SetMaxColumnWidth( 2, BUTTON_WIDTH ); this->InvalidateLayout(); this->Relayout(); this->Invalidate(); fLastError = B_OK; }