Kstars

moonphasecalendarwidget.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Akarsh Simha <akarshsimha@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "moonphasecalendarwidget.h"
8
9#include "ksnumbers.h"
10#include "kstarsdatetime.h"
11#include "ksutils.h"
12#include "texturemanager.h"
13#include "skyobjects/ksmoon.h"
14#include "skyobjects/ksplanet.h"
15#include "skyobjects/kssun.h"
16
17#include <kcalendarsystem.h>
18#include <kcolorscheme.h>
19#include <kglobal.h>
20#include <kglobalsettings.h>
21#include <KLocale>
22
23#include <QActionEvent>
24#include <QDebug>
25#include <QFontDatabase>
26#include <QPainter>
27#include <QStyle>
28#include <QtGui/QStyleOptionViewItem>
29
30#include <cmath>
31
32MoonPhaseCalendar::MoonPhaseCalendar(KSMoon &moon, KSSun &sun, QWidget *parent)
33 : KDateTable(parent), m_Moon(moon), m_Sun(sun)
34{
35 // Populate moon images from disk into the hash
36 numDayColumns = calendar()->daysInWeek(QDate::currentDate());
37 numWeekRows = 7;
38 imagesLoaded = false;
39 // TODO: Set geometry.
40}
41
42MoonPhaseCalendar::~MoonPhaseCalendar()
43{
44}
45
46QSize MoonPhaseCalendar::sizeHint() const
47{
48 const int suggestedMoonImageSize = 50;
49 return QSize(qRound((suggestedMoonImageSize + 2) * numDayColumns),
50 (qRound(suggestedMoonImageSize + 4 + 12) * numWeekRows)); // FIXME: Using hard-coded fontsize
51}
52
53void MoonPhaseCalendar::loadImages()
54{
55 computeMoonImageSize();
56 qDebug() << "Loading moon images. MoonImageSize = " << MoonImageSize;
57 for (int i = 0; i < 36; ++i)
58 {
59 QString imName = QString().sprintf("moon%02d", i);
61 .scaled(MoonImageSize, MoonImageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
62 }
63 imagesLoaded = true;
64}
65
66void MoonPhaseCalendar::computeMoonImageSize()
67{
68 cellWidth = width() / (double)numDayColumns;
69 cellHeight = height() / (double)numWeekRows;
70 qDebug() << cellWidth << cellHeight;
71 MoonImageSize =
72 ((cellWidth > cellHeight - 12) ? cellHeight - 12 : cellWidth) - 2; // FIXME: Using hard-coded fontsize
73}
74
75void MoonPhaseCalendar::setGeometry(int, int, int, int)
76{
77 imagesLoaded = false;
78}
79
80void MoonPhaseCalendar::setGeometry(const QRect &r)
81{
82 setGeometry(r.x(), r.y(), r.width(), r.height()); // FIXME: +1 / -1 pixel compensation. Not required at the moment.
83}
84
85void MoonPhaseCalendar::paintEvent(QPaintEvent *e)
86{
87 QPainter p(this);
88 if (!imagesLoaded)
89 loadImages();
90 KColorScheme colorScheme(palette().currentColorGroup(), KColorScheme::View);
91 const QRect &rectToUpdate = e->rect();
92 int leftCol = (int)std::floor(rectToUpdate.left() / cellWidth);
93 int topRow = (int)std::floor(rectToUpdate.top() / cellHeight);
94 int rightCol = (int)std::ceil(rectToUpdate.right() / cellWidth);
95 int bottomRow = (int)std::ceil(rectToUpdate.bottom() / cellHeight);
96 bottomRow = qMin(bottomRow, numWeekRows - 1);
97 rightCol = qMin(rightCol, numDayColumns - 1);
98 p.translate(leftCol * cellWidth, topRow * cellHeight);
99 for (int i = leftCol; i <= rightCol; ++i)
100 {
101 for (int j = topRow; j <= bottomRow; ++j)
102 {
103 this->paintCell(&p, j, i, colorScheme);
104 p.translate(0, cellHeight);
105 }
106 p.translate(cellWidth, 0);
107 p.translate(0, -cellHeight * (bottomRow - topRow + 1));
108 }
109 p.end();
110}
111
112void MoonPhaseCalendar::paintCell(QPainter *painter, int row, int col, const KColorScheme &colorScheme)
113{
114 double w = cellWidth - 1;
115 double h = cellHeight - 1;
116 QRectF cell = QRectF(0, 0, w, h);
118 QPen pen;
121 bool workingDay = false;
122 int cellWeekDay, pos;
123
124 //Calculate the position of the cell in the grid
125 pos = numDayColumns * (row - 1) + col;
126
127 //Calculate what day of the week the cell is
128 cellWeekDay = col + calendar()->weekStartDay();
129 if (cellWeekDay > numDayColumns)
130 {
131 cellWeekDay -= numDayColumns;
132 }
133
134 //See if cell day is normally a working day
135 if (KLocale::global()->workingWeekStartDay() <= KLocale::global()->workingWeekEndDay())
136 {
137 workingDay = cellWeekDay >= KLocale::global()->workingWeekStartDay() &&
138 cellWeekDay <= KLocale::global()->workingWeekEndDay();
139 }
140 else
141 {
142 workingDay = cellWeekDay >= KLocale::global()->workingWeekStartDay() ||
143 cellWeekDay <= KLocale::global()->workingWeekEndDay();
144 }
145
146 if (row == 0)
147 {
148 //We are drawing a header cell
149
150 //If not a normal working day, then use "do not work today" color
151 if (workingDay)
152 {
154 }
155 else
156 {
157 KColorScheme colorScheme(palette().currentColorGroup(), KColorScheme::Window);
159 }
161
162 //Set the text to the short day name and bold it
163 cellFont.setBold(true);
164 cellText = calendar()->weekDayName(cellWeekDay, KCalendarSystem::ShortDayName);
165 }
166 else
167 {
168 //We are drawing a day cell
169
170 //Calculate the date the cell represents
172
173 bool validDay = calendar()->isValid(cellDate);
174
175 // Draw the day number in the cell, if the date is not valid then we don't want to show it
176 if (validDay)
177 {
178 cellText = calendar()->dayString(cellDate, KCalendarSystem::ShortFormat);
179 }
180 else
181 {
182 cellText = "";
183 }
184
185 if (!validDay || calendar()->month(cellDate) != calendar()->month(date()))
186 {
187 // we are either
188 // ° painting an invalid day
189 // ° painting a day of the previous month or
190 // ° painting a day of the following month or
193 }
194 else
195 {
196 //Paint a day of the current month
197
198 // Background Colour priorities will be (high-to-low):
199 // * Selected Day Background Colour
200 // * Customized Day Background Colour
201 // * Normal Day Background Colour
202
203 // Background Shape priorities will be (high-to-low):
204 // * Customized Day Shape
205 // * Normal Day Shape
206
207 // Text Colour priorities will be (high-to-low):
208 // * Customized Day Colour
209 // * Day of Pray Colour (Red letter)
210 // * Selected Day Colour
211 // * Normal Day Colour
212
213 //Determine various characteristics of the cell date
214 bool selectedDay = (cellDate == date());
216 bool dayOfPray = (calendar()->dayOfWeek(cellDate) == KLocale::global()->weekDayOfPray());
217
218 //Default values for a normal cell
221
222 // If we are drawing the current date, then draw it bold and active
223 if (currentDay)
224 {
225 cellFont.setBold(true);
227 }
228
229 // if we are drawing the day cell currently selected in the table
230 if (selectedDay)
231 {
232 // set the background to highlighted
235 }
236
237 //If the cell day is the day of religious observance, then always color text red unless Custom overrides
238 if (dayOfPray)
239 {
240 KColorScheme colorScheme(palette().currentColorGroup(),
243 }
244 }
245 }
246
247 //Draw the background
248 if (row == 0)
249 {
250 painter->setPen(cellBackgroundColor);
252 painter->drawRect(cell);
253 }
254 else if (cellBackgroundColor != palette().color(backgroundRole()))
255 {
257 opt.initFrom(this);
258 opt.rect = cell.toRect();
260 {
263 }
264 if (false && opt.state & QStyle::State_Enabled)
265 {
267 }
268 else
269 {
270 opt.state &= ~QStyle::State_MouseOver;
271 }
272 opt.showDecorationSelected = true;
273 opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
275 }
276
277 if (row != 0)
278 {
279 // Paint the moon phase
281 if (calendar()->isValid(cellDate))
282 {
283 int iPhase = computeMoonPhase(KStarsDateTime(cellDate, QTime(0, 0, 0)));
284 QRect drawRect = cell.toRect();
285 painter->drawPixmap((drawRect.width() - MoonImageSize) / 2,
286 12 + ((drawRect.height() - 12) - MoonImageSize) / 2,
287 m_Images[iPhase]); // FIXME: Using hard coded fon
288 // + painter
289 // painter->drawPixmap( ( drawRect.width() - MoonImageSize )/2,
290 // 12 + (( drawRect.height() - 12 ) - MoonImageSize)/2,
291 // m_Images[ iPhase ] );
292 // FIXME: Using hard coded fontsize
293 // qDebug() << "Drew moon image " << iPhase;
294 }
295 }
296
297 //Draw the text
298 painter->setPen(cellTextColor);
299 painter->setFont(cellFont);
300 painter->drawText(cell, (row == 0) ? Qt::AlignCenter : (Qt::AlignTop | Qt::AlignHCenter), cellText, &cell);
301
302 //Draw the base line
303 if (row == 0)
304 {
305 painter->setPen(palette().color(foregroundRole()));
306 painter->drawLine(QPointF(0, h), QPointF(w, h));
307 }
308
309 // If the day cell we just drew is bigger than the current max cell sizes,
310 // then adjust the max to the current cell
311
312 /*
313 if ( cell.width() > d->maxCell.width() ) d->maxCell.setWidth( cell.width() );
314 if ( cell.height() > d->maxCell.height() ) d->maxCell.setHeight( cell.height() );
315 */
316}
317
318unsigned short MoonPhaseCalendar::computeMoonPhase(const KStarsDateTime &date)
319{
320 KSNumbers num(date.djd());
321 KSPlanet earth(I18N_NOOP("Earth"), QString(), QColor("white"), 12756.28 /*diameter in km*/);
322 earth.findPosition(&num);
323
324 m_Sun.findPosition(
325 &num, 0, 0,
326 &earth); // Find position is overkill for this purpose. Wonder if it is worth making findGeocentricPosition public instead of protected.
327 m_Moon.findGeocentricPosition(&num, &earth);
328
329 m_Moon.findPhase(&m_Sun);
330
331 return m_Moon.getIPhase();
332}
QBrush foreground(ForegroundRole=NormalText) const
Provides necessary information about the Moon.
Definition ksmoon.h:26
bool findGeocentricPosition(const KSNumbers *num, const KSPlanetBase *) override
Reimplemented from KSPlanetBase, this function employs unique algorithms for estimating the lunar coo...
Definition ksmoon.cpp:153
short int getIPhase() const
Definition ksmoon.h:58
void findPhase(const KSSun *Sun=nullptr)
Determine the phase angle of the moon, and assign the appropriate moon image.
Definition ksmoon.cpp:268
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
void findPosition(const KSNumbers *num, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, const KSPlanetBase *Earth=nullptr)
Find position, including correction for Figure-of-the-Earth.
A subclass of KSPlanetBase for seven of the major planets in the solar system (Earth and Pluto have t...
Definition ksplanet.h:33
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition kssun.h:24
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
long double djd() const
static const QImage & getImage(const QString &name)
Return texture image.
bool isValid(QStringView ifopt)
const QColor & color() const const
QDate currentDate()
QFont systemFont(SystemFont type)
void drawLine(const QLine &line)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawRect(const QRect &rectangle)
void drawText(const QPoint &position, const QString &text)
void setBrush(Qt::BrushStyle style)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
const QRect & rect() const const
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
QPixmap scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
int height() const const
int width() const const
int x() const const
int y() const const
QRect toRect() const const
PE_PanelItemViewItem
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
AlignCenter
KeepAspectRatio
SmoothTransformation
QPalette::ColorRole backgroundRole() const const
QPalette::ColorRole foregroundRole() const const
QStyle * style() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.