001package polaris.sdk.ui.controls; 002import polaris.sdk.ui.*; 003 004import java.time.*; 005public class DatePicker extends Button { 006 private LocalDate value=LocalDate.now();public DatePicker(){super();refresh();}public DatePicker value(LocalDate date){if(date==null)throw new NullPointerException("date");value=date;refresh();return this;}public LocalDate value(){return value;}private void refresh(){text=value.toString()+" ▾";} 007 @Override public void activate(){if(ui!=null)ui.popup(new CalendarPopup(),ax,ay+h+4);} 008 private final class CalendarPopup extends Widget { 009 private YearMonth month=YearMonth.from(value);private LocalDate current=value; 010 CalendarPopup(){w=294;h=280;focusable=true;} 011 private LocalDate first(){LocalDate day=month.atDay(1);return day.minusDays(day.getDayOfWeek().getValue()-1);} 012 private void choose(LocalDate date){DatePicker.this.value(date);DatePicker.this.changed();if(ui!=null)ui.close(this);} 013 @Override protected void paint(Painter p){glassPart(p,ax,ay,w,h,13,.07f,theme().surface,0,theme().blur);p.text("‹",ax+14,ay+12,20,theme().accent);p.text(month.toString(),ax+96,ay+16,15,ink());p.text("›",ax+w-26,ay+12,20,theme().accent);String[] week={"一","二","三","四","五","六","日"};for(int i=0;i<7;i++)p.text(week[i],ax+15+i*40,ay+48,12,theme().muted);LocalDate first=first();for(int i=0;i<42;i++){LocalDate day=first.plusDays(i);float xx=ax+7+(i%7)*40,yy=ay+71+(i/7)*32;if(day.equals(current)){float sx=motion("dayX",xx-ax,28,.84f),sy=motion("dayY",yy-ay,28,.84f);glassPart(p,ax+sx,ay+sy,34,28,14,theme().selectedTint,theme().accent,.32f,theme().blur);}p.text(Integer.toString(day.getDayOfMonth()),xx+9,yy+7,12,day.getMonth()==month.getMonth()?ink():theme().muted);}} 014 @Override public void event(UiEvent e){if(e.type==UiEvent.Type.UP){if(e.y<ay+42){if(e.x<ax+50)month=month.minusMonths(1);else if(e.x>ax+w-50)month=month.plusMonths(1);}else if(e.y>=ay+71){int col=(int)((e.x-ax-7)/40),row=(int)((e.y-ay-71)/32);if(col>=0&&col<7&&row>=0&&row<6)choose(first().plusDays(row*7+col));}}else if(e.type==UiEvent.Type.KEY){if(e.key==10){choose(current);}else if(e.key==37||e.key==39||e.key==38||e.key==40){current=current.plusDays(e.key==37?-1:e.key==39?1:e.key==38?-7:7);month=YearMonth.from(current);}else return;e.handled=true;}} 015 } 016}