Wtx ~ Wt Extension Library
WtxLib
MiniMonth.cpp
1 
2 #include <Wt/WPushButton.h>
3 #include <Wt/WText.h>
4 #include <Wt/WTable.h>
5 #include <Wt/WCalendar.h>
6 
7 #include <Wtx/Util.h>
8 
9 #include "Calendar.h"
10 #include "MiniMonth.h"
11 
12 Wtx::Web::Calendar::MiniMonth::MiniMonth( int fdow, const Wt::WDate & date )
13 : Wt::WContainerWidget()
14 {
15  m_firstDayOfWeek = fdow;
16 
17  /*
18  ** grab the date but make sure it's properly set to the
19  ** beginning of the month, just in case the caller failed
20  ** to do so.
21  **
22  */
23  m_date = Wt::WDate(date.year(),date.month(),1);
24 
25  m_templt =
26  addNew< Wt::WTemplate >
27  (
28  "<div>"
29  " <center>"
30  " ${prev}"
31  " ${month}"
32  " ${year}"
33  " ${next}"
34  " </center>"
35  "</div>"
36  "<div>"
37  " ${table}"
38  "</div>"
39  );
40 
41  m_prev = templt()-> bindNew< Wt::WText >( "prev", "" );
42  m_next = templt()-> bindNew< Wt::WText >( "next", "" );
43  m_month = templt()-> bindNew< Wt::WText >( "month", Wt::WDate::longMonthName( date.month() ) );
44  m_year = templt()-> bindNew< Wt::WText >( "year", Wtx::itos( date.year() ) );
45 
46  m_prev-> clicked().connect( [=](){ m_prevClicked.emit(); } );
47  m_next-> clicked().connect( [=](){ m_nextClicked.emit(); } );
48 
49  /*
50  ** put in a table, and then put another header
51  ** in that contains the weekday-names.
52  **
53  */
54  m_table = templt()-> bindNew<Wt::WTable>( "table" );
55  table()-> addStyleClass( "Wtx_MiniMonth" );
56 
57  updateView();
58 
59 } // endMiniCalendar::MiniCalendar( const Wt::WDate & date )
60 
61 
62 void Wtx::Web::Calendar::MiniMonth::updateView()
63 {
64  table()-> clear();
65 
66  /*
67  ** The normal WCalendar employs a firstDayOfWeek function that is
68  ** 1-based, meaning, 1=first day of week which is also Monday. Since
69  ** we have daynames() that are zero-based, meaning 0=Sunday, the logic
70  ** works out that 0=Sunday so therefore 1=Monday, but the specification
71  ** for WCalendar is that the possible range is 1..7, not 0..6 so we
72  ** have to make a slight adjustment to the incoming value so that
73  ** 7 becomes 0.
74  **
75  */
76  auto firstDayOfWeek = m_firstDayOfWeek % 7;
77 
78  /*
79  ** put up a short-day-name based on the (normal)
80  ** day names (meaning, sunday is usually the first day)
81  ** in the header row. If a different firstDayOfWeek was
82  ** asked for, then the first-day pasted here will be
83  ** that day. If the firstDayOfWeek=3 then the first
84  ** day shown in the first column should be wednesday.
85  **
86  */
87  for( int weekday = 0; weekday < 7; weekday++ )
88  {
89  auto w = std::make_unique< Wt::WText >( daynames().at((weekday+firstDayOfWeek)%7).substr(0,3) );
90 
91  w-> addStyleClass( "Wtx_MiniMonth_dayname" );
92 
93  table()-> elementAt( 0, weekday )-> addWidget( std::move(w) );
94  }
95 
96 // for( int i=0; i<14; i++ )
97 // std::cout << __FILE__ << ":" << __LINE__ << " " << i << " " << i % 7 << std::endl;
98 
99  auto dow = (m_date.dayOfWeek()-firstDayOfWeek)%7;
100 
101 #ifndef NEVER
102  std::cout << __FILE__ << ":" << __LINE__
103  << " dat:" << m_date.toString()
104  << " dow:" << m_date.dayOfWeek()
105  << " dow:" << dow
106  << " fdw:" << firstDayOfWeek
107  << std::endl
108  ;
109 #endif
110 
111  /*
112  ** put out a row for each week. We are going to
113  ** plop down 6 weeks of days
114  **
115  */
116  for( int week = 0; week < 6; week++ )
117  {
118  /*
119  ** put out a column for each day. There are 7
120  ** days in a week.
121  **
122  */
123  for( int day = 0; day < 7; day++ )
124  {
125  auto d = m_date.addDays( (dow*-1) + ((week*7)+day) );
126  auto w = std::make_unique< DayWidget >( d );
127  m_dayWidgets.push_back( w.get() );
128 
129  table()-> elementAt( week*7, day )-> addWidget( std::move(w) );
130  }
131 
132  } // endfor( int week = 0; week < 6; week++ )
133 
134 }
135 
136 void Wtx::Web::Calendar::MiniMonth::setSelectedDate( const Wt::WDate & date )
137 {
138  for( auto dayWidget : m_dayWidgets )
139  {
140  if( dayWidget-> date() == date )
141  {
142  dayWidget-> setSelected( true );
143  }
144  else
145  {
146  dayWidget-> setSelected( false );
147  }
148 
149  }
150 }
151 
152 
153 void Wtx::Web::Calendar::MiniMonth::allowPrev( bool value )
154 {
155  if( value )
156  m_prev-> setText( "<<" );
157  else
158  m_prev-> setText( "" );
159 }
160 
161 void Wtx::Web::Calendar::MiniMonth::allowNext( bool value )
162 {
163  if( value )
164  m_next-> setText( ">>" );
165  else
166  m_next-> setText( "" );
167 }
168 
169 void Wtx::Web::Calendar::MiniMonth::allowPrevNext( bool value )
170 {
171  allowPrev( value );
172  allowNext( value );
173 }
174 
175 
176 
177 Wtx::Web::Calendar::MiniMonth::DayWidget::DayWidget( const Wt::WDate & date )
178 : Wt::WText( Wt::WString("{1}").arg( date.day() ) ),
179  m_date(date)
180 {
181  addStyleClass( "Wtx_MiniMonth_day" );
182 
183  if( date == Wt::WDate::currentDate() )
184  {
185  addStyleClass( "Wtx_MiniMonth_today" );
186  }
187 
188 }
189 
190 const Wt::WDate & Wtx::Web::Calendar::MiniMonth::DayWidget::date() const
191 {
192  return m_date;
193 }
194 
195 void Wtx::Web::Calendar::MiniMonth::DayWidget::setSelected( bool value )
196 {
197  if( value )
198  {
199  addStyleClass( "Wtx_MiniMonth_selected" );
200  }
201  else
202  {
203  removeStyleClass( "Wtx_MiniMonth_selected" );
204  }
205 }
206 
207 void Wtx::Web::Calendar::MiniMonth::browseTo( const Wt::WDate & date )
208 {
209  m_date = date;
210  updateView();
211 }
212 
213 
const std::vector< std::string > & daynames()
Long Day Names.
Definition: Calendar.cpp:11
std::string itos(int value)
Convert an Integer to a String.
Definition: Util.cpp:311