From 8ce0f69f1bbdaed3e60e5ff4d4350f173466f82d Mon Sep 17 00:00:00 2001 From: Andrew Tribick Date: Sun, 18 Feb 2024 08:26:35 +0100 Subject: [PATCH 1/8] [sdl] Move code to unnamed namespace --- src/celestia/sdl/sdlmain.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/celestia/sdl/sdlmain.cpp b/src/celestia/sdl/sdlmain.cpp index f49d926bb4..d140a784b0 100644 --- a/src/celestia/sdl/sdlmain.cpp +++ b/src/celestia/sdl/sdlmain.cpp @@ -31,8 +31,12 @@ #include #endif -namespace celestia +namespace celestia::sdl { + +namespace +{ + class SDL_Alerter : public CelestiaCore::Alerter { SDL_Window* window { nullptr }; @@ -307,7 +311,7 @@ SDL_Application::update() return RunLoopState::Normal; } -static int +int toCelestiaKey(SDL_Keycode key) { switch (key) @@ -442,7 +446,7 @@ SDL_Application::handleTextInputEvent(const SDL_TextInputEvent &event) m_appCore->charEntered(event.text, 0); } -static int +int toCelestiaButton(int button) { switch (button) @@ -611,7 +615,7 @@ SDL_Application::pasteURL() SDL_free(str); } -static void +void FatalErrorImpl(fmt::string_view format, fmt::format_args args) { auto message = fmt::vformat(format, args); @@ -623,13 +627,14 @@ FatalErrorImpl(fmt::string_view format, fmt::format_args args) fmt::print(stderr, "{}\n", message); } -template void +template +void FatalError(const char *format, const Args&... args) { FatalErrorImpl(fmt::string_view(format), fmt::make_format_args(args...)); } -static void +void DumpGLInfo() { const char* s; @@ -709,10 +714,13 @@ sdlmain(int /* argc */, char ** /* argv */) return 0; } -} // namespace + +} // end unnamed namespace + +} // end namespace celestia::sdl int main(int argc, char **argv) { - return celestia::sdlmain(argc, argv); + return celestia::sdl::sdlmain(argc, argv); } From 66b2887174a7474cced67f912297f306ef3f1454 Mon Sep 17 00:00:00 2001 From: Colin Kinloch Date: Sat, 17 Feb 2024 13:10:57 +0000 Subject: [PATCH 2/8] Generate platform specific metainfo at configure * Add fields to pass flathub linting * Use owned celestiaproject.space for reverse domain id --- debian/celestia-gtk.install | 2 +- debian/celestia-qt5.install | 2 +- ...e.celestiaproject.Celestia.metainfo.xml.in | 48 +++++++++++++++++++ src/celestia/gtk/data/CMakeLists.txt | 9 +++- .../space.celestia.celestia_gtk.metainfo.xml | 29 ----------- src/celestia/qt5/data/CMakeLists.txt | 9 +++- .../space.celestia.celestia_qt5.metainfo.xml | 29 ----------- src/celestia/qt6/data/CMakeLists.txt | 9 +++- .../space.celestia.celestia_qt6.metainfo.xml | 29 ----------- src/celestia/sdl/data/CMakeLists.txt | 9 +++- .../space.celestia.celestia_sdl.metainfo.xml | 29 ----------- 11 files changed, 78 insertions(+), 126 deletions(-) create mode 100644 src/celestia/data/space.celestiaproject.Celestia.metainfo.xml.in delete mode 100644 src/celestia/gtk/data/space.celestia.celestia_gtk.metainfo.xml delete mode 100644 src/celestia/qt5/data/space.celestia.celestia_qt5.metainfo.xml delete mode 100644 src/celestia/qt6/data/space.celestia.celestia_qt6.metainfo.xml delete mode 100644 src/celestia/sdl/data/space.celestia.celestia_sdl.metainfo.xml diff --git a/debian/celestia-gtk.install b/debian/celestia-gtk.install index 2ac59b0e90..2f3ab797b0 100644 --- a/debian/celestia-gtk.install +++ b/debian/celestia-gtk.install @@ -1,5 +1,5 @@ usr/bin/celestia-gtk usr/share/celestia/celestiaui.xml usr/share/applications/celestia-gtk.desktop -usr/share/metainfo/space.celestia.celestia_gtk.metainfo.xml +usr/share/metainfo/space.celestiaproject.Celestia-gtk.metainfo.xml usr/share/man/man1/celestia-gtk.1 diff --git a/debian/celestia-qt5.install b/debian/celestia-qt5.install index fa99c1f924..e5d3ab7c46 100644 --- a/debian/celestia-qt5.install +++ b/debian/celestia-qt5.install @@ -1,4 +1,4 @@ usr/bin/celestia-qt5 usr/share/applications/celestia-qt5.desktop -usr/share/metainfo/space.celestia.celestia_qt5.metainfo.xml +usr/share/metainfo/space.celestiaproject.Celestia-qt5.metainfo.xml usr/share/man/man1/celestia-qt5.1 diff --git a/src/celestia/data/space.celestiaproject.Celestia.metainfo.xml.in b/src/celestia/data/space.celestiaproject.Celestia.metainfo.xml.in new file mode 100644 index 0000000000..a110c6c747 --- /dev/null +++ b/src/celestia/data/space.celestiaproject.Celestia.metainfo.xml.in @@ -0,0 +1,48 @@ + + + + @METAINFO_ID@ + MIT + GPL-2.0+ + @METAINFO_NAME@ + Celestia Project + + Celestia Project + + Explore the universe + +

+ Celestia provides photo-realistic, real-time, three-dimensional viewing of + the Solar System, the Galaxy and the Universe. +

+

+ It is an easy to use, freely-distributed, multi-platform, open source, + software package which has become a valuable tool for astronomy education. + Used in homes, schools, museums and planetariums around the world, it also + is used as a visualization tool by space mission designers. +

+
+ @METAINFO_DESKTOP@ + https://celestiaproject.space + + + + + + Cassini–Huygens in orbit around Saturn + https://celestiaproject.space/images/gallery/cassini.jpg + + + Earth + https://celestiaproject.space/images/gallery/earth.jpg + + + Europa in orbit around Jupiter with Io inbetween + https://celestiaproject.space/images/gallery/europa.jpg + + + Proxima Centuri with solar filaments + https://celestiaproject.space/images/gallery/proxima.png + + +
diff --git a/src/celestia/gtk/data/CMakeLists.txt b/src/celestia/gtk/data/CMakeLists.txt index 94b1e42cd8..43f30b6594 100644 --- a/src/celestia/gtk/data/CMakeLists.txt +++ b/src/celestia/gtk/data/CMakeLists.txt @@ -1,15 +1,20 @@ +set(METAINFO_ID "space.celestiaproject.Celestia-gtk") +set(METAINFO_NAME "Celestia (GTK)") +set(METAINFO_DESKTOP "celestia-gtk.desktop") +configure_file("../../data/space.celestiaproject.Celestia.metainfo.xml.in" "${METAINFO_ID}.metainfo.xml") + install( FILES celestiaui.xml celestia-logo.png DESTINATION "${DATADIR}" COMPONENT gtkgui ) install( - FILES celestia-gtk.desktop + FILES "${METAINFO_DESKTOP}" DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" COMPONENT gtkgui ) install( - FILES space.celestia.celestia_gtk.metainfo.xml + FILES "${METAINFO_ID}.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo" COMPONENT gtkgui ) diff --git a/src/celestia/gtk/data/space.celestia.celestia_gtk.metainfo.xml b/src/celestia/gtk/data/space.celestia.celestia_gtk.metainfo.xml deleted file mode 100644 index f53a22cf35..0000000000 --- a/src/celestia/gtk/data/space.celestia.celestia_gtk.metainfo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - space.celestia.celestia_gtk - MIT - GPL-2.0+ - Celestia (GTK) - Explore the universe - -

- Celestia provides photo-realistic, real-time, three-dimensional viewing of - the Solar System, the Galaxy and the Universe. -

-

- It is an easy to use, freely-distributed, multi-platform, open source, - software package which has become a valuable tool for astronomy education. - Used in homes, schools, museums and planetariums around the world, it also - is used as a visualization tool by space mission designers. -

-
- celestia-gtk.desktop - https://celestiaproject.space - - https://celestiaproject.space/images/gallery/cassini.jpg - https://celestiaproject.space/images/gallery/earth.jpg - https://celestiaproject.space/images/gallery/europa.jpg - https://celestiaproject.space/images/gallery/proxima.png - -
diff --git a/src/celestia/qt5/data/CMakeLists.txt b/src/celestia/qt5/data/CMakeLists.txt index c5b6fc4bfc..750feede5f 100644 --- a/src/celestia/qt5/data/CMakeLists.txt +++ b/src/celestia/qt5/data/CMakeLists.txt @@ -1,10 +1,15 @@ +set(METAINFO_ID "space.celestiaproject.Celestia-qt5") +set(METAINFO_NAME "Celestia (Qt5)") +set(METAINFO_DESKTOP "celestia-qt5.desktop") +configure_file("../../data/space.celestiaproject.Celestia.metainfo.xml.in" "${METAINFO_ID}.metainfo.xml") + install( - FILES celestia-qt5.desktop + FILES "${METAINFO_DESKTOP}" DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" COMPONENT qt5gui ) install( - FILES space.celestia.celestia_qt5.metainfo.xml + FILES "${METAINFO_ID}.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo" COMPONENT qt5gui ) diff --git a/src/celestia/qt5/data/space.celestia.celestia_qt5.metainfo.xml b/src/celestia/qt5/data/space.celestia.celestia_qt5.metainfo.xml deleted file mode 100644 index 5c248d7451..0000000000 --- a/src/celestia/qt5/data/space.celestia.celestia_qt5.metainfo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - space.celestia.celestia_qt5 - MIT - GPL-2.0+ - Celestia (Qt5) - Explore the universe - -

- Celestia provides photo-realistic, real-time, three-dimensional viewing of - the Solar System, the Galaxy and the Universe. -

-

- It is an easy to use, freely-distributed, multi-platform, open source, - software package which has become a valuable tool for astronomy education. - Used in homes, schools, museums and planetariums around the world, it also - is used as a visualization tool by space mission designers. -

-
- celestia-qt5.desktop - https://celestiaproject.space - - https://celestiaproject.space/images/gallery/cassini.jpg - https://celestiaproject.space/images/gallery/earth.jpg - https://celestiaproject.space/images/gallery/europa.jpg - https://celestiaproject.space/images/gallery/proxima.png - -
diff --git a/src/celestia/qt6/data/CMakeLists.txt b/src/celestia/qt6/data/CMakeLists.txt index 0cb00d1316..2fb671e204 100644 --- a/src/celestia/qt6/data/CMakeLists.txt +++ b/src/celestia/qt6/data/CMakeLists.txt @@ -1,10 +1,15 @@ +set(METAINFO_ID "space.celestiaproject.Celestia-qt6") +set(METAINFO_NAME "Celestia (Qt6)") +set(METAINFO_DESKTOP "celestia-qt6.desktop") +configure_file("../../data/space.celestiaproject.Celestia.metainfo.xml.in" "${METAINFO_ID}.metainfo.xml") + install( - FILES celestia-qt6.desktop + FILES "${METAINFO_DESKTOP}" DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" COMPONENT qt6gui ) install( - FILES space.celestia.celestia_qt6.metainfo.xml + FILES "${METAINFO_ID}.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo" COMPONENT qt6gui ) diff --git a/src/celestia/qt6/data/space.celestia.celestia_qt6.metainfo.xml b/src/celestia/qt6/data/space.celestia.celestia_qt6.metainfo.xml deleted file mode 100644 index 85bb10dbf6..0000000000 --- a/src/celestia/qt6/data/space.celestia.celestia_qt6.metainfo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - space.celestia.celestia_qt6 - MIT - GPL-2.0+ - Celestia (Qt6) - Explore the universe - -

- Celestia provides photo-realistic, real-time, three-dimensional viewing of - the Solar System, the Galaxy and the Universe. -

-

- It is an easy to use, freely-distributed, multi-platform, open source, - software package which has become a valuable tool for astronomy education. - Used in homes, schools, museums and planetariums around the world, it also - is used as a visualization tool by space mission designers. -

-
- celestia-qt6.desktop - https://celestiaproject.space - - https://celestiaproject.space/images/gallery/cassini.jpg - https://celestiaproject.space/images/gallery/earth.jpg - https://celestiaproject.space/images/gallery/europa.jpg - https://celestiaproject.space/images/gallery/proxima.png - -
diff --git a/src/celestia/sdl/data/CMakeLists.txt b/src/celestia/sdl/data/CMakeLists.txt index 96b72cc2b6..805ff3b236 100644 --- a/src/celestia/sdl/data/CMakeLists.txt +++ b/src/celestia/sdl/data/CMakeLists.txt @@ -1,10 +1,15 @@ +set(METAINFO_ID "space.celestiaproject.Celestia-sdl") +set(METAINFO_NAME "Celestia (SDL)") +set(METAINFO_DESKTOP "celestia-sdl.desktop") +configure_file("../../data/space.celestiaproject.Celestia.metainfo.xml.in" "${METAINFO_ID}.metainfo.xml") + install( - FILES celestia-sdl.desktop + FILES "${METAINFO_DESKTOP}" DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" COMPONENT sdlgui ) install( - FILES space.celestia.celestia_sdl.metainfo.xml + FILES "${METAINFO_ID}.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo" COMPONENT sdlgui ) diff --git a/src/celestia/sdl/data/space.celestia.celestia_sdl.metainfo.xml b/src/celestia/sdl/data/space.celestia.celestia_sdl.metainfo.xml deleted file mode 100644 index fd16861bcd..0000000000 --- a/src/celestia/sdl/data/space.celestia.celestia_sdl.metainfo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - space.celestia.celestia_sdl - MIT - GPL-2.0+ - Celestia (SDL) - Explore the universe - -

- Celestia provides photo-realistic, real-time, three-dimensional viewing of - the Solar System, the Galaxy and the Universe. -

-

- It is an easy to use, freely-distributed, multi-platform, open source, - software package which has become a valuable tool for astronomy education. - Used in homes, schools, museums and planetariums around the world, it also - is used as a visualization tool by space mission designers. -

-
- celestia-sdl.desktop - https://celestiaproject.space - - https://celestiaproject.space/images/gallery/cassini.jpg - https://celestiaproject.space/images/gallery/earth.jpg - https://celestiaproject.space/images/gallery/europa.jpg - https://celestiaproject.space/images/gallery/proxima.png - -
From 8505d4f226226cafcdf1867fb7a9bb18532d40e7 Mon Sep 17 00:00:00 2001 From: Levin Li Date: Sun, 18 Feb 2024 18:38:01 +0800 Subject: [PATCH 3/8] Remove setlocale for fmt calls --- src/celengine/overlay.h | 8 +++ src/celestia/celestiacore.cpp | 70 ++++++------------ src/celestia/celestiacore.h | 3 + src/celestia/hud.cpp | 131 ++++++++++++++++++++-------------- src/celestia/hud.h | 12 ++-- 5 files changed, 114 insertions(+), 110 deletions(-) diff --git a/src/celengine/overlay.h b/src/celengine/overlay.h index f7255b184c..8257a717ed 100644 --- a/src/celengine/overlay.h +++ b/src/celengine/overlay.h @@ -10,6 +10,7 @@ #pragma once +#include #include #include #include @@ -60,6 +61,13 @@ class Overlay void print(std::string_view); + template + void print(const std::locale& loc, std::string_view format, const T&... args) + { + static_assert(sizeof...(args) > 0); + print(fmt::format(loc, format, args...)); + } + template void print(std::string_view format, const T&... args) { diff --git a/src/celestia/celestiacore.cpp b/src/celestia/celestiacore.cpp index f5effddf15..e443160da3 100644 --- a/src/celestia/celestiacore.cpp +++ b/src/celestia/celestiacore.cpp @@ -33,6 +33,9 @@ #include #include +#if FMT_VERSION < 90000 +#include +#endif #include #include @@ -1206,12 +1209,12 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) Vector3d v = sim->getSelection().getPosition(sim->getTime()).offsetFromKm(sim->getObserver().getPosition()); int hours, mins; float secs; - string buf; + std::string buf; if (v.norm() >= 86400.0_c) { // Light travel time in years, if >= 1day - buf = fmt::sprintf(_("Light travel time: %.4f yr"), - astro::kilometersToLightYears(v.norm())); + buf = fmt::format(loc, _("Light travel time: {:.4f} yr"), + astro::kilometersToLightYears(v.norm())); } else { @@ -1219,13 +1222,13 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) getLightTravelDelay(v.norm(), hours, mins, secs); if (hours == 0) { - buf = fmt::sprintf(_("Light travel time: %d min %.1f s"), - mins, secs); + buf = fmt::format(loc, _("Light travel time: {} min {:.1f} s"), + mins, secs); } else { - buf = fmt::sprintf(_("Light travel time: %d h %d min %.1f s"), - hours, mins, secs); + buf = fmt::format(loc, _("Light travel time: {} h {} min {:.1f} s"), + hours, mins, secs); } } flash(buf, 2.0); @@ -1378,9 +1381,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) sim->setTimeScale(sim->getTimeScale() / CoarseTimeScaleFactor); else sim->setTimeScale(sim->getTimeScale() / FineTimeScaleFactor); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Time rate: %.6g"), sim->getTimeScale()); // XXX %'.12g - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Time rate: {:.6g}"), sim->getTimeScale()); // XXX %'.12g flash(buf); } break; @@ -1393,9 +1394,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) sim->setTimeScale(sim->getTimeScale() * CoarseTimeScaleFactor); else sim->setTimeScale(sim->getTimeScale() * FineTimeScaleFactor); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Time rate: %.6g"), sim->getTimeScale()); // XXX %'.12g - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Time rate: {:.6g}"), sim->getTimeScale()); flash(buf); } break; @@ -1511,10 +1510,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) { setFaintest(sim->getFaintestVisible() - 0.2f); notifyWatchers(FaintestChanged); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Magnitude limit: %.2f"), - sim->getFaintestVisible()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Magnitude limit: {:.2f}"), sim->getFaintestVisible()); flash(buf); } } @@ -1522,10 +1518,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) { renderer->setFaintestAM45deg(renderer->getFaintestAM45deg() - 0.1f); setFaintestAutoMag(); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Auto magnitude limit at 45 degrees: %.2f"), - renderer->getFaintestAM45deg()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Auto magnitude limit at 45 degrees: {:.2f}"), renderer->getFaintestAM45deg()); flash(buf); } break; @@ -1542,10 +1535,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) { setFaintest(sim->getFaintestVisible() + 0.2f); notifyWatchers(FaintestChanged); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Magnitude limit: %.2f"), - sim->getFaintestVisible()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Magnitude limit: {:.2f}"), sim->getFaintestVisible()); flash(buf); } } @@ -1553,10 +1543,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) { renderer->setFaintestAM45deg(renderer->getFaintestAM45deg() + 0.1f); setFaintestAutoMag(); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Auto magnitude limit at 45 degrees: %.2f"), - renderer->getFaintestAM45deg()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Auto magnitude limit at 45 degrees: {:.2f}"), renderer->getFaintestAM45deg()); flash(buf); } break; @@ -1572,10 +1559,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) else renderer->setAmbientLightLevel(0.0f); notifyWatchers(AmbientLightChanged); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Ambient light level: %.2f"), - renderer->getAmbientLightLevel()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Ambient light level: {:.2f}"), renderer->getAmbientLightLevel()); flash(buf); } break; @@ -1587,10 +1571,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) else renderer->setAmbientLightLevel(1.0f); notifyWatchers(AmbientLightChanged); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf(_("Ambient light level: %.2f"), - renderer->getAmbientLightLevel()); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Ambient light level: {:.2f}"), renderer->getAmbientLightLevel()); flash(buf); } break; @@ -1598,9 +1579,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) case '(': { Galaxy::decreaseLightGain(); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf("%s: %3.0f %%", _("Light gain"), Galaxy::getLightGain() * 100.0f); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Light gain: {:3.0f} %"), Galaxy::getLightGain() * 100.0f); flash(buf); notifyWatchers(GalaxyLightGainChanged); } @@ -1609,9 +1588,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers) case ')': { Galaxy::increaseLightGain(); - setlocale(LC_NUMERIC, ""); - string buf = fmt::sprintf("%s: %3.0f %%", _("Light gain"), Galaxy::getLightGain() * 100.0f); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Light gain: {:3.0f} %"), Galaxy::getLightGain() * 100.0f); flash(buf); notifyWatchers(GalaxyLightGainChanged); } @@ -2300,9 +2277,8 @@ void CelestiaCore::updateFOV(float newFOV, const std::optional if ((renderer->getRenderFlags() & Renderer::ShowAutoMag) != 0) { setFaintestAutoMag(); - setlocale(LC_NUMERIC, ""); - flash(fmt::sprintf(_("Magnitude limit: %.2f"), sim->getFaintestVisible())); - setlocale(LC_NUMERIC, "C"); + auto buf = fmt::format(loc, _("Magnitude limit: {:.2f}"), sim->getFaintestVisible()); + flash(buf); } } @@ -2368,7 +2344,7 @@ bool CelestiaCore::initSimulation(const fs::path& configFileName, } } - hud = std::make_unique(); + hud = std::make_unique(loc); #ifdef CELX initLuaHook(progressNotifier); diff --git a/src/celestia/celestiacore.h b/src/celestia/celestiacore.h index d95094ce9e..e0a658da84 100644 --- a/src/celestia/celestiacore.h +++ b/src/celestia/celestiacore.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -425,6 +426,8 @@ class CelestiaCore // : public Watchable Simulation* sim{ nullptr }; Renderer* renderer{ nullptr }; + std::locale loc{ "" }; + celestia::WindowMetrics metrics; std::unique_ptr hud; diff --git a/src/celestia/hud.cpp b/src/celestia/hud.cpp index b760b57d47..33c5f6d57e 100644 --- a/src/celestia/hud.cpp +++ b/src/celestia/hud.cpp @@ -21,6 +21,9 @@ #include #include +#if FMT_VERSION < 90000 +#include +#endif #include #include @@ -249,7 +252,7 @@ displaySpeed(const util::NumberFormatter& formatter, Overlay& overlay, float spe // degree, only minutes and seconds are shown; if the angle is less than one minute, only // seconds are displayed. std::string -angleToStr(double angle) +angleToStr(double angle, const std::locale& loc) { int degrees; int minutes; @@ -258,20 +261,20 @@ angleToStr(double angle) if (degrees > 0) { - return fmt::format("{}" UTF8_DEGREE_SIGN "{:02d}' {:.1f}\"", + return fmt::format(loc, "{}" UTF8_DEGREE_SIGN "{:02d}' {:.1f}\"", degrees, abs(minutes), abs(seconds)); } if (minutes > 0) { - return fmt::format("{:02d}' {:.1f}\"", abs(minutes), abs(seconds)); + return fmt::format(loc, "{:02d}' {:.1f}\"", abs(minutes), abs(seconds)); } - return fmt::format("{:.2f}\"", abs(seconds)); + return fmt::format(loc, "{:.2f}\"", abs(seconds)); } void -displayApparentDiameter(Overlay& overlay, double radius, double distance) +displayApparentDiameter(Overlay& overlay, double radius, double distance, const std::locale& loc) { if (distance < radius) return; @@ -281,52 +284,53 @@ displayApparentDiameter(Overlay& overlay, double radius, double distance) // Only display the arc size if it's less than 160 degrees and greater // than one second--otherwise, it's probably not interesting data. if (arcSize < 160.0 && arcSize > 1.0 / 3600.0) - overlay.printf(_("Apparent diameter: %s\n"), angleToStr(arcSize)); + overlay.printf(_("Apparent diameter: %s\n"), angleToStr(arcSize, loc)); } void -displayDeclination(Overlay& overlay, double angle) +displayDeclination(Overlay& overlay, double angle, const std::locale& loc) { int degrees; int minutes; double seconds; astro::decimalToDegMinSec(angle, degrees, minutes, seconds); - overlay.printf(_("Dec: %+d%s %02d' %.1f\"\n"), - std::abs(degrees), UTF8_DEGREE_SIGN, - std::abs(minutes), std::abs(seconds)); + overlay.print(loc, _("Dec: {:+d}{} {:02d}' {:.1f}\"\n"), + std::abs(degrees), UTF8_DEGREE_SIGN, + std::abs(minutes), std::abs(seconds)); } void -displayRightAscension(Overlay& overlay, double angle) +displayRightAscension(Overlay& overlay, double angle, const std::locale& loc) { int hours; int minutes; double seconds; astro::decimalToHourMinSec(angle, hours, minutes, seconds); - overlay.printf(_("RA: %dh %02dm %.1fs\n"), - hours, abs(minutes), abs(seconds)); + overlay.print(loc, _("RA: {}h {:02}m {:.1f}s\n"), + hours, abs(minutes), abs(seconds)); } void displayApparentMagnitude(Overlay& overlay, float absMag, - double distance) + double distance, + const std::locale& loc) { if (distance > 32.6167) { - float appMag = astro::absToAppMag(absMag, (float) distance); - overlay.printf(_("Apparent magnitude: %.1f\n"), appMag); + float appMag = astro::absToAppMag(absMag, static_cast(distance)); + overlay.print(loc, _("Apparent magnitude: {:.1f}\n"), appMag); } else { - overlay.printf(_("Absolute magnitude: %.1f\n"), absMag); + overlay.print(loc, _("Absolute magnitude: {:.1f}\n"), absMag); } } void -displayRADec(Overlay& overlay, const Eigen::Vector3d& v) +displayRADec(Overlay& overlay, const Eigen::Vector3d& v, const std::locale& loc) { double phi = std::atan2(v.x(), v.z()) - celestia::numbers::pi / 2; if (phi < 0.0) @@ -339,8 +343,8 @@ displayRADec(Overlay& overlay, const Eigen::Vector3d& v) theta = -celestia::numbers::pi * 0.5 - theta; - displayRightAscension(overlay, math::radToDeg(phi)); - displayDeclination(overlay, math::radToDeg(theta)); + displayRightAscension(overlay, math::radToDeg(phi), loc); + displayDeclination(overlay, math::radToDeg(theta), loc); } // Display nicely formatted planetocentric/planetographic coordinates. @@ -353,7 +357,8 @@ displayPlanetocentricCoords(const util::NumberFormatter& formatter, double longitude, double latitude, double altitude, - MeasurementSystem measurement) + MeasurementSystem measurement, + const std::locale& loc) { char ewHemi = ' '; char nsHemi = ' '; @@ -399,9 +404,9 @@ displayPlanetocentricCoords(const util::NumberFormatter& formatter, lat = std::abs(math::radToDeg(latitude)); } - overlay.printf(_("%.6f%c %.6f%c %s"), - lat, nsHemi, lon, ewHemi, - DistanceKmToStr(formatter, altitude, 5, measurement)); + overlay.print(loc, _("{:.6f}{} {:.6f}{} {}"), + lat, nsHemi, lon, ewHemi, + DistanceKmToStr(formatter, altitude, 5, measurement)); } void @@ -411,7 +416,8 @@ displayStarInfo(const util::NumberFormatter& formatter, const Star& star, const Universe& universe, double distance, - const HudSettings& hudSettings) + const HudSettings& hudSettings, + const std::locale& loc) { overlay.printf(_("Distance: %s\n"), DistanceLyToStr(formatter, distance, 5, hudSettings.measurementSystem)); @@ -422,12 +428,12 @@ displayStarInfo(const util::NumberFormatter& formatter, } else { - overlay.printf(_("Abs (app) mag: %.2f (%.2f)\n"), - star.getAbsoluteMagnitude(), - star.getApparentMagnitude(float(distance))); + overlay.print(loc, _("Abs (app) mag: {:.2f} ({:.2f})\n"), + star.getAbsoluteMagnitude(), + star.getApparentMagnitude(float(distance))); if (star.getLuminosity() > 1.0e-10f) - overlay.print(_("Luminosity: {}x Sun\n"), formatter.format(star.getLuminosity(), 3, SigDigitNum)); + overlay.print(loc, _("Luminosity: {}x Sun\n"), formatter.format(star.getLuminosity(), 3, SigDigitNum)); const char* star_class; switch (star.getSpectralType()[0]) @@ -444,7 +450,7 @@ displayStarInfo(const util::NumberFormatter& formatter, overlay.printf(_("Class: %s\n"), star_class); displayApparentDiameter(overlay, star.getRadius(), - astro::lightYearsToKilometers(distance)); + astro::lightYearsToKilometers(distance), loc); if (detail > 1) { @@ -483,7 +489,8 @@ void displayDSOinfo(const util::NumberFormatter& formatter, Overlay& overlay, const DeepSkyObject& dso, double distance, - MeasurementSystem measurement) + MeasurementSystem measurement, + const std::locale& loc) { overlay.print(dso.getDescription()); overlay.print("\n"); @@ -501,12 +508,13 @@ void displayDSOinfo(const util::NumberFormatter& formatter, overlay.printf(_("Radius: %s\n"), DistanceLyToStr(formatter, dso.getRadius(), 5, measurement)); - displayApparentDiameter(overlay, dso.getRadius(), distance); + displayApparentDiameter(overlay, dso.getRadius(), distance, loc); if (dso.getAbsoluteMagnitude() > DSO_DEFAULT_ABS_MAGNITUDE) { displayApparentMagnitude(overlay, dso.getAbsoluteMagnitude(), - distance); + distance, + loc); } } @@ -517,7 +525,8 @@ displayPlanetInfo(const util::NumberFormatter& formatter, Body& body, double t, const Eigen::Vector3d& viewVec, - const HudSettings& hudSettings) + const HudSettings& hudSettings, + const std::locale& loc) { double distanceKm = viewVec.norm(); double distance = distanceKm - body.getRadius(); @@ -532,7 +541,7 @@ displayPlanetInfo(const util::NumberFormatter& formatter, overlay.printf(_("Radius: %s\n"), DistanceKmToStr(formatter, body.getRadius(), 5, hudSettings.measurementSystem)); - displayApparentDiameter(overlay, body.getRadius(), distanceKm); + displayApparentDiameter(overlay, body.getRadius(), distanceKm, loc); // Display the phase angle @@ -568,7 +577,7 @@ displayPlanetInfo(const util::NumberFormatter& formatter, sunVec.normalize(); double cosPhaseAngle = std::clamp(sunVec.dot(viewVec.normalized()), -1.0, 1.0); double phaseAngle = acos(cosPhaseAngle); - overlay.printf(_("Phase angle: %.1f%s\n"), math::radToDeg(phaseAngle), UTF8_DEGREE_SIGN); + overlay.print(loc, _("Phase angle: {:.1f}{}\n"), math::radToDeg(phaseAngle), UTF8_DEGREE_SIGN); } } @@ -604,7 +613,8 @@ displayLocationInfo(const util::NumberFormatter& formatter, Overlay& overlay, const Location& location, double distanceKm, - MeasurementSystem measurement) + MeasurementSystem measurement, + const std::locale& loc) { overlay.printf(_("Distance: %s\n"), DistanceKmToStr(formatter, distanceKm, 5, measurement)); @@ -615,7 +625,7 @@ displayLocationInfo(const util::NumberFormatter& formatter, Eigen::Vector3f locPos = location.getPosition(); Eigen::Vector3d lonLatAlt = body->cartesianToPlanetocentric(locPos.cast()); displayPlanetocentricCoords(formatter, overlay, *body, - lonLatAlt.x(), lonLatAlt.y(), lonLatAlt.z(), measurement); + lonLatAlt.x(), lonLatAlt.y(), lonLatAlt.z(), measurement, loc); } std::string @@ -692,6 +702,16 @@ HudFonts::setTitleFont(const std::shared_ptr& f) m_titleEmWidth = engine::TextLayout::getTextWidth("M", f.get()); } +Hud::Hud(const std::locale& loc) : + loc(loc), +#ifdef USE_ICU + m_numberFormatter(std::make_unique()) +#else + m_numberFormatter(std::make_unique(loc)) +#endif +{ +} + Hud::~Hud() = default; int @@ -849,8 +869,6 @@ Hud::renderOverlay(const WindowMetrics& metrics, views.renderBorders(m_overlay.get(), metrics, timeInfo.currentTime); - setlocale(LC_NUMERIC, ""); - if (m_hudDetail > 0 && util::is_set(m_hudSettings.overlayElements, HudElements::ShowTime)) renderTimeInfo(metrics, sim, timeInfo); @@ -865,7 +883,7 @@ Hud::renderOverlay(const WindowMetrics& metrics, m_overlay->beginText(); m_overlay->print("\n"); if (m_hudSettings.showFPSCounter) - m_overlay->printf(_("FPS: %.1f\n"), timeInfo.fps); + m_overlay->print(loc, _("FPS: {:.1f}\n"), timeInfo.fps); else m_overlay->print("\n"); @@ -907,7 +925,6 @@ Hud::renderOverlay(const WindowMetrics& metrics, } m_overlay->end(); - setlocale(LC_NUMERIC, "C"); } void @@ -959,11 +976,11 @@ Hud::renderTimeInfo(const WindowMetrics& metrics, const Simulation* sim, const T } else if (std::abs(sim->getTimeScale()) > 1.0) { - m_overlay->printf(_("%.6g x faster"), sim->getTimeScale()); // XXX: %'.12g + m_overlay->print(loc, _("{:.6g} x faster"), sim->getTimeScale()); // XXX: %'.12g } else { - m_overlay->printf(_("%.6g x slower"), 1.0 / sim->getTimeScale()); // XXX: %'.12g + m_overlay->print(loc, _("{:.6g} x slower"), 1.0 / sim->getTimeScale()); // XXX: %'.12g } if (sim->getPauseState() == true) @@ -1039,7 +1056,7 @@ Hud::renderFrameInfo(const WindowMetrics& metrics, const Simulation* sim) // Field of view const Observer* activeObserver = sim->getActiveObserver(); float fov = math::radToDeg(activeObserver->getFOV()); - m_overlay->printf(_("FOV: %s (%.2fx)\n"), angleToStr(fov), activeObserver->getZoom()); + m_overlay->print(loc, _("FOV: {} ({:.2f}x)\n"), angleToStr(fov, loc), activeObserver->getZoom()); m_overlay->endText(); m_overlay->restorePos(); } @@ -1076,7 +1093,8 @@ Hud::renderSelectionInfo(const WindowMetrics& metrics, *(sel.star()), *(sim->getUniverse()), astro::kilometersToLightYears(v.norm()), - m_hudSettings); + m_hudSettings, + loc); } break; @@ -1096,7 +1114,8 @@ Hud::renderSelectionInfo(const WindowMetrics& metrics, *m_overlay, *sel.deepsky(), astro::kilometersToLightYears(v.norm()) - sel.deepsky()->getRadius(), - m_hudSettings.measurementSystem); + m_hudSettings.measurementSystem, + loc); } break; @@ -1119,7 +1138,8 @@ Hud::renderSelectionInfo(const WindowMetrics& metrics, *(sel.body()), sim->getTime(), v, - m_hudSettings); + m_hudSettings, + loc); } break; @@ -1132,7 +1152,8 @@ Hud::renderSelectionInfo(const WindowMetrics& metrics, *m_overlay, *(sel.location()), v.norm(), - m_hudSettings.measurementSystem); + m_hudSettings.measurementSystem, + loc); break; default: @@ -1158,7 +1179,7 @@ Hud::renderSelectionInfo(const WindowMetrics& metrics, // near the Earth. Eigen::Vector3d vEarth = sel.getPosition(sim->getTime()).offsetFromKm(Selection(earth).getPosition(sim->getTime())); vEarth = math::XRotation(astro::J2000Obliquity) * vEarth; - displayRADec(*m_overlay, vEarth); + displayRADec(*m_overlay, vEarth, loc); } } @@ -1210,10 +1231,10 @@ Hud::renderMovieCapture(const WindowMetrics& metrics, const MovieCapture& movieC m_overlay->moveBy(static_cast((metrics.width - movieWidth) / 2), static_cast((metrics.height + movieHeight) / 2 + 2)); m_overlay->beginText(); - m_overlay->printf(_("%dx%d at %.2f fps %s"), - movieWidth, movieHeight, - movieCapture.getFrameRate(), - movieCapture.recordingStatus() ? _("Recording") : _("Paused")); + m_overlay->print(loc, _("{}x{} at {:.2f} fps {}"), + movieWidth, movieHeight, + movieCapture.getFrameRate(), + movieCapture.recordingStatus() ? _("Recording") : _("Paused")); m_overlay->endText(); m_overlay->restorePos(); @@ -1225,7 +1246,7 @@ Hud::renderMovieCapture(const WindowMetrics& metrics, const MovieCapture& movieC auto min = static_cast(sec / 60.0f); sec -= static_cast(min) * 60.0f; m_overlay->beginText(); - m_overlay->print("{:3d}:{:05.2f}", min, sec); + m_overlay->print(loc, "{:3d}:{:05.2f}", min, sec); m_overlay->endText(); m_overlay->restorePos(); diff --git a/src/celestia/hud.h b/src/celestia/hud.h index 7387a6d930..6a24094fbd 100644 --- a/src/celestia/hud.h +++ b/src/celestia/hud.h @@ -13,9 +13,7 @@ #pragma once #include -#ifndef USE_ICU #include -#endif #include #include #include @@ -125,7 +123,7 @@ class Hud PassToScript = 0x02, }; - Hud() = default; + explicit Hud(const std::locale&); ~Hud(); int detail() const; @@ -175,12 +173,10 @@ class Hud std::unique_ptr m_image; + std::locale loc; + std::unique_ptr m_dateFormatter{ std::make_unique() }; -#ifdef USE_ICU - std::unique_ptr m_numberFormatter{ std::make_unique() }; -#else - std::unique_ptr m_numberFormatter{ std::make_unique(std::locale("")) }; -#endif + std::unique_ptr m_numberFormatter; celestia::astro::Date::Format m_dateFormat{ celestia::astro::Date::Locale }; int m_dateStrWidth{ 0 }; From 2f4bd198f596344710e85f4965498b8c51848bf5 Mon Sep 17 00:00:00 2001 From: Hleb Valoshka <375gnu@gmail.com> Date: Mon, 19 Feb 2024 14:33:13 +0200 Subject: [PATCH 4/8] [qt] fix compilation with GCC 7 --- src/celestia/qt/qtappwin.cpp | 9 +++------ src/celestia/qt/qtcelestialbrowser.cpp | 2 +- src/celestia/qt/qtdeepskybrowser.cpp | 2 +- src/celestia/qt/qteventfinder.cpp | 2 +- src/celestia/qt/qtsolarsystembrowser.cpp | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/celestia/qt/qtappwin.cpp b/src/celestia/qt/qtappwin.cpp index 2960c0ad53..ed56cc104c 100644 --- a/src/celestia/qt/qtappwin.cpp +++ b/src/celestia/qt/qtappwin.cpp @@ -343,14 +343,12 @@ CelestiaAppWindow::init(const CelestiaCommandLineOptions& options) toolsDock = new QDockWidget(_("Celestial Browser"), this); toolsDock->setObjectName("celestia-tools-dock"); - toolsDock->setAllowedAreas(Qt::LeftDockWidgetArea | - Qt::RightDockWidgetArea); + toolsDock->setAllowedAreas(static_cast(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea)); // Info browser for a selected object infoPanel = new InfoPanel(m_appCore, _("Info Browser"), this); infoPanel->setObjectName("info-panel"); - infoPanel->setAllowedAreas(Qt::LeftDockWidgetArea | - Qt::RightDockWidgetArea); + infoPanel->setAllowedAreas(static_cast(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea)); infoPanel->setVisible(false); // Create the various browser widgets @@ -387,8 +385,7 @@ CelestiaAppWindow::init(const CelestiaCommandLineOptions& options) eventFinder = new EventFinder(m_appCore, _("Event Finder"), this); eventFinder->setObjectName("event-finder"); - eventFinder->setAllowedAreas(Qt::LeftDockWidgetArea | - Qt::RightDockWidgetArea); + eventFinder->setAllowedAreas(static_cast(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea)); addDockWidget(Qt::LeftDockWidgetArea, eventFinder); eventFinder->setVisible(false); //addDockWidget(Qt::DockWidgetArea, eventFinder); diff --git a/src/celestia/qt/qtcelestialbrowser.cpp b/src/celestia/qt/qtcelestialbrowser.cpp index 70335f82e1..5217e73f1d 100644 --- a/src/celestia/qt/qtcelestialbrowser.cpp +++ b/src/celestia/qt/qtcelestialbrowser.cpp @@ -147,7 +147,7 @@ CelestialBrowser::StarTableModel::objectAtIndex(const QModelIndex& _index) const Qt::ItemFlags CelestialBrowser::StarTableModel::flags(const QModelIndex& /*unused*/) const { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return static_cast(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } // Override QAbstractTableModel::data() diff --git a/src/celestia/qt/qtdeepskybrowser.cpp b/src/celestia/qt/qtdeepskybrowser.cpp index 1f15a9b8d0..28efa33d2b 100644 --- a/src/celestia/qt/qtdeepskybrowser.cpp +++ b/src/celestia/qt/qtdeepskybrowser.cpp @@ -281,7 +281,7 @@ DeepSkyBrowser::DSOTableModel::objectAtIndex(const QModelIndex& _index) const Qt::ItemFlags DeepSkyBrowser::DSOTableModel::flags(const QModelIndex& /*unused*/) const { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return static_cast(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } // Override QAbstractTableModel::data() diff --git a/src/celestia/qt/qteventfinder.cpp b/src/celestia/qt/qteventfinder.cpp index 351f3e6ec7..9eba3f1e58 100644 --- a/src/celestia/qt/qteventfinder.cpp +++ b/src/celestia/qt/qteventfinder.cpp @@ -162,7 +162,7 @@ class EventFinder::EventTableModel : public QAbstractTableModel Qt::ItemFlags EventFinder::EventTableModel::flags(const QModelIndex& /*unused*/) const { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return static_cast(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } QVariant diff --git a/src/celestia/qt/qtsolarsystembrowser.cpp b/src/celestia/qt/qtsolarsystembrowser.cpp index 1f98dcf373..a7cebc1e91 100644 --- a/src/celestia/qt/qtsolarsystembrowser.cpp +++ b/src/celestia/qt/qtsolarsystembrowser.cpp @@ -622,7 +622,7 @@ SolarSystemBrowser::SolarSystemTreeModel::flags(const QModelIndex& index) const if (!index.isValid()) return {}; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return static_cast(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } // Override QAbstractTableModel::data() From da72aaebdfc74a3348483abe46066bc279643e11 Mon Sep 17 00:00:00 2001 From: Hleb Valoshka <375gnu@gmail.com> Date: Mon, 19 Feb 2024 14:37:14 +0200 Subject: [PATCH 5/8] Make GL_ARB_framebuffer_object mandatory It's impossible to compile Celestia for systems which have GL 2.1 but not framebuffers, because such systems (if they exist) have too old drivers, and the only reason for this is too old OS. But such systems are not supported by modern C++ compilers. --- src/celengine/framebuffer.h | 10 ----- src/celengine/glsupport.cpp | 8 +++- src/celengine/glsupport.h | 1 - src/celengine/render.cpp | 2 - src/celengine/texture.cpp | 44 +++------------------ src/tools/cmod/cmodview/modelviewwidget.cpp | 3 -- 6 files changed, 13 insertions(+), 55 deletions(-) diff --git a/src/celengine/framebuffer.h b/src/celengine/framebuffer.h index 802745940f..52f70bfabe 100644 --- a/src/celengine/framebuffer.h +++ b/src/celengine/framebuffer.h @@ -28,7 +28,6 @@ class FramebufferObject FramebufferObject& operator=(FramebufferObject&&) noexcept; ~FramebufferObject(); - static inline bool isSupported(); bool isValid() const; GLuint width() const { @@ -60,12 +59,3 @@ class FramebufferObject GLuint m_fboId; GLenum m_status; }; - -bool FramebufferObject::isSupported() -{ -#ifdef GL_ES - return true; -#else - return celestia::gl::ARB_framebuffer_object; -#endif -} diff --git a/src/celengine/glsupport.cpp b/src/celengine/glsupport.cpp index 17a9ca6ee4..f4d7fb8168 100644 --- a/src/celengine/glsupport.cpp +++ b/src/celengine/glsupport.cpp @@ -1,6 +1,8 @@ #include "glsupport.h" #include #include +#include +#include namespace celestia::gl { @@ -81,7 +83,11 @@ bool init(util::array_view ignore) noexcept OES_geometry_shader = check_extension(ignore, "GL_OES_geometry_shader") || check_extension(ignore, "GL_EXT_geometry_shader"); #else ARB_vertex_array_object = check_extension(ignore, "GL_ARB_vertex_array_object"); - ARB_framebuffer_object = check_extension(ignore, "GL_ARB_framebuffer_object") || check_extension(ignore, "GL_EXT_framebuffer_object"); + if (!has_extension("GL_ARB_framebuffer_object")) + { + fmt::print(_("Mandatory extension GL_ARB_framebuffer_object is missing!\n")); + return false; + } #endif ARB_shader_texture_lod = check_extension(ignore, "GL_ARB_shader_texture_lod"); EXT_texture_compression_s3tc = check_extension(ignore, "GL_EXT_texture_compression_s3tc"); diff --git a/src/celengine/glsupport.h b/src/celengine/glsupport.h index dce2d25483..9cfbcb0e4f 100644 --- a/src/celengine/glsupport.h +++ b/src/celengine/glsupport.h @@ -49,7 +49,6 @@ extern CELAPI bool OES_texture_border_clamp; //NOSONAR extern CELAPI bool OES_geometry_shader; //NOSONAR #else extern CELAPI bool ARB_vertex_array_object; //NOSONAR -extern CELAPI bool ARB_framebuffer_object; //NOSONAR #endif extern CELAPI GLint maxPointSize; //NOSONAR extern CELAPI GLint maxTextureSize; //NOSONAR diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index ff1a09f9c7..29cdc1283e 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -4811,8 +4811,6 @@ Renderer::createShadowFBO() void Renderer::setShadowMapSize(unsigned size) { - if (!FramebufferObject::isSupported()) - return; m_shadowMapSize = std::min(size, static_cast(gl::maxTextureSize)); if (m_shadowFBO != nullptr && m_shadowMapSize == m_shadowFBO->width()) return; diff --git a/src/celengine/texture.cpp b/src/celengine/texture.cpp index 12953ff4df..7742e14b40 100644 --- a/src/celengine/texture.cpp +++ b/src/celengine/texture.cpp @@ -485,10 +485,6 @@ ImageTexture::ImageTexture(const Image& img, } bool genMipmaps = mipmap && !precomputedMipMaps; -#ifndef GL_ES - if (genMipmaps && !FramebufferObject::isSupported()) - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); -#endif if (mipmap) { @@ -511,7 +507,7 @@ ImageTexture::ImageTexture(const Image& img, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); #endif } - if (genMipmaps && FramebufferObject::isSupported()) + if (genMipmaps) glGenerateMipmap(GL_TEXTURE_2D); alpha = img.hasAlpha(); @@ -689,25 +685,9 @@ TiledTexture::TiledTexture(const Image& img, } } + LoadMiplessTexture(*tile, GL_TEXTURE_2D); if (mipmap) - { - if (FramebufferObject::isSupported()) - { - LoadMiplessTexture(*tile, GL_TEXTURE_2D); - glGenerateMipmap(GL_TEXTURE_2D); - } -#ifndef GL_ES - else - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - LoadMiplessTexture(*tile, GL_TEXTURE_2D); - } -#endif - } - else - { - LoadMiplessTexture(*tile, GL_TEXTURE_2D); - } + glGenerateMipmap(GL_TEXTURE_2D); } } } @@ -810,29 +790,17 @@ CubeMap::CubeMap(celestia::util::array_view faces) : bool genMipmaps = mipmap && !precomputedMipMaps; -#if !defined(GL_ES) - if (genMipmaps && !FramebufferObject::isSupported()) - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE); -#endif - for (int i = 0; i < 6; i++) { auto targetFace = static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); const Image* face = faces[i]; - if (mipmap) - { - if (precomputedMipMaps) - LoadMipmapSet(*face, targetFace); - else - LoadMiplessTexture(*face, targetFace); - } + if (mipmap && precomputedMipMaps) + LoadMipmapSet(*face, targetFace); else - { LoadMiplessTexture(*face, targetFace); - } } - if (genMipmaps && FramebufferObject::isSupported()) + if (genMipmaps) glGenerateMipmap(GL_TEXTURE_CUBE_MAP); } diff --git a/src/tools/cmod/cmodview/modelviewwidget.cpp b/src/tools/cmod/cmodview/modelviewwidget.cpp index f1189e86c1..7588991611 100644 --- a/src/tools/cmod/cmodview/modelviewwidget.cpp +++ b/src/tools/cmod/cmodview/modelviewwidget.cpp @@ -904,9 +904,6 @@ ModelViewWidget::setAmbientLight(bool enable) void ModelViewWidget::setShadows(bool enable) { - if (!FramebufferObject::isSupported()) - return; - if (enable != m_shadowsEnabled) { m_shadowsEnabled = enable; From 727ba15075ed0e7e218fed030f596e844f3eaa2e Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:52:28 +0200 Subject: [PATCH 6/8] Updates for file po/celestia.pot in bg --- po/bg.po | 515 ++++++++++++++++++++++--------------------------------- 1 file changed, 207 insertions(+), 308 deletions(-) diff --git a/po/bg.po b/po/bg.po index cee3044adf..06cfddf180 100644 --- a/po/bg.po +++ b/po/bg.po @@ -2,11 +2,11 @@ # Copyright (C) YEAR Celestia Development Team # This file is distributed under the same license as the celestia package. # FIRST AUTHOR , YEAR. -# +# # Translators: -# Hleb Valoshka <375gnu@gmail.com>, 2021 -# Georgi Georgiev (Жоро) , 2023 -# +# Hleb Valoshka <375gnu@gmail.com>, 2023 +# Georgi Georgiev (RacerBG) , 2024 +# #, fuzzy msgid "" msgstr "" @@ -14,13 +14,12 @@ msgstr "" "Report-Msgid-Bugs-To: team@celestiaproject.space\n" "POT-Creation-Date: 2023-12-17 11:09+0100\n" "PO-Revision-Date: 2018-11-02 18:33+0000\n" -"Last-Translator: Georgi Georgiev (Жоро) , 2023\n" -"Language-Team: Bulgarian (https://app.transifex.com/celestia/teams/93131/" -"bg/)\n" -"Language: bg\n" +"Last-Translator: Georgi Georgiev (RacerBG) , 2024\n" +"Language-Team: Bulgarian (https://app.transifex.com/celestia/teams/93131/bg/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: bg\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../src/celastro/date.cpp:486 @@ -31,27 +30,25 @@ msgstr "ЛЧВ" msgid "STD" msgstr "СЧВ" -#. #. // Put AbsMag = avgAbsMag for Add-ons without AbsMag entry #. for (int i = 0; i < nDSOs; ++i) #. { #. if(DSOs[i]->getAbsoluteMagnitude() == DSO_DEFAULT_ABS_MAGNITUDE) #. DSOs[i]->setAbsoluteMagnitude((float)avgAbsMag); #. } -#. #: ../src/celengine/dsodb.cpp:333 msgid "Loaded {} deep space objects\n" -msgstr "Заредени са {} обекти от дълбокия космос\n" +msgstr "Заредени са {} обекта от дълбокия космос\n" #: ../src/celengine/galaxy.cpp:95 #, c-format msgid "Galaxy (Hubble type: %s)" -msgstr "Галактика (спецификация на Хъбъл: %s)" +msgstr "Галактика (тип: %s)" #: ../src/celengine/globular.cpp:70 #, c-format, qt-format msgid "Globular (core radius: %4.2f', King concentration: %4.2f)" -msgstr "Кълбовиден (размер на ядрото: %4.2f', плътност: %4.2f)" +msgstr "Кълбовиден (радиус на ядрото: %4.2f', плътност: %4.2f)" #: ../src/celengine/meshmanager.cpp:451 msgid "Loading model: {}\n" @@ -59,22 +56,21 @@ msgstr "Зареждане на модел: {}\n" #: ../src/celengine/meshmanager.cpp:466 msgid "Unknown model format '{}'\n" -msgstr "" +msgstr "Неизвестен формат на модела „{}“\n" #: ../src/celengine/meshmanager.cpp:472 msgid "Error loading model '{}'\n" -msgstr "Грешка при зареждане на модел „{}“\n" +msgstr "Грешка при зареждане на модела „{}“\n" #. Display some statics for the model #: ../src/celengine/meshmanager.cpp:493 msgid "" " Model statistics: {} vertices, {} primitives, {} materials ({} unique)\n" -msgstr "" -"Данни за модела: {} върхове, {} примитиви, {} материали ({} уникални)\n" +msgstr "Данни за модела: {} върхове, {} примитиви, {} материали ({} уникални)\n" #: ../src/celengine/modelgeometry.cpp:186 msgid "Mesh index {} is higher than VBO count {}!" -msgstr "" +msgstr "Индексът на мрежата {} е по-голям от броя на VBO {}!" #: ../src/celengine/nebula.cpp:33 msgid "Nebula" @@ -86,39 +82,39 @@ msgstr "Разсеян куп" #: ../src/celengine/solarsys.cpp:104 msgid "Error in .ssc file (line {}): {}\n" -msgstr "Грешка в „.ssc“ файла (линия {}): {}\n" +msgstr "Грешка в .ssc файла (линия {}): {}\n" #: ../src/celengine/solarsys.cpp:745 msgid "Ring system needs inner and outer radii.\n" -msgstr "" +msgstr "Пръстеновата система се нуждае от вътрешен и външен радиус.\n" #: ../src/celengine/solarsys.cpp:837 msgid "Invalid SemiAxes value for object {}: [{}, {}, {}]\n" -msgstr "" +msgstr "Невалидна стойност на полуоста за обекта {}: [{}, {}, {}]\n" #: ../src/celengine/solarsys.cpp:872 msgid "Invalid Oblateness value for object {}: {}\n" -msgstr "" +msgstr "Невалидна стойност на сплеснатост за обекта {}: {}\n" #: ../src/celengine/solarsys.cpp:926 msgid "Incorrect GeomAlbedo value: {}\n" -msgstr "Неправилна стойност на „GeomAlbedo“: {}\n" +msgstr "Неправилна стойност на геометричното албедо: {}\n" #: ../src/celengine/solarsys.cpp:935 msgid "Incorrect Reflectivity value: {}\n" -msgstr "Неправилна стойност на „Reflectivity“: {}\n" +msgstr "Неправилна стойност на отражателната способност: {}\n" #: ../src/celengine/solarsys.cpp:943 msgid "Incorrect BondAlbedo value: {}\n" -msgstr "Неправилна стойност на „BondAlbedo“: {}\n" +msgstr "Неправилна стойност на сферичното албедо: {}\n" #: ../src/celengine/solarsys.cpp:985 msgid "Atmosphere must be an associative array.\n" -msgstr "" +msgstr "Атмосферата трябва да е асоциативен масив.\n" #: ../src/celengine/solarsys.cpp:994 msgid "Rings must be an associative array.\n" -msgstr "" +msgstr "Пръстените трябва да са асоциативен масив.\n" #: ../src/celengine/solarsys.cpp:1205 ../src/celengine/solarsys.cpp:1262 #, c-format @@ -140,7 +136,7 @@ msgstr "неточно местоположение" #: ../src/celengine/stardb.cpp:346 msgid "Error in .stc file (line {}): {}\n" -msgstr "Грешка в „.stc“ файла (линия {}): {}\n" +msgstr "Грешка в .stc файла (линия {}): {}\n" #: ../src/celengine/stardb.cpp:760 msgid "Bad spectral type in star database, star #{}\n" @@ -152,20 +148,20 @@ msgstr "{} звезди в двоичната база от данни\n" #: ../src/celengine/stardb.cpp:1071 msgid "Bad header for cross index\n" -msgstr "Неточна заглавка за кръстосаното индексиране\n" +msgstr "Неточна заглавка за кръстосания индекс\n" #: ../src/celengine/stardb.cpp:1079 msgid "Bad version for cross index\n" -msgstr "Неточна версия за кръстосаното индексиране\n" +msgstr "Неточна версия за кръстосания индекс\n" #: ../src/celengine/stardb.cpp:1096 msgid "Loading cross index failed\n" -msgstr "Зареждането на кръстосаното индексиране се провали\n" +msgstr "Зареждането на кръстосания индекс се провали\n" #: ../src/celengine/stardb.cpp:1107 -#, fuzzy msgid "Loading cross index failed - unexpected EOF\n" -msgstr "Зареждането на кръстосаното индексиране дава грешка при {}\n" +msgstr "" +"Зареждането на кръстосания индекс е неуспешно – неочакван край на файла\n" #: ../src/celengine/stardb.cpp:1137 msgid "Total star count: {}\n" @@ -218,27 +214,23 @@ msgstr "Създаване на обикновена текстура: {}х{}\n" #: ../src/celephem/sampfile.cpp:46 msgid "Skipping out-of-order samples in {}.\n" -msgstr "" +msgstr "Пропускане на неподредените примери в {}.\n" #: ../src/celephem/sampfile.cpp:58 -#, fuzzy msgid "No samples found in sample file {}.\n" -msgstr "Грешка при отваряне на изображение {}.\n" +msgstr "Няма намерени примери в примерния файл {}.\n" #: ../src/celephem/sampfile.cpp:67 -#, fuzzy msgid "Error reading sample file {}.\n" -msgstr "Грешка при четене на файла с фаворити {}.\n" +msgstr "Грешка при четене на примерния файл {}.\n" #: ../src/celephem/sampfile.cpp:74 -#, fuzzy msgid "Error opening ASCII sample file {}.\n" -msgstr "Грешка при отваряне на изображение {}.\n" +msgstr "Грешка при отваряне на примерния файл ASCII {}.\n" #: ../src/celephem/sampfile.cpp:81 -#, fuzzy msgid "Error finding data in ASCII sample file {}.\n" -msgstr "Грешка при отваряне на астеризмите {}.\n" +msgstr "Грешка при четене на данните в примерния файл ASCII {}.\n" #: ../src/celephem/samporbit.cpp:624 ../src/tools/xyzv2bin/bin2xyzv.cpp:35 msgid "Error reading header of {}.\n" @@ -246,31 +238,27 @@ msgstr "Грешка при четене на заглавката от {}.\n" #: ../src/celephem/samporbit.cpp:630 ../src/tools/xyzv2bin/bin2xyzv.cpp:41 msgid "Bad binary xyzv file {}.\n" -msgstr "Неточен бинарен файл „xyzv“ {}.\n" +msgstr "Неточен двоичен файл xyzv {}.\n" #: ../src/celephem/samporbit.cpp:638 -#, fuzzy msgid "Unsupported byte order {}, expected {} in {}.\n" -msgstr "Неподдържан байтов ред {}, очакван {}.\n" +msgstr "Неподдържан ред на байтовете {}, очакван {} в {}.\n" #: ../src/celephem/samporbit.cpp:647 -#, fuzzy msgid "Unsupported digits number {}, expected {} in {}.\n" -msgstr "Неподдържано число {}, очаквано {}.\n" +msgstr "Неподдържан брой числа {}, очакван {} в {}.\n" #: ../src/celephem/samporbit.cpp:656 msgid "Invalid record count {} in {}.\n" -msgstr "" +msgstr "Невалиден брой на записите {} в {}.\n" #: ../src/celephem/samporbit.cpp:712 -#, fuzzy msgid "Error opening binary sample file {}.\n" -msgstr "Грешка при отваряне на изображение {}.\n" +msgstr "Грешка при отваряне на двоичния примерен файл {}.\n" #: ../src/celephem/samporbit.cpp:718 -#, fuzzy msgid "Could not read XYZV binary file {}.\n" -msgstr "Изображението не може да бъде запазено." +msgstr "Двоичният файл XYZV не може да бъде прочетен {}.\n" #: ../src/celestia/celestiacore.cpp:110 ../src/celestia/scriptmenu.cpp:108 #: ../src/celscript/lua/luascript.cpp:173 @@ -384,22 +372,19 @@ msgstr "Продължи" #: ../src/celestia/celestiacore.cpp:1118 msgid "Star color: Blackbody D65" -msgstr "Звезден цвят: Цветови стандарт D65" +msgstr "Звезден цвят: Чернотелен D65" #: ../src/celestia/celestiacore.cpp:1124 -#, fuzzy msgid "Star color: Blackbody (Solar Whitepoint)" -msgstr "Звезден цвят: Цветови стандарт D65" +msgstr "Звезден цвят: Чернотелен (Бяла точка от Слънцето)" #: ../src/celestia/celestiacore.cpp:1130 -#, fuzzy msgid "Star color: Blackbody (Vega Whitepoint)" -msgstr "Звезден цвят: Цветови стандарт D65" +msgstr "Звезден цвят: Чернотелен (Бяла точка от Вега)" #: ../src/celestia/celestiacore.cpp:1136 -#, fuzzy msgid "Star color: Classic" -msgstr "Звездни цветове" +msgstr "Звезден цвят: Класически" #. Light travel time in years, if >= 1day #: ../src/celestia/celestiacore.cpp:1169 @@ -508,23 +493,23 @@ msgstr "Изгледът е добавен" #: ../src/celestia/celestiacore.cpp:2242 msgid "Skipping solar system catalog: {}\n" -msgstr "Пропускане на системен каталог: {}\n" +msgstr "Пропускане на системния каталог: {}\n" #: ../src/celestia/celestiacore.cpp:2245 msgid "Loading solar system catalog: {}\n" -msgstr "Зареждане на системен каталог: {}\n" +msgstr "Зареждане на системния каталог: {}\n" #: ../src/celestia/celestiacore.cpp:2288 msgid "Skipping {} catalog: {}\n" -msgstr "Пропускане на {} каталог: {}\n" +msgstr "Пропускане на каталога {}: {}\n" #: ../src/celestia/celestiacore.cpp:2291 msgid "Loading {} catalog: {}\n" -msgstr "Зареждане на {} каталог: {}\n" +msgstr "Зареждане на каталога {}: {}\n" #: ../src/celestia/celestiacore.cpp:2299 msgid "Error reading {} catalog file: {}\n" -msgstr "Грешка при четене на {} каталог: {}\n" +msgstr "Грешка при четене на каталога {}: {}\n" #: ../src/celestia/celestiacore.cpp:2333 msgid "Error reading configuration file." @@ -532,7 +517,7 @@ msgstr "Грешка при четене на конфигурационния #: ../src/celestia/celestiacore.cpp:2347 msgid "Initialization of SPICE library failed." -msgstr "Създаването на библиотеката „SPICE“ се провали." +msgstr "Създаването на библиотеката SPICE се провали." #: ../src/celestia/celestiacore.cpp:2392 msgid "Cannot read star database." @@ -564,11 +549,11 @@ msgstr "Грешка при зареждане на шрифта, текстът #: ../src/celestia/celestiacore.cpp:2739 msgid "Error reading cross index {}\n" -msgstr "Грешка при четене на кръстосаното индексиране {}\n" +msgstr "Грешка при четене на кръстосания индекс {}\n" #: ../src/celestia/celestiacore.cpp:2741 msgid "Loaded cross index {}\n" -msgstr "Кръстосаното индексиране {} е заредено\n" +msgstr "Кръстосаният индекс {} е зареден\n" #: ../src/celestia/celestiacore.cpp:2758 msgid "Error reading star names file\n" @@ -605,12 +590,12 @@ msgstr "Грешка при отваряне на астеризмите {}.\n" #: ../src/celestia/gtk/actions.cpp:90 ../src/celestia/qt/qtappwin.cpp:747 #: ../src/celestia/win32/winmoviecapture.cpp:68 msgid "Lossless" -msgstr "Без загуба" +msgstr "Некомпресирано" #: ../src/celestia/gtk/actions.cpp:91 ../src/celestia/qt/qtappwin.cpp:748 #: ../src/celestia/win32/winmoviecapture.cpp:69 msgid "Lossy (H.264)" -msgstr "Със загуба (H.264)" +msgstr "Компресирано (H.264)" #: ../src/celestia/gtk/actions.cpp:745 ../src/celestia/qt/qtappwin.cpp:1259 #: ../src/celestia/qt/qtappwin.cpp:1676 @@ -621,7 +606,7 @@ msgstr "За „Celestia“" #: ../src/celestia/gtk/actions.cpp:1107 #: ../src/celestia/win32/winfiledlgs.cpp:97 msgid "Please use a name ending in '.jpg' or '.png'." -msgstr "Моля, използвайте име, завършващо с „.jpg“ или „.png“." +msgstr "Моля, използвайте име, завършващо с .jpg или .png." #: ../src/celestia/helper.cpp:106 ../src/celestia/helper.cpp:115 #, c-format @@ -639,14 +624,14 @@ msgid "Renderer: %s\n" msgstr "Възпроизвеждане: %s\n" #: ../src/celestia/helper.cpp:118 -#, fuzzy, c-format +#, c-format msgid "Color component: %s\n" -msgstr "Елементи" +msgstr "Цветен компонент: %s\n" #: ../src/celestia/helper.cpp:121 -#, fuzzy, c-format +#, c-format msgid "Depth component: %s\n" -msgstr "Елементи" +msgstr "Дълбочинен компонент: %s\n" #: ../src/celestia/helper.cpp:124 #, c-format @@ -661,12 +646,12 @@ msgstr "Максимален размер на текстурите: %s\n" #: ../src/celestia/helper.cpp:130 #, c-format msgid "Point size range: %s - %s\n" -msgstr "Диапазон на размера на точките: %s - %s\n" +msgstr "Диапазон на размера на точките: %s – %s\n" #: ../src/celestia/helper.cpp:133 #, c-format msgid "Line width range: %s - %s\n" -msgstr "Диапазон на размера на линиите: %s - %s\n" +msgstr "Диапазон на размера на линиите: %s – %s\n" #: ../src/celestia/helper.cpp:136 #, c-format @@ -751,22 +736,18 @@ msgid "Rotation period: {} {}\n" msgstr "Период на въртене: {} {}\n" #: ../src/celestia/hud.cpp:182 -#, fuzzy msgid "Mass: {} lb\n" -msgstr "Маса: {} лб\n" +msgstr "Маса: {} фунта\n" #: ../src/celestia/hud.cpp:185 -#, fuzzy msgid "Mass: {} kg\n" msgstr "Маса: {} кг\n" #: ../src/celestia/hud.cpp:189 -#, fuzzy msgid "Mass: {} Mj\n" msgstr "Маса: {} Юп\n" #: ../src/celestia/hud.cpp:192 -#, fuzzy msgid "Mass: {} Me\n" msgstr "Маса: {} Зем\n" @@ -875,7 +856,7 @@ msgstr "Радиус: {}\n" #: ../src/celestia/hud.cpp:476 msgid "Planetary companions present\n" -msgstr "Налични са планетарни спътници\n" +msgstr "Присъстват планетарни спътници\n" #: ../src/celestia/hud.cpp:496 #, c-format @@ -893,14 +874,12 @@ msgid "Phase angle: %.1f%s\n" msgstr "Фазов ъгъл: %.1f%s\n" #: ../src/celestia/hud.cpp:585 -#, fuzzy msgid "Density: {} lb/ft³\n" -msgstr "Плътност: %.2f х 1000 лб/фт^3\n" +msgstr "Плътност: {} фунта/фт³\n" #: ../src/celestia/hud.cpp:590 -#, fuzzy msgid "Density: {} kg/m³\n" -msgstr "Плътност: %.2f х 1000 кг/м^3\n" +msgstr "Плътност: {} кг/м³\n" #: ../src/celestia/hud.cpp:596 #, c-format @@ -1003,17 +982,15 @@ msgstr "F11 за Старт и Пауза F12 за Спиране" #. TRANSLATORS: fps == frames per second #: ../src/celestia/qt/qtappwin.cpp:209 -#, fuzzy msgctxt "fps" msgid "Auto" -msgstr "Автоматично" +msgstr "Автоматична" #. TRANSLATORS: fps == frames per second #: ../src/celestia/qt/qtappwin.cpp:216 -#, fuzzy msgctxt "fps" msgid "Custom" -msgstr "Персонализирано" +msgstr "Персонализирана" #: ../src/celestia/qt/qtappwin.cpp:257 msgid "Error getting path for log filename!" @@ -1021,8 +998,8 @@ msgstr "Грешка при получаване на пътя за името #: ../src/celestia/qt/qtappwin.cpp:272 msgid "" -"Celestia is unable to run because the data directory was not found, probably " -"due to improper installation." +"Celestia is unable to run because the data directory was not found, probably" +" due to improper installation." msgstr "" "„Celestia“ не успя да стартира, защото папката с данни липсва, вероятната " "причина е неправилна инсталация." @@ -1060,7 +1037,8 @@ msgstr "Звезди" msgid "Deep Sky Objects" msgstr "Обекти от дълбокото небе" -#: ../src/celestia/qt/qtappwin.cpp:393 ../src/celestia/qt/qteventfinder.cpp:414 +#: ../src/celestia/qt/qtappwin.cpp:393 +#: ../src/celestia/qt/qteventfinder.cpp:414 #: ../src/celestia/qt/qteventfinder.cpp:424 msgid "Event Finder" msgstr "Търсач на събития" @@ -1086,11 +1064,11 @@ msgstr "Цял екран" #: ../src/celestia/qt/qtappwin.cpp:466 msgid "ALT+Enter" -msgstr "" +msgstr "ALT+Enter" #: ../src/celestia/qt/qtappwin.cpp:466 msgid "ALT+Return" -msgstr "" +msgstr "ALT+Return" #: ../src/celestia/qt/qtappwin.cpp:626 msgid "Error opening bookmarks file" @@ -1161,42 +1139,43 @@ msgid "Celestia Scripts (*.celx *.cel)" msgstr "Скриптове на „Celestia“ (*.celx *.cel)" #: ../src/celestia/qt/qtappwin.cpp:974 -#, fuzzy msgid "Celestia Scripts (*.cel)" -msgstr "Скриптове на „Celestia“ (*.celx *.cel)" +msgstr "Скриптове на „Celestia“ (*.cel)" #: ../src/celestia/qt/qtappwin.cpp:1148 msgid "New bookmark" msgstr "Нова отметка" #: ../src/celestia/qt/qtappwin.cpp:1209 -#, fuzzy, qt-format +#, qt-format msgid "" -"

Celestia 1.7.0

Development snapshot, commit %1.

Built for %2 bit CPU
Using %3 %4
Built against Qt library: " -"%5
NAIF kernels are %7
AVIF images are %8
Runtime Qt version: %6

Copyright (C) 2001-2023 by the Celestia Development Team.
Celestia " -"is free software. You can redistribute it and/or modify it under the terms " -"of the GNU General Public License as published by the Free Software " -"Foundation; either version 2 of the License, or (at your option) any later " -"version.

Main site: https://" -"celestiaproject.space/
Forum: https://celestiaproject.space/forum/
GitHub project: https://github.com/" -"CelestiaProject/Celestia

" +"

Celestia 1.7.0

Development snapshot, commit " +"%1.

Built for %2 bit CPU
Using %3 %4
Built against Qt " +"library: %5
NAIF kernels are %7
AVIF images are %8
Runtime Qt " +"version: %6

Copyright (C) 2001-2023 by the Celestia Development " +"Team.
Celestia is free software. You can redistribute it and/or modify it" +" under the terms of the GNU General Public License as published by the Free " +"Software Foundation; either version 2 of the License, or (at your option) " +"any later version.

Main site: https://celestiaproject.space/
Forum:" +" https://celestiaproject.space/forum/
GitHub" +" project: https://github.com/CelestiaProject/Celestia

" msgstr "" -"

„Celestia“ 1.7

В процес на разработка, компилация %1." -"

За %2 битови процесори
Използва %3 %4
Създадена е с Qt: " -"%5
Ядрата NAIF са %7
Изображенията AVIF са %8

Версия на Qt: %6

Авторско право (C) 2001-2021, Екипа на „Celestia“.
„Celestia“ е " -"безплатен софтуер. Може да се разпространява и/или променя под условията на " -"„GNU General Public License“, който е публикуван от „Фондацията за свободен " -"софтуер“, версия 2 или всяка по-нова версия на Лиценза (по Ваша преценка).

Сайт: https://" -"celestiaproject.space/
Форум: https://celestiaproject.space/forum/
„GitHub“: https://github.com/" -"CelestiaProject/Celestia

" +"

„Celestia“ 1.7.0

В процес на разработка, компилация " +"%1.

За %2 битови процесори
Използва %3 %4
Създадена с Qt:" +" %5
Ядрата NAIF са %7
Изображенията AVIF са %8
Версия на Qt: " +"%6

Авторско право (C) 2001-2023, Екипът на „Celestia“.
„Celestia“ е" +" безплатен софтуер. Може да се разпространява и/или променя под условията на" +" „GNU General Public License“, който е публикуван от „Фондацията за свободен" +" софтуер“, версия 2 или всяка по-нова версия на Лиценза (по Ваша " +"преценка).

Сайт: https://celestiaproject.space/
Форум:" +" https://celestiaproject.space/forum/
„GitHub“:" +" https://github.com/CelestiaProject/Celestia

" #: ../src/celestia/qt/qtappwin.cpp:1245 msgid "Unknown compiler" @@ -1478,18 +1457,16 @@ msgid "&Help" msgstr "&Помощ" #: ../src/celestia/qt/qtappwin.cpp:1664 -#, fuzzy msgid "Celestia Guide" -msgstr "„Celestia“" +msgstr "Ръководство на „Celestia“" #: ../src/celestia/qt/qtappwin.cpp:1667 -#, fuzzy msgid "Celestia Wiki" -msgstr "„Celestia“" +msgstr "Уикипедия на „Celestia“" #: ../src/celestia/qt/qtappwin.cpp:1672 msgid "OpenGL Info" -msgstr "Информация за „OpenGL“" +msgstr "Информация за OpenGL" #: ../src/celestia/qt/qtappwin.cpp:1693 msgid "Add Bookmark..." @@ -1513,7 +1490,7 @@ msgid "" "Loading data files: %1\n" "\n" msgstr "" -"Зареждане на файлове с данни: %1\n" +"Зареждане на файловете с данни: %1\n" "\n" #: ../src/celestia/qt/qtappwin.cpp:1779 @@ -1547,7 +1524,7 @@ msgstr "Добави отметките в тази папка за да се п #: ../src/celestia/qt/qtbookmark.cpp:644 msgid "Error reading bookmarks file" -msgstr "Грешка при четене на файла с отметки" +msgstr "Грешка при четене на файла с отметките" #. Create a subtree item called "Bookmarks" #: ../src/celestia/qt/qtbookmark.cpp:761 @@ -1569,7 +1546,8 @@ msgid "System time at activation" msgstr "Системно време при активиране" #. i18n: file: ../src/celestia/qt/newbookmarkfolder.ui:13 -#. i18n: ectx: property (windowTitle), widget (QDialog, newBookmarkFolderDialog) +#. i18n: ectx: property (windowTitle), widget (QDialog, +#. newBookmarkFolderDialog) #. i18n: file: ../src/celestia/qt/organizebookmarks.ui:24 #. i18n: ectx: property (text), widget (QPushButton, newFolderButton) #: ../src/celestia/qt/qtbookmark.cpp:897 ../src/celestia/qt/rc.cpp:39 @@ -1680,8 +1658,9 @@ msgstr "Орбити" #: ../src/celestia/qt/qtcelestiaactions.cpp:95 #: ../src/celestia/qt/qtcelestiaactions.cpp:122 #: ../src/celestia/qt/qtselectionpopup.cpp:402 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:101 ../src/celestia/qt/rc.cpp:75 -#: ../src/celestia/qt/rc.cpp:157 ../src/celestia/qt/rc.cpp:224 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:101 +#: ../src/celestia/qt/rc.cpp:75 ../src/celestia/qt/rc.cpp:157 +#: ../src/celestia/qt/rc.cpp:224 #: ../src/celestia/win32/res/resource_strings.cpp:216 #: ../src/celestia/win32/wincontextmenu.cpp:160 #: ../src/celestia/win32/wincontextmenu.cpp:319 @@ -1703,8 +1682,9 @@ msgstr "Планети джуджета" #: ../src/celestia/qt/qtcelestiaactions.cpp:97 #: ../src/celestia/qt/qtcelestiaactions.cpp:124 #: ../src/celestia/qt/qtselectionpopup.cpp:408 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:103 ../src/celestia/qt/rc.cpp:81 -#: ../src/celestia/qt/rc.cpp:163 ../src/celestia/qt/rc.cpp:230 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:103 +#: ../src/celestia/qt/rc.cpp:81 ../src/celestia/qt/rc.cpp:163 +#: ../src/celestia/qt/rc.cpp:230 #: ../src/celestia/win32/res/resource_strings.cpp:218 #: ../src/celestia/win32/wincontextmenu.cpp:156 msgid "Moons" @@ -1725,8 +1705,9 @@ msgstr "Астероидни спътници" #: ../src/celestia/qt/qtcelestiaactions.cpp:99 #: ../src/celestia/qt/qtcelestiaactions.cpp:126 #: ../src/celestia/qt/qtselectionpopup.cpp:414 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:771 ../src/celestia/qt/rc.cpp:87 -#: ../src/celestia/qt/rc.cpp:169 ../src/celestia/qt/rc.cpp:236 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:771 +#: ../src/celestia/qt/rc.cpp:87 ../src/celestia/qt/rc.cpp:169 +#: ../src/celestia/qt/rc.cpp:236 #: ../src/celestia/win32/res/resource_strings.cpp:220 #: ../src/celestia/win32/wincontextmenu.cpp:150 msgid "Asteroids" @@ -1741,8 +1722,9 @@ msgstr "Астероиди" #: ../src/celestia/qt/qtcelestiaactions.cpp:100 #: ../src/celestia/qt/qtcelestiaactions.cpp:127 #: ../src/celestia/qt/qtselectionpopup.cpp:417 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:779 ../src/celestia/qt/rc.cpp:90 -#: ../src/celestia/qt/rc.cpp:172 ../src/celestia/qt/rc.cpp:239 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:779 +#: ../src/celestia/qt/rc.cpp:90 ../src/celestia/qt/rc.cpp:172 +#: ../src/celestia/qt/rc.cpp:239 #: ../src/celestia/win32/res/resource_strings.cpp:221 #: ../src/celestia/win32/wincontextmenu.cpp:152 msgid "Comets" @@ -1762,8 +1744,9 @@ msgstr "Комети" #: ../src/celestia/qt/qtcelestiaactions.cpp:128 #: ../src/celestia/qt/qtselectionpopup.cpp:420 #: ../src/celestia/qt/qtsolarsystembrowser.cpp:105 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:775 ../src/celestia/qt/rc.cpp:94 -#: ../src/celestia/qt/rc.cpp:176 ../src/celestia/qt/rc.cpp:243 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:775 +#: ../src/celestia/qt/rc.cpp:94 ../src/celestia/qt/rc.cpp:176 +#: ../src/celestia/qt/rc.cpp:243 #: ../src/celestia/win32/res/resource_strings.cpp:222 #: ../src/celestia/win32/wincontextmenu.cpp:166 msgctxt "plural" @@ -2156,53 +2139,52 @@ msgstr "%1 намерени обекта" #: ../src/celestia/qt/qtcommandline.cpp:16 msgid "Set the data directory." -msgstr "" +msgstr "Задай папката с данните." #: ../src/celestia/qt/qtcommandline.cpp:16 msgid "datadir" -msgstr "" +msgstr "папка с данни" #: ../src/celestia/qt/qtcommandline.cpp:17 -#, fuzzy msgid "Set the configuraton file." -msgstr "{}: Неточен конфигурационен файл.\n" +msgstr "Задай конфигурационният файл." #: ../src/celestia/qt/qtcommandline.cpp:17 msgid "conf" -msgstr "" +msgstr "конфигурационен файл" #: ../src/celestia/qt/qtcommandline.cpp:18 msgid "Add an extras directory. This option may be specified multiple times." msgstr "" +"Добави папка с допълнения. Тази опция може да бъде зададена няколко пъти." #: ../src/celestia/qt/qtcommandline.cpp:18 msgid "extrasdir" -msgstr "" +msgstr "папка с допълнения" #: ../src/celestia/qt/qtcommandline.cpp:19 msgid "Start in fullscreen mode." -msgstr "" +msgstr "Започни в режим на цял екран." #: ../src/celestia/qt/qtcommandline.cpp:20 msgid "Skip the splash screen." -msgstr "" +msgstr "Пропусни началния екран." #: ../src/celestia/qt/qtcommandline.cpp:21 msgid "Set the start cel:// URL or startup script path." -msgstr "" +msgstr "Задай пътя към началната връзка или скрипт." #: ../src/celestia/qt/qtcommandline.cpp:21 -#, fuzzy msgid "url" -msgstr "Юли" +msgstr "връзка" #: ../src/celestia/qt/qtcommandline.cpp:22 msgid "Set the path to the log file." -msgstr "" +msgstr "Задай пътя към дневника." #: ../src/celestia/qt/qtcommandline.cpp:22 msgid "logpath" -msgstr "" +msgstr "път към дневника" #: ../src/celestia/qt/qtdeepskybrowser.cpp:523 msgid "Mark DSOs selected in list view" @@ -2315,13 +2297,12 @@ msgid "Behind %1" msgstr "Зад %1" #: ../src/celestia/qt/qtglwidget.cpp:105 -#, fuzzy msgid "Celestia was unable to initialize OpenGLES 2.0." -msgstr "„Celestia“ не успя да стартира „OpenGL“ 2.1." +msgstr "„Celestia“ не успя да стартира OpenGLES 2.0." #: ../src/celestia/qt/qtglwidget.cpp:112 msgid "Celestia was unable to initialize OpenGL 2.1." -msgstr "„Celestia“ не успя да стартира „OpenGL“ 2.1." +msgstr "„Celestia“ не успя да стартира OpenGL 2.1." #: ../src/celestia/qt/qtinfopanel.cpp:155 msgid "Error: no object selected!\n" @@ -2460,9 +2441,9 @@ msgid "Period (calculated): %L1 %2" msgstr "Период (изчислен): %L1 %2" #: ../src/celestia/qt/qtinfopanel.cpp:338 -#, fuzzy, qt-format +#, qt-format msgid "Mean motion (calculated): %L1%2/day" -msgstr "Период (изчислен): %L1 %2" +msgstr "Средно движение (изчислено): %L1%2/на ден" #: ../src/celestia/qt/qtinfopanel.cpp:362 #: ../src/celestia/qt/qtinfopanel.cpp:385 @@ -2490,22 +2471,22 @@ msgstr "B: %L1%2 %L3' %L4\"" #: ../src/celestia/qt/qtpreferencesdialog.cpp:210 msgid "OpenGL 2.1" -msgstr "„OpenGL“ 2.1" +msgstr "OpenGL 2.1" #: ../src/celestia/qt/qtpreferencesdialog.cpp:254 #: ../src/celestia/win32/res/resource_strings.cpp:43 msgid "Blackbody D65" -msgstr "Цветови стандарт D65" +msgstr "Чернотелен D65" #: ../src/celestia/qt/qtpreferencesdialog.cpp:255 #: ../src/celestia/win32/res/resource_strings.cpp:44 msgid "Blackbody (Solar Whitepoint)" -msgstr "" +msgstr "Чернотелен (Бяла точка от Слънцето)" #: ../src/celestia/qt/qtpreferencesdialog.cpp:256 #: ../src/celestia/win32/res/resource_strings.cpp:45 msgid "Blackbody (Vega Whitepoint)" -msgstr "" +msgstr "Чернотелен (Бяла точка от Вега)" #: ../src/celestia/qt/qtpreferencesdialog.cpp:257 #: ../src/celestia/win32/res/resource_strings.cpp:46 @@ -2522,7 +2503,7 @@ msgstr "Име на часовата зона" #: ../src/celestia/qt/qtpreferencesdialog.cpp:266 msgid "UTC offset" -msgstr "Отклонение по „UTC“" +msgstr "Отклонение по UTC" #: ../src/celestia/qt/qtselectionpopup.cpp:98 #, qt-format @@ -2688,9 +2669,9 @@ msgstr "Планети джуджета" #. i18n: file: ../src/celestia/qt/preferences.ui:527 #. i18n: ectx: property (text), widget (QCheckBox, minorMoonLabelsCheck) #: ../src/celestia/qt/qtselectionpopup.cpp:411 -#: ../src/celestia/qt/qtsolarsystembrowser.cpp:111 ../src/celestia/qt/rc.cpp:84 -#: ../src/celestia/qt/rc.cpp:166 ../src/celestia/qt/rc.cpp:233 -#: ../src/celestia/win32/wincontextmenu.cpp:158 +#: ../src/celestia/qt/qtsolarsystembrowser.cpp:111 +#: ../src/celestia/qt/rc.cpp:84 ../src/celestia/qt/rc.cpp:166 +#: ../src/celestia/qt/rc.cpp:233 ../src/celestia/win32/wincontextmenu.cpp:158 msgid "Minor moons" msgstr "Астероидни спътници" @@ -2879,7 +2860,7 @@ msgstr "Задай към текущото време" #: ../src/celestia/qt/qttourguide.cpp:61 msgid "No guide destinations were found." -msgstr "" +msgstr "Няма намерени дестинации на екскурзовода." #. i18n: file: ../src/celestia/qt/addbookmark.ui:16 #. i18n: ectx: property (windowTitle), widget (QDialog, addBookmarkDialog) @@ -2957,7 +2938,8 @@ msgid "Description:" msgstr "Описание:" #. i18n: file: ../src/celestia/qt/organizebookmarks.ui:13 -#. i18n: ectx: property (windowTitle), widget (QDialog, organizeBookmarksDialog) +#. i18n: ectx: property (windowTitle), widget (QDialog, +#. organizeBookmarksDialog) #: ../src/celestia/qt/rc.cpp:51 #: ../src/celestia/win32/res/resource_strings.cpp:156 msgid "Organize Bookmarks" @@ -3224,23 +3206,20 @@ msgstr "Резолюция на текстурите" #. i18n: file: ../src/celestia/qt/preferences.ui:865 #. i18n: ectx: property (title), widget (QGroupBox, ambientLightGroupBox) #: ../src/celestia/qt/rc.cpp:318 -#, fuzzy msgid "Lighting" -msgstr "Увеличение на светлината" +msgstr "Светлина" #. i18n: file: ../src/celestia/qt/preferences.ui:871 #. i18n: ectx: property (text), widget (QLabel, label_4) #: ../src/celestia/qt/rc.cpp:321 -#, fuzzy msgid "Ambient light:" -msgstr "Фонова светлина" +msgstr "Фонова светлина:" #. i18n: file: ../src/celestia/qt/preferences.ui:932 #. i18n: ectx: property (text), widget (QLabel, label_5) #: ../src/celestia/qt/rc.cpp:324 -#, fuzzy msgid "Tinted illumination saturation:" -msgstr "Тонирано осветление" +msgstr "Тонирана наситеност на осветяването:" #. i18n: file: ../src/celestia/qt/preferences.ui:991 #. i18n: ectx: property (title), widget (QGroupBox, renderPathGroupBox) @@ -3307,12 +3286,11 @@ msgstr "Отиди до" #: ../src/celestia/qt/xbel.cpp:78 msgid "Not an XBEL version 1.0 file." -msgstr "Не е файл с версия 1.0 на „XBEL“." +msgstr "Не е файл с версия 1.0 на XBEL." #: ../src/celestia/textinput.cpp:191 -#, fuzzy msgid "Target name: {}" -msgstr "Име на целта: %s" +msgstr "Име на целта: {}" #: ../src/celestia/url.cpp:349 msgid "Incorrect hex value \"{}\"\n" @@ -3348,7 +3326,7 @@ msgstr "Неподдържана версия на връзката: {}\n" #: ../src/celestia/url.cpp:552 msgid "URL parameter must look like key=value\n" -msgstr "Параметърът на връзката трябва да изглежда така: key=value\n" +msgstr "Параметърът на връзката трябва да изглежда така: ключ=стойност\n" #: ../src/celestia/win32/res/resource_strings.cpp:4 msgid "Placeholder" @@ -3560,7 +3538,7 @@ msgstr "Контроли" #: ../src/celestia/win32/res/resource_strings.cpp:69 msgid "&OpenGL Info" -msgstr "Информация за „OpenGL“" +msgstr "Информация за OpenGL" #: ../src/celestia/win32/res/resource_strings.cpp:70 msgid "&License" @@ -3599,7 +3577,7 @@ msgstr "1.7.0" #: ../src/celestia/win32/res/resource_strings.cpp:76 msgid "Copyright (C) 2001-2021, Celestia Development Team" -msgstr "Авторско право (С) 2001-2021, Екипа на „Celestia“" +msgstr "Авторско право (С) 2001-2021, Екипът на „Celestia“" #: ../src/celestia/win32/res/resource_strings.cpp:77 msgid "Celestia is free software and comes with absolutely no warranty." @@ -3740,7 +3718,7 @@ msgstr "Име на обект" #: ../src/celestia/win32/res/resource_strings.cpp:121 msgid "OpenGL Driver Info" -msgstr "Информация за драйвъра на „OpenGL“" +msgstr "Информация за драйвъра на OpenGL" #: ../src/celestia/win32/res/resource_strings.cpp:123 msgid "Go to Object" @@ -3970,7 +3948,7 @@ msgstr "Сеп" #: ../src/celestia/win32/winbookmarks.cpp:1484 msgid "(empty)" -msgstr "" +msgstr "(празно)" #: ../src/celestia/win32/wincontextmenu.cpp:154 msgid "Invisibles" @@ -4012,7 +3990,7 @@ msgstr "Сателити" #: ../src/celestia/win32/wincontextmenu.cpp:317 msgid "Orbiting Bodies" -msgstr "Орбитиращи тела" +msgstr "Орбитални тела" #. Add windowed mode as the first item on the menu #: ../src/celestia/win32/windisplaymodedlg.cpp:46 @@ -4021,7 +3999,7 @@ msgstr "В прозорец" #: ../src/celestia/win32/wineclipses.cpp:72 msgid "Body" -msgstr "" +msgstr "Тяло" #: ../src/celestia/win32/wineclipses.cpp:74 msgid "Date" @@ -4033,11 +4011,11 @@ msgstr "Старт" #: ../src/celestia/win32/winfiledlgs.cpp:47 msgid "JPEG - JFIF Compliant (*.jpg)" -msgstr "" +msgstr "Съвместимо с JPEG – JFIF (*.jpg)" #: ../src/celestia/win32/winfiledlgs.cpp:49 msgid "Portable Network Graphics (*.png)" -msgstr "" +msgstr "Преносими мрежови графики (*.png)" #: ../src/celestia/win32/winfiledlgs.cpp:64 msgid "Save As - Specify File to Capture Image" @@ -4058,16 +4036,18 @@ msgid "Could not save image file." msgstr "Изображението не може да бъде запазено." #: ../src/celestia/win32/winfiledlgs.cpp:122 -#, fuzzy msgid "Celestia Script (*.celx, *.cel)" -msgstr "Скриптове на „Celestia“ (*.celx *.cel)" +msgstr "Скрипт на „Celestia“ (*.celx, *.cel)" -#. Gettext complains about using \r in translated messages, so add it in afterwards +#. Gettext complains about using \r in translated messages, so add it in +#. afterwards #: ../src/celestia/win32/winhelpdlgs.cpp:157 msgid "" "License file missing!\n" "See {}" msgstr "" +"Лицензът липсва!\n" +"Вижте {}" #: ../src/celestia/win32/winmain.cpp:143 msgid "Unable to switch to full screen mode; running in window mode" @@ -4083,7 +4063,7 @@ msgstr "Фатална грешка" #: ../src/celestia/win32/winmain.cpp:407 msgid "Directory expected after --dir" -msgstr "Очаква се име на папката след параметъра „--dir“" +msgstr "Очаква се име на папката след параметъра --dir" #: ../src/celestia/win32/winmain.cpp:408 ../src/celestia/win32/winmain.cpp:420 #: ../src/celestia/win32/winmain.cpp:433 ../src/celestia/win32/winmain.cpp:445 @@ -4093,29 +4073,27 @@ msgstr "Грешка в командния ред на „Celestia“" #: ../src/celestia/win32/winmain.cpp:419 msgid "Configuration file name expected after --conf" -msgstr "Очаква се име на конфигурационния файл след параметъра „--conf“" +msgstr "Очаква се име на конфигурационния файл след параметъра --conf" #: ../src/celestia/win32/winmain.cpp:432 msgid "Directory expected after --extrasdir" -msgstr "Очаква се име на папката след параметъра „--extrasdir“" +msgstr "Очаква се име на папката след параметъра --extrasdir" #: ../src/celestia/win32/winmain.cpp:444 msgid "URL expected after --url" -msgstr "Очаква се връзка след параметъра „--url“" +msgstr "Очаква се връзка след параметъра --url" #: ../src/celestia/win32/winmain.cpp:458 -#, fuzzy msgid "Invalid command line option '{}'" -msgstr "Невалидна опция на командния ред „%s“" +msgstr "Невалидна опция на командния ред „{}“" #: ../src/celestia/win32/winmain.cpp:485 -#, fuzzy msgid "Loading: {}" -msgstr "Зареждане: " +msgstr "Зареждане: {}" #: ../src/celestia/win32/winmain.cpp:559 msgid "Loading data files..." -msgstr "Зареждане на файлове с данни..." +msgstr "Зареждане на файловете с данни..." #: ../src/celestia/win32/winmain.cpp:637 ../src/celutil/fsutils.cpp:41 msgid "LANGUAGE" @@ -4123,14 +4101,13 @@ msgstr "bg" #: ../src/celestia/win32/winmain.cpp:655 msgid "Could not load localized resources: {}\n" -msgstr "" +msgstr "Локализираните ресурси не може да бъдат заредени: {}\n" #: ../src/celestia/win32/winmain.cpp:660 msgid "Loaded localized resource: {}\n" -msgstr "" +msgstr "Локализираните ресурси са заредени: {}\n" #: ../src/celestia/win32/winmain.cpp:698 -#, fuzzy msgid "Confugration file missing!" msgstr "Конфигурационният файл липсва!" @@ -4151,40 +4128,38 @@ msgid "Failed to create the application window." msgstr "Неуспешно създаване на прозореца на приложението." #: ../src/celestia/win32/winmain.cpp:785 -#, fuzzy msgid "Error locking drop target\n" -msgstr "Грешка при отваряне на звездния каталог {}\n" +msgstr "Грешка при заключване на целта\n" #: ../src/celestia/win32/winmain.cpp:794 -#, fuzzy msgid "Failed to register drop target as OLE object.\n" -msgstr "Неуспешно регистриране на прозоречния клас." +msgstr "Неуспешно регистриране на целта като OLE обект.\n" #: ../src/celestia/win32/winmainwindow.cpp:260 msgid "Error getting joystick caps.\n" -msgstr "" +msgstr "Грешка при получаване на обратна връзка от джойстика.\n" #: ../src/celestia/win32/winmainwindow.cpp:264 msgid "Using joystick: {}\n" -msgstr "" +msgstr "Използван джойстик: {}\n" #: ../src/celestia/win32/winmainwindow.cpp:725 msgid "Loading URL" -msgstr "Зареждане на връзка" +msgstr "Зареждане на връзката" #: ../src/celestia/win32/winmainwindow.cpp:1135 msgid "Could not get appropriate pixel format for OpenGL rendering." msgstr "" -"Не може да бъде избран подходящ формат на пикселите за възпроизвеждане с " -"„OpenGL“." +"Подходящият формат на пикселите за възпроизвеждане с OpenGL не може да бъде " +"избран." #: ../src/celestia/win32/winmainwindow.cpp:1153 msgid "Your system doesn't support OpenGL 2.1!" -msgstr "Вашата система не поддържа „OpenGL“ 2.1!" +msgstr "Вашата система не поддържа OpenGL 2.1!" #: ../src/celestia/win32/winmainwindow.cpp:1170 msgid "Releasing device context failed." -msgstr "Неуспешно извличане на контекста на устройството." +msgstr "Извличането на контекста на устройството се провали." #: ../src/celestia/win32/winmainwindow.cpp:1568 msgid "Failed to register the window class." @@ -4195,9 +4170,8 @@ msgid "Stop current movie capture before starting another one." msgstr "Спри текущото прихващане на видео, преди започване на следващото." #: ../src/celestia/win32/winmoviecapture.cpp:240 -#, fuzzy msgid "Matroska (*.mkv)" -msgstr "Видео формат „Матрьошка“ (*.mkv)" +msgstr "Формат „Матрьошка“ (*.mkv)" #: ../src/celestia/win32/winmoviecapture.cpp:258 msgid "Save As - Specify Output File for Capture Movie" @@ -4214,23 +4188,20 @@ msgstr "Видеото не може да бъде прихванато." #: ../src/celestia/win32/winpreferences.cpp:202 #: ../src/celestia/win32/winpreferences.cpp:261 -#, fuzzy msgid "Error opening registry key: {}\n" -msgstr "Грешка при отваряне на скрипта {}" +msgstr "Грешка при отваряне на ключа от регистъра: {}\n" #: ../src/celestia/win32/winpreferences.cpp:253 -#, fuzzy msgid "Saving preferences...\n" -msgstr "Предпочитания..." +msgstr "Запазване на предпочитанията...\n" #: ../src/celestia/win32/winpreferences.cpp:265 msgid "Opened registry key\n" -msgstr "" +msgstr "Ключът от регистъра е отворен\n" #: ../src/celestia/win32/winsplash.cpp:122 -#, fuzzy msgid "Version: {}" -msgstr "Версия: " +msgstr "Версия: {}" #: ../src/celestia/win32/wintime.cpp:99 msgid "Time Zone Name" @@ -4238,20 +4209,19 @@ msgstr "Име на часовата зона" #: ../src/celestia/win32/wintime.cpp:100 msgid "UTC Offset" -msgstr "Отклонение по „UTC“" +msgstr "Отклонение по UTC" #: ../src/celimage/image.cpp:385 msgid "Loading image from file {}\n" -msgstr "Зареждане на изображение от файл {}\n" +msgstr "Зареждане на изображение от файла {}\n" #: ../src/celimage/image.cpp:409 msgid "{}: unrecognized or unsupported image file type.\n" -msgstr "" +msgstr "{}: неразпознат или неподдържан формат на изображението.\n" #: ../src/celimage/png.cpp:27 -#, fuzzy msgid "Error reading PNG data" -msgstr "Грешка при четене на „PNG“ изображението {}\n" +msgstr "Грешка при четене на PNG данните" #: ../src/celimage/png.cpp:49 msgid "Can't open screen capture file '{}'\n" @@ -4259,7 +4229,7 @@ msgstr "Прихванатото изображение „{}“ не може #: ../src/celimage/png.cpp:105 msgid "Error writing PNG file '{}'\n" -msgstr "Грешка при записване на „PNG“ изображението „{}“\n" +msgstr "Грешка при записване на PNG изображението „{}“\n" #: ../src/celimage/png.cpp:153 msgid "Error opening image file {}.\n" @@ -4267,11 +4237,11 @@ msgstr "Грешка при отваряне на изображение {}.\n" #: ../src/celimage/png.cpp:161 msgid "Error: {} is not a PNG file.\n" -msgstr "Грешка: {} не е „PNG“ файл.\n" +msgstr "Грешка: {} не е PNG файл.\n" #: ../src/celimage/png.cpp:187 msgid "Error reading PNG image file {}\n" -msgstr "Грешка при четене на „PNG“ изображението {}\n" +msgstr "Грешка при четене на PNG изображението {}\n" #: ../src/celscript/legacy/legacyscript.cpp:101 msgid "Error opening script file." @@ -4280,16 +4250,16 @@ msgstr "Грешка при отваряне на скрипта." #: ../src/celscript/legacy/legacyscript.cpp:110 #: ../src/celscript/lua/luascript.cpp:99 msgid "Unknown error loading script" -msgstr "Неизвестна грешка при зареждането на скрипта" +msgstr "Неизвестна грешка при зареждане на скрипта" #. TRANSLATORS: Y is first letter of Yes #: ../src/celscript/lua/celx.cpp:434 msgid "Y" -msgstr "" +msgstr "Д" #: ../src/celscript/lua/celx.cpp:735 msgid "In line {}: {}" -msgstr "Съответства {}: {}" +msgstr "На линия {}: {}" #: ../src/celscript/lua/celx.cpp:780 msgid "" @@ -4309,7 +4279,7 @@ msgstr "" "Това може да доведе до потенциален риск за сигурността.\n" "Сигурни ли сте, че искате да продължите?\n" "\n" -"„y“ = да, „ESC“ = спиране на скрипта, всички останали клавиши = не" +"y = да, ESC = спиране на скрипта, всички останали клавиши = не" #: ../src/celscript/lua/celx.cpp:791 msgid "" @@ -4334,7 +4304,7 @@ msgstr "Грешка при отваряне на скрипта {}" #: ../src/celscript/lua/luascript.cpp:107 #: ../src/celscript/lua/luascript.cpp:242 msgid "Script coroutine initialization failed" -msgstr "Корутинното стартиране на скрипта се провали" +msgstr "Съпрограмното стартиране на скрипта се провали" #: ../src/celscript/lua/luascript.cpp:214 msgid "Error opening LuaHook {}" @@ -4342,16 +4312,15 @@ msgstr "Грешка при отваряне на куката на „Lua“ {} #: ../src/celscript/lua/luascript.cpp:231 msgid "Unknown error loading hook script" -msgstr "Неизвестна грешка при зареждането на скрипта кука" +msgstr "Неизвестна грешка при зареждане на скрипта кука" #: ../src/celutil/tzutil.cpp:51 msgid "Unknown value returned by GetTimeZoneInformation()\n" msgstr "„GetTimeZoneInformation()“ отчита неизвестна стойност\n" #: ../src/tools/xyzv2bin/bin2xyzv.cpp:27 -#, fuzzy msgid "Error opening {} or {}.\n" -msgstr "Грешка при отваряне на {} или .\n" +msgstr "Грешка при отваряне на {} или {}.\n" #: ../src/tools/xyzv2bin/bin2xyzv.cpp:49 msgid "Unsupported byte order {}, expected {}.\n" @@ -4359,74 +4328,4 @@ msgstr "Неподдържан байтов ред {}, очакван {}.\n" #: ../src/tools/xyzv2bin/bin2xyzv.cpp:58 msgid "Unsupported digits number {}, expected {}.\n" -msgstr "Неподдържано число {}, очаквано {}.\n" - -#~ msgid "https://celestiaproject.space/" -#~ msgstr "https://celestiaproject.space/" - -#~ msgid "Satellite" -#~ msgstr "Сателит" - -#~ msgid "" -#~ "License file missing!\n" -#~ "See http://www.gnu.org/copyleft/gpl.html" -#~ msgstr "" -#~ "Лицензът липсва!\n" -#~ "Вижте http://www.gnu.org/copyleft/gpl.html" - -#, c-format -#~ msgid "%d x %d" -#~ msgstr "%d x %d" - -#~ msgid "Specified file extension is not recognized." -#~ msgstr "Зададеното разширение на файла не е разпознато." - -#~ msgid "Error opening {}.\n" -#~ msgstr "Грешка при отваряне на {}.\n" - -#~ msgid "GL error: " -#~ msgstr "Грешка при „OpenGL“: " - -#, c-format -#~ msgid "" -#~ "FPS: %.1f, vis. stars stats: [ %zu : %zu : %zu ], vis. DSOs stats: " -#~ "[ %zu : %zu : %zu ]\n" -#~ msgstr "" -#~ "ЧКС: %.1f, стат. на видимите звезди: [ %zu : %zu : %zu ], стат. на " -#~ "видимите ОДК: [ %zu : %zu : %zu ]\n" - -#~ msgid "000; " -#~ msgstr "000; " - -#~ msgid "Error opening config file '{}'.\n" -#~ msgstr "Грешка при отваряне на конфигурационния файл „{}“.\n" - -#~ msgid "{}:{} 'Configuration' expected.\n" -#~ msgstr "{}:{} очаква се „Configuration“.\n" - -#~ msgid "Star color: Enhanced" -#~ msgstr "Звезден цвят: Засилен" - -#~ msgid "Celestia was unable to initialize OpenGL 2.1.\n" -#~ msgstr "„Celestia“ не успя да стартира „OpenGL“ 2.1.\n" - -#~ msgid "Shift+F11" -#~ msgstr "Shift+F11" - -#~ msgid "Celestia Manual" -#~ msgstr "Ръководство за „Celestia“" - -#~ msgid "A filename expected after --log/-l" -#~ msgstr "Очаква се име на файла след параметъра „--log/-l“" - -#~ msgid "S&ynch Orbit" -#~ msgstr "Синхронизирай с орбитата" - -#~ msgid "Set time" -#~ msgstr "Задай времето" - -#~ msgid "&Disabled" -#~ msgstr "Изключен" - -#~ msgid "&Enabled" -#~ msgstr "Включен" +msgstr "Неподдържан брой числа {}, очакван {}.\n" From 8a6a41b3a972cb13e2b8ef6579bec423c4d5a0aa Mon Sep 17 00:00:00 2001 From: Andrew Tribick Date: Sat, 10 Feb 2024 22:38:31 +0100 Subject: [PATCH 7/8] Update GTK build - Move code to celestia::gtk namespace - Remove using namespace std - Remove GNOME frontend conditional compilation - Move private types into unnamed namespaces - Use C++-17 inline variables --- src/celestia/gtk/actions.cpp | 855 +++++++++++++--------------- src/celestia/gtk/actions.h | 9 +- src/celestia/gtk/common.cpp | 105 ++-- src/celestia/gtk/common.h | 30 +- src/celestia/gtk/dialog-eclipse.cpp | 442 +++++++------- src/celestia/gtk/dialog-eclipse.h | 61 +- src/celestia/gtk/dialog-goto.cpp | 259 +++++---- src/celestia/gtk/dialog-goto.h | 25 +- src/celestia/gtk/dialog-options.cpp | 229 ++++---- src/celestia/gtk/dialog-options.h | 21 +- src/celestia/gtk/dialog-solar.cpp | 171 +++--- src/celestia/gtk/dialog-solar.h | 12 +- src/celestia/gtk/dialog-star.cpp | 77 +-- src/celestia/gtk/dialog-star.h | 5 + src/celestia/gtk/dialog-time.cpp | 210 ++++--- src/celestia/gtk/dialog-time.h | 4 + src/celestia/gtk/dialog-tour.cpp | 156 ++--- src/celestia/gtk/dialog-tour.h | 12 +- src/celestia/gtk/glwidget.cpp | 404 +++++++------ src/celestia/gtk/glwidget.h | 4 + src/celestia/gtk/main.cpp | 162 ++---- src/celestia/gtk/menu-context.cpp | 310 +++++----- src/celestia/gtk/menu-context.h | 5 + src/celestia/gtk/settings-file.cpp | 169 +++--- src/celestia/gtk/settings-file.h | 6 +- src/celestia/gtk/settings-gconf.cpp | 527 ----------------- src/celestia/gtk/settings-gconf.h | 41 -- src/celestia/gtk/splash.cpp | 151 ++--- src/celestia/gtk/splash.h | 33 +- src/celestia/gtk/ui.h | 281 ++++----- 30 files changed, 2077 insertions(+), 2699 deletions(-) delete mode 100644 src/celestia/gtk/settings-gconf.cpp delete mode 100644 src/celestia/gtk/settings-gconf.h diff --git a/src/celestia/gtk/actions.cpp b/src/celestia/gtk/actions.cpp index dfb4f24dfe..70e9d99741 100644 --- a/src/celestia/gtk/actions.cpp +++ b/src/celestia/gtk/actions.cpp @@ -11,15 +11,12 @@ */ #include +#include #include #include #include #include -#ifdef GNOME -#include -#endif /* GNOME */ - #include #include #include @@ -45,40 +42,164 @@ #include "dialog-time.h" #include "dialog-tour.h" -#ifdef GNOME -#include "settings-gconf.h" -#else #include "settings-file.h" -#endif /* GNOME */ -using namespace std; +namespace celestia::gtk +{ + +namespace +{ + +/* Script opening helper called by actionOpenScript() */ +void +openScript(const char* filename, AppData* app) +{ + /* Modified From Win32 HandleOpenScript */ + if (filename) + { + /* If you got here, a path and file has been specified. + * filename contains full path to specified file. */ + app->core->runScript(filename); + } +} + +/* Image capturing helper called by actionCaptureImage() */ +void +captureImage(const char* filename, AppData* app) +{ + ContentType type = DetermineFileType(filename); + if (type != ContentType::JPEG && type != ContentType::PNG) + { + GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Please use a name ending in '.jpg' or '.png'.")); + gtk_dialog_run(GTK_DIALOG(errBox)); + gtk_widget_destroy(errBox); + return; + } + + if (!app->core->saveScreenShot(filename)) + { + GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Error writing captured image.")); + gtk_dialog_run(GTK_DIALOG(errBox)); + gtk_widget_destroy(errBox); + } +} -/* Declarations: Action Helpers */ -static void openScript(const char* filename, AppData* app); -static void captureImage(const char* filename, AppData* app); +/* Image capturing helper called by actionCaptureImage() */ #ifdef USE_FFMPEG -static void captureMovie(const char* filename, const int resolution[], float fps, - AVCodecID codec, float bitrate, AppData* app); +void +captureMovie(const char* filename, const int resolution[], float fps, + AVCodecID codec, float bitrate, AppData* app) +{ + auto* movieCapture = new FFMPEGCapture(app->renderer); + movieCapture->setVideoCodec(codec); + movieCapture->setBitRate(bitrate); + if (codec == AV_CODEC_ID_H264) + movieCapture->setEncoderOptions(app->core->getConfig()->x264EncoderOptions); + else + movieCapture->setEncoderOptions(app->core->getConfig()->ffvhEncoderOptions); + + bool success = movieCapture->start(filename, resolution[0], resolution[1], fps); + if (success) + { + app->core->initMovieCapture(movieCapture); + } + else + { + delete movieCapture; + + GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Error initializing movie capture."); + gtk_dialog_run(GTK_DIALOG(errBox)); + gtk_widget_destroy(errBox); + } +} #endif -static void textInfoDialog(const char *txt, const char *title, AppData* app); -static void setRenderFlag(AppData* a, uint64_t flag, gboolean state); -static void setOrbitMask(AppData* a, int mask, gboolean state); -static void setLabelMode(AppData* a, int mode, gboolean state); + +/* Runs a dialog that displays text; should be replaced at some point with + a more elegant solution. */ +void +textInfoDialog(const char *txt, const char *title, AppData* app) +{ + /* I would use a gnome_message_box dialog for this, except they don't seem + * to notice that the texts are so big that they create huge windows, and + * would work better with a scrolled window. Deon */ + GtkWidget* dialog = gtk_dialog_new_with_buttons(title, + GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL); + GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + gtk_box_pack_start(GTK_BOX(content_area), scrolled_window, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_widget_show(scrolled_window); + + GtkWidget *text = gtk_label_new(txt); + gtk_widget_modify_font(text, pango_font_description_from_string("mono")); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), GTK_WIDGET(text)); + gtk_widget_show(text); + + gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400); /* Absolute Size, urghhh */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +/* Calculates and sets the render-flag int */ +void +setRenderFlag(AppData* a, std::uint64_t flag, gboolean state) +{ + std::uint64_t rf = (a->renderer->getRenderFlags() & ~flag) | (state ? flag : 0); + a->renderer->setRenderFlags(rf); +} + +/* Calculates and sets the orbit-mask int */ +void +setOrbitMask(AppData* a, int mask, gboolean state) +{ + int om = (a->renderer->getOrbitMask() & ~mask) | (state ? mask : 0); + a->renderer->setOrbitMask(om); +} + +/* Calculates and sets the label-mode int */ +void +setLabelMode(AppData* a, int mode, gboolean state) +{ + int lm = (a->renderer->getLabelMode() & ~mode) | (state ? mode : 0); + a->renderer->setLabelMode(lm); +} #ifdef USE_FFMPEG -static const int MovieSizes[][2] = -{ - { 160, 120 }, - { 320, 240 }, - { 640, 480 }, - { 720, 480 }, - { 720, 576 }, - { 1024, 768 }, - { 1280, 720 }, - { 1920, 1080 } +using MovieSize = std::array; + +constexpr std::array MovieSizes +{ + MovieSize{ 160, 120 }, + MovieSize{ 320, 240 }, + MovieSize{ 640, 480 }, + MovieSize{ 720, 480 }, + MovieSize{ 720, 576 }, + MovieSize{ 1024, 768 }, + MovieSize{ 1280, 720 }, + MovieSize{ 1920, 1080 } }; -static const float MovieFramerates[] = { 15.0f, 23.976f, 24.0f, 25.0f, 29.97f, 30.0f, 60.0f }; +constexpr std::array MovieFramerates{ 15.0f, 23.976f, 24.0f, 25.0f, 29.97f, 30.0f, 60.0f }; struct MovieCodec { @@ -86,13 +207,14 @@ struct MovieCodec const char *codecDesc; }; -static MovieCodec MovieCodecs[2] = +constexpr std::array MovieCodecs { - { AV_CODEC_ID_FFVHUFF, N_("Lossless") }, - { AV_CODEC_ID_H264, N_("Lossy (H.264)") } + MovieCodec{ AV_CODEC_ID_FFVHUFF, N_("Lossless") }, + MovieCodec{ AV_CODEC_ID_H264, N_("Lossy (H.264)") } }; -static void insert_text_event(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data) +void +insert_text_event(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data) { for (int i = 0; i < length; i++) { @@ -105,8 +227,11 @@ static void insert_text_event(GtkEditable *editable, const gchar *text, gint len } #endif +} // end unnamed namespace + /* File -> Copy URL */ -void actionCopyURL(GtkAction*, AppData* app) +void +actionCopyURL(GtkAction*, AppData* app) { GtkClipboard* cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); CelestiaState appState(app->core); @@ -117,7 +242,8 @@ void actionCopyURL(GtkAction*, AppData* app) /* File -> Open URL */ -void actionOpenURL(GtkAction*, AppData* app) +void +actionOpenURL(GtkAction*, AppData* app) { GtkWidget* dialog = gtk_dialog_new_with_buttons("Enter cel:// URL", GTK_WINDOW(app->mainWindow), @@ -145,7 +271,8 @@ void actionOpenURL(GtkAction*, AppData* app) /* File -> Open Script... */ -void actionOpenScript(GtkAction*, AppData* app) +void +actionOpenScript(GtkAction*, AppData* app) { GtkWidget* fs = gtk_file_chooser_dialog_new("Open Script.", GTK_WINDOW(app->mainWindow), @@ -183,9 +310,9 @@ void actionOpenScript(GtkAction*, AppData* app) gtk_widget_destroy(fs); } - /* File -> Capture Image... */ -void actionCaptureImage(GtkAction*, AppData* app) +void +actionCaptureImage(GtkAction*, AppData* app) { GtkWidget* fs = gtk_file_chooser_dialog_new("Save Image to File", GTK_WINDOW(app->mainWindow), @@ -224,7 +351,8 @@ void actionCaptureImage(GtkAction*, AppData* app) } /* File -> Capture Movie... */ -void actionCaptureMovie(GtkAction*, AppData* app) +void +actionCaptureMovie(GtkAction*, AppData* app) { #ifdef USE_FFMPEG // TODO: The menu item should be disable so that the user doesn't even @@ -318,7 +446,7 @@ void actionCaptureMovie(GtkAction*, AppData* app) int fridx = gtk_combo_box_get_active(GTK_COMBO_BOX(frcombo)); int vcidx = gtk_combo_box_get_active(GTK_COMBO_BOX(vccombo)); const gchar *brtext = gtk_entry_get_text(GTK_ENTRY(brentry)); - const int *resolution = MovieSizes[vsidx]; + const int *resolution = MovieSizes[vsidx].data(); float fps = MovieFramerates[fridx]; AVCodecID codec = MovieCodecs[vcidx].codecId; float bitrate = 400000; @@ -346,9 +474,9 @@ void actionCaptureMovie(GtkAction*, AppData* app) #endif } - /* File -> Run Demo... */ -void actionRunDemo(GtkAction*, AppData* app) +void +actionRunDemo(GtkAction*, AppData* app) { const auto& demoScriptFile = app->core->getConfig()->paths.demoScriptFile; if (!demoScriptFile.empty()) @@ -358,32 +486,27 @@ void actionRunDemo(GtkAction*, AppData* app) } } - -void actionQuit(GtkAction*, AppData* app) +void +actionQuit(GtkAction*, AppData* app) { - #ifdef GNOME - saveSettingsGConf(app); - #else saveSettingsFile(app); - #endif /* GNOME */ - gtk_main_quit(); } - -void actionSelectSol(GtkAction*, AppData* app) +void +actionSelectSol(GtkAction*, AppData* app) { app->core->charEntered('H'); } - -void actionTourGuide(GtkAction*, AppData* app) +void +actionTourGuide(GtkAction*, AppData* app) { dialogTourGuide(app); } - -void actionSearchObject(GtkAction*, AppData* app) +void +actionSearchObject(GtkAction*, AppData* app) { GtkWidget* dialog = gtk_dialog_new_with_buttons("Select Object", GTK_WINDOW(app->mainWindow), @@ -420,109 +543,105 @@ void actionSearchObject(GtkAction*, AppData* app) gtk_widget_destroy(GTK_WIDGET(dialog)); } - -void actionGotoObject(GtkAction*, AppData* app) +void +actionGotoObject(GtkAction*, AppData* app) { dialogGotoObject(app); } - -void actionCenterSelection(GtkAction*, AppData* app) +void +actionCenterSelection(GtkAction*, AppData* app) { app->core->charEntered('c'); } - -void actionGotoSelection(GtkAction*, AppData* app) +void +actionGotoSelection(GtkAction*, AppData* app) { app->core->charEntered('G'); } - -void actionFollowSelection(GtkAction*, AppData* app) +void +actionFollowSelection(GtkAction*, AppData* app) { app->core->charEntered('F'); } - -void actionSyncSelection(GtkAction*, AppData* app) +void +actionSyncSelection(GtkAction*, AppData* app) { app->core->charEntered('Y'); } - -void actionTrackSelection(GtkAction*, AppData* app) +void +actionTrackSelection(GtkAction*, AppData* app) { app->core->charEntered('T'); } - -void actionSystemBrowser(GtkAction*, AppData* app) +void +actionSystemBrowser(GtkAction*, AppData* app) { dialogSolarBrowser(app); } - -void actionStarBrowser(GtkAction*, AppData* app) +void +actionStarBrowser(GtkAction*, AppData* app) { dialogStarBrowser(app); } - -void actionEclipseFinder(GtkAction*, AppData* app) +void +actionEclipseFinder(GtkAction*, AppData* app) { dialogEclipseFinder(app); } - -void actionTimeFaster(GtkAction*, AppData* app) +void +actionTimeFaster(GtkAction*, AppData* app) { app->core->charEntered('L'); } - -void actionTimeSlower(GtkAction*, AppData* app) +void +actionTimeSlower(GtkAction*, AppData* app) { app->core->charEntered('K'); } - -void actionTimeFreeze(GtkAction*, AppData* app) +void +actionTimeFreeze(GtkAction*, AppData* app) { app->core->charEntered(' '); } - -void actionTimeReal(GtkAction*, AppData* app) +void +actionTimeReal(GtkAction*, AppData* app) { app->core->charEntered('\\'); } - -void actionTimeReverse(GtkAction*, AppData* app) +void +actionTimeReverse(GtkAction*, AppData* app) { app->core->charEntered('J'); } - -void actionTimeSet(GtkAction*, AppData* app) +void +actionTimeSet(GtkAction*, AppData* app) { dialogSetTime(app); } - -void actionTimeLocal(GtkAction* action, AppData* app) +void +actionTimeLocal(GtkAction* action, AppData* app) { app->showLocalTime = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); updateTimeZone(app, app->showLocalTime); - - #ifdef GNOME - gconf_client_set_bool(app->client, "/apps/celestia/showLocalTime", app->showLocalTime, NULL); - #endif /* GNOME */ } - -void actionViewerSize(GtkAction*, AppData* app) +void +actionViewerSize(GtkAction*, AppData* app) { GtkWidget* dialog; int newX, currentX, currentY, winX, winY, screenX, i = 1, position = -1; @@ -552,12 +671,12 @@ void actionViewerSize(GtkAction*, AppData* app) { if (position == -1 && resolutions[i-1] < currentX && resolutions[i] >= currentX) { - sprintf(res, "%d x %d (current)", currentX, currentY); + std::sprintf(res, "%d x %d (current)", currentX, currentY); position = i - 1; } else if (resolutions[i] < screenX) { - sprintf(res, "%d x %d", resolutions[i], int(0.75 * resolutions[i])); + std::sprintf(res, "%d x %d", resolutions[i], int(0.75 * resolutions[i])); i++; } else @@ -592,8 +711,8 @@ void actionViewerSize(GtkAction*, AppData* app) gtk_widget_destroy(GTK_WIDGET(dialog)); } - -void actionFullScreen(GtkAction* action, AppData* app) +void +actionFullScreen(GtkAction* action, AppData* app) { int positionX, positionY; app->fullScreen = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); @@ -616,110 +735,98 @@ void actionFullScreen(GtkAction* action, AppData* app) /* Enable/Disable the Viewer Size action */ gtk_action_set_sensitive(gtk_action_group_get_action(app->agMain, "ViewerSize"), !app->fullScreen); - - #ifdef GNOME - gconf_client_set_bool(app->client, "/apps/celestia/fullScreen", app->fullScreen, NULL); - #endif } - -void actionViewOptions(GtkAction*, AppData* app) +void +actionViewOptions(GtkAction*, AppData* app) { dialogViewOptions(app); } - -void actionStarsMore(GtkAction*, AppData* app) +void +actionStarsMore(GtkAction*, AppData* app) { app->core->charEntered(']'); - - #ifdef GNOME - gconf_client_set_float(app->client, "/apps/celestia/visualMagnitude", app->simulation->getFaintestVisible(), NULL); - #endif } - -void actionStarsFewer(GtkAction*, AppData* app) +void +actionStarsFewer(GtkAction*, AppData* app) { app->core->charEntered('['); - - #ifdef GNOME - gconf_client_set_float(app->client, "/apps/celestia/visualMagnitude", app->simulation->getFaintestVisible(), NULL); - #endif } - -void actionMenuBarVisible(GtkToggleAction* action, AppData* app) +void +actionMenuBarVisible(GtkToggleAction* action, AppData* app) { g_object_set(G_OBJECT(app->mainMenu), "visible", gtk_toggle_action_get_active(action), NULL); } - -void actionMultiSplitH(GtkAction*, AppData* app) +void +actionMultiSplitH(GtkAction*, AppData* app) { app->core->splitView(celestia::View::HorizontalSplit); } - -void actionMultiSplitV(GtkAction*, AppData* app) +void +actionMultiSplitV(GtkAction*, AppData* app) { app->core->splitView(celestia::View::VerticalSplit); } - -void actionMultiCycle(GtkAction*, AppData* app) +void +actionMultiCycle(GtkAction*, AppData* app) { /* Pass a Tab character */ app->core->charEntered('\011'); } - -void actionMultiDelete(GtkAction*, AppData* app) +void +actionMultiDelete(GtkAction*, AppData* app) { app->core->deleteView(); } - -void actionMultiSingle(GtkAction*, AppData* app) +void +actionMultiSingle(GtkAction*, AppData* app) { app->core->singleView(); } - -void actionMultiShowFrames(GtkToggleAction* action, AppData* app) +void +actionMultiShowFrames(GtkToggleAction* action, AppData* app) { app->core->setFramesVisible(gtk_toggle_action_get_active(action)); } - -void actionMultiShowActive(GtkToggleAction* action, AppData* app) +void +actionMultiShowActive(GtkToggleAction* action, AppData* app) { app->core->setActiveFrameVisible(gtk_toggle_action_get_active(action)); } - -void actionMultiSyncTime(GtkToggleAction* action, AppData* app) +void +actionMultiSyncTime(GtkToggleAction* action, AppData* app) { app->simulation->setSyncTime(gtk_toggle_action_get_active(action)); } - -void actionHelpControls(GtkAction*, AppData* app) +void +actionHelpControls(GtkAction*, AppData* app) { char *txt = readFromFile("controls.txt"); textInfoDialog(txt, "Mouse and Keyboard Controls", app); g_free(txt); } - -void actionHelpOpenGL(GtkAction*, AppData* app) +void +actionHelpOpenGL(GtkAction*, AppData* app) { - string s = Helper::getRenderInfo(app->renderer); + std::string s = Helper::getRenderInfo(app->renderer); textInfoDialog(s.c_str(), "Renderer Info", app); } - -void actionHelpAbout(GtkAction*, AppData* app) +void +actionHelpAbout(GtkAction*, AppData* app) { const gchar* authors[] = { "Chris Laurel ", @@ -738,9 +845,9 @@ void actionHelpAbout(GtkAction*, AppData* app) GdkPixbuf *logo = gdk_pixbuf_new_from_file ("celestia-logo.png", NULL); - string comments = fmt::format("GTK+ Front-End, built using gtk+ version {}.{}", - GTK_MAJOR_VERSION, - GTK_MINOR_VERSION); + std::string comments = fmt::format("GTK+ Front-End, built using gtk+ version {}.{}", + GTK_MAJOR_VERSION, + GTK_MINOR_VERSION); gtk_show_about_dialog(GTK_WINDOW(app->mainWindow), "title", _("About Celestia"), @@ -756,490 +863,332 @@ void actionHelpAbout(GtkAction*, AppData* app) g_object_unref(logo); } - -void actionVerbosity(GtkRadioAction* action, GtkRadioAction*, AppData* app) +void +actionVerbosity(GtkRadioAction* action, GtkRadioAction*, AppData* app) { int value = gtk_radio_action_get_current_value(action); app->core->setHudDetail(value); - - #ifdef GNOME - gconf_client_set_int(app->client, "/apps/celestia/verbosity", value, NULL); - #endif } - -void actionStarStyle(GtkRadioAction* action, GtkRadioAction*, AppData* app) +void +actionStarStyle(GtkRadioAction* action, GtkRadioAction*, AppData* app) { int value = gtk_radio_action_get_current_value(action); app->renderer->setStarStyle((Renderer::StarStyle)value); - - #ifdef GNOME - gconf_client_set_int(app->client, "/apps/celestia/starStyle", value, NULL); - #endif } - -void actionAmbientLight(GtkRadioAction* action, GtkRadioAction*, AppData* app) +void +actionAmbientLight(GtkRadioAction* action, GtkRadioAction*, AppData* app) { float value = amLevels[gtk_radio_action_get_current_value(action)]; app->renderer->setAmbientLightLevel(value); - - #ifdef GNOME - gconf_client_set_float(app->client, "/apps/celestia/ambientLight", value, NULL); - #endif } /* Render-Flag Actions */ -void actionRenderAA(GtkToggleAction* action, AppData* app) +void +actionRenderAA(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowSmoothLines, gtk_toggle_action_get_active(action)); } - -void actionRenderAtmospheres(GtkToggleAction* action, AppData* app) +void +actionRenderAtmospheres(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowAtmospheres, gtk_toggle_action_get_active(action)); } - -void actionRenderAutoMagnitude(GtkToggleAction* action, AppData* app) +void +actionRenderAutoMagnitude(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowAutoMag, gtk_toggle_action_get_active(action)); } - -void actionRenderCelestialGrid(GtkToggleAction* action, AppData* app) +void +actionRenderCelestialGrid(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowCelestialSphere, gtk_toggle_action_get_active(action)); } - -void actionRenderClouds(GtkToggleAction* action, AppData* app) +void +actionRenderClouds(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowCloudMaps, gtk_toggle_action_get_active(action)); } - -void actionRenderCometTails(GtkToggleAction* action, AppData* app) +void +actionRenderCometTails(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowCometTails, gtk_toggle_action_get_active(action)); } - -void actionRenderConstellationBoundaries(GtkToggleAction* action, AppData* app) +void +actionRenderConstellationBoundaries(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowBoundaries, gtk_toggle_action_get_active(action)); } - -void actionRenderConstellations(GtkToggleAction* action, AppData* app) +void +actionRenderConstellations(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowDiagrams, gtk_toggle_action_get_active(action)); } - -void actionRenderEclipticGrid(GtkToggleAction* action, AppData* app) +void +actionRenderEclipticGrid(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowEclipticGrid, gtk_toggle_action_get_active(action)); } - -void actionRenderEclipseShadows(GtkToggleAction* action, AppData* app) +void +actionRenderEclipseShadows(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowEclipseShadows, gtk_toggle_action_get_active(action)); } - -void actionRenderGalacticGrid(GtkToggleAction* action, AppData* app) +void +actionRenderGalacticGrid(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowGalacticGrid, gtk_toggle_action_get_active(action)); } - -void actionRenderGalaxies(GtkToggleAction* action, AppData* app) +void +actionRenderGalaxies(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowGalaxies, gtk_toggle_action_get_active(action)); } - -void actionRenderGlobulars(GtkToggleAction* action, AppData* app) +void +actionRenderGlobulars(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowGlobulars, gtk_toggle_action_get_active(action)); } - -void actionRenderHorizontalGrid(GtkToggleAction* action, AppData* app) +void +actionRenderHorizontalGrid(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowHorizonGrid, gtk_toggle_action_get_active(action)); } - -void actionRenderMarkers(GtkToggleAction* action, AppData* app) +void +actionRenderMarkers(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowMarkers, gtk_toggle_action_get_active(action)); } - -void actionRenderNebulae(GtkToggleAction* action, AppData* app) +void +actionRenderNebulae(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowNebulae, gtk_toggle_action_get_active(action)); } - -void actionRenderNightLights(GtkToggleAction* action, AppData* app) +void +actionRenderNightLights(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowNightMaps, gtk_toggle_action_get_active(action)); } - -void actionRenderOpenClusters(GtkToggleAction* action, AppData* app) +void +actionRenderOpenClusters(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowOpenClusters, gtk_toggle_action_get_active(action)); } - -void actionRenderOrbits(GtkToggleAction* action, AppData* app) +void +actionRenderOrbits(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowOrbits, gtk_toggle_action_get_active(action)); } -void actionRenderFadingOrbits(GtkToggleAction* action, AppData* app) +void +actionRenderFadingOrbits(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowFadingOrbits, gtk_toggle_action_get_active(action)); } - -void actionRenderPlanets(GtkToggleAction* action, AppData* app) +void +actionRenderPlanets(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowPlanets, gtk_toggle_action_get_active(action)); } - -void actionRenderDwarfPlanets(GtkToggleAction* action, AppData* app) +void +actionRenderDwarfPlanets(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowDwarfPlanets, gtk_toggle_action_get_active(action)); } - -void actionRenderMoons(GtkToggleAction* action, AppData* app) +void +actionRenderMoons(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowMoons, gtk_toggle_action_get_active(action)); } - -void actionRenderMinorMoons(GtkToggleAction* action, AppData* app) +void +actionRenderMinorMoons(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowMinorMoons, gtk_toggle_action_get_active(action)); } - -void actionRenderAsteroids(GtkToggleAction* action, AppData* app) +void +actionRenderAsteroids(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowAsteroids, gtk_toggle_action_get_active(action)); } - -void actionRenderComets(GtkToggleAction* action, AppData* app) +void +actionRenderComets(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowComets, gtk_toggle_action_get_active(action)); } - -void actionRenderSpacecrafts(GtkToggleAction* action, AppData* app) +void +actionRenderSpacecrafts(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowSpacecrafts, gtk_toggle_action_get_active(action)); } - -void actionRenderPlanetRings(GtkToggleAction* action, AppData* app) +void +actionRenderPlanetRings(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowPlanetRings, gtk_toggle_action_get_active(action)); } -void actionRenderRingShadows(GtkToggleAction* action, AppData* app) +void +actionRenderRingShadows(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowRingShadows, gtk_toggle_action_get_active(action)); } - -void actionRenderStars(GtkToggleAction* action, AppData* app) +void +actionRenderStars(GtkToggleAction* action, AppData* app) { setRenderFlag(app, Renderer::ShowStars, gtk_toggle_action_get_active(action)); } - -void actionOrbitAsteroids(GtkToggleAction* action, AppData* app) +void +actionOrbitAsteroids(GtkToggleAction* action, AppData* app) { setOrbitMask(app, Body::Asteroid, gtk_toggle_action_get_active(action)); } - -void actionOrbitComets(GtkToggleAction* action, AppData* app) +void +actionOrbitComets(GtkToggleAction* action, AppData* app) { setOrbitMask(app, Body::Comet, gtk_toggle_action_get_active(action)); } - -void actionOrbitMoons(GtkToggleAction* action, AppData* app) +void +actionOrbitMoons(GtkToggleAction* action, AppData* app) { setOrbitMask(app, Body::Moon, gtk_toggle_action_get_active(action)); } - -void actionOrbitPlanets(GtkToggleAction* action, AppData* app) +void +actionOrbitPlanets(GtkToggleAction* action, AppData* app) { setOrbitMask(app, Body::Planet, gtk_toggle_action_get_active(action)); } - -void actionOrbitSpacecraft(GtkToggleAction* action, AppData* app) +void +actionOrbitSpacecraft(GtkToggleAction* action, AppData* app) { setOrbitMask(app, Body::Spacecraft, gtk_toggle_action_get_active(action)); } - -void actionLabelAsteroids(GtkToggleAction* action, AppData* app) +void +actionLabelAsteroids(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::AsteroidLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelComets(GtkToggleAction* action, AppData* app) +void +actionLabelComets(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::CometLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelConstellations(GtkToggleAction* action, AppData* app) +void +actionLabelConstellations(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::ConstellationLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelGalaxies(GtkToggleAction* action, AppData* app) +void +actionLabelGalaxies(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::GalaxyLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelGlobulars(GtkToggleAction* action, AppData* app) +void +actionLabelGlobulars(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::GlobularLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelLocations(GtkToggleAction* action, AppData* app) +void +actionLabelLocations(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::LocationLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelMoons(GtkToggleAction* action, AppData* app) +void +actionLabelMoons(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::MoonLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelMinorMoons(GtkToggleAction* action, AppData* app) +void +actionLabelMinorMoons(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::MinorMoonLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelNebulae(GtkToggleAction* action, AppData* app) +void +actionLabelNebulae(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::NebulaLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelOpenClusters(GtkToggleAction* action, AppData* app) +void +actionLabelOpenClusters(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::OpenClusterLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelPlanets(GtkToggleAction* action, AppData* app) +void +actionLabelPlanets(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::PlanetLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelDwarfPlanets(GtkToggleAction* action, AppData* app) +void +actionLabelDwarfPlanets(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::DwarfPlanetLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelSpacecraft(GtkToggleAction* action, AppData* app) +void +actionLabelSpacecraft(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::SpacecraftLabels, gtk_toggle_action_get_active(action)); } - -void actionLabelStars(GtkToggleAction* action, AppData* app) +void +actionLabelStars(GtkToggleAction* action, AppData* app) { setLabelMode(app, Renderer::StarLabels, gtk_toggle_action_get_active(action)); } - -/* Script opening helper called by actionOpenScript() */ -static void openScript(const char* filename, AppData* app) -{ - /* Modified From Win32 HandleOpenScript */ - if (filename) - { - /* If you got here, a path and file has been specified. - * filename contains full path to specified file. */ - app->core->runScript(filename); - } -} - - -/* Image capturing helper called by actionCaptureImage() */ -static void captureImage(const char* filename, AppData* app) -{ - ContentType type = DetermineFileType(filename); - if (type != ContentType::JPEG && type != ContentType::PNG) - { - GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Please use a name ending in '.jpg' or '.png'.")); - gtk_dialog_run(GTK_DIALOG(errBox)); - gtk_widget_destroy(errBox); - return; - } - - if (!app->core->saveScreenShot(filename)) - { - GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Error writing captured image."); - gtk_dialog_run(GTK_DIALOG(errBox)); - gtk_widget_destroy(errBox); - } -} - -/* Image capturing helper called by actionCaptureImage() */ -#ifdef USE_FFMPEG -static void captureMovie(const char* filename, const int resolution[], float fps, - AVCodecID codec, float bitrate, AppData* app) -{ - auto* movieCapture = new FFMPEGCapture(app->renderer); - movieCapture->setVideoCodec(codec); - movieCapture->setBitRate(bitrate); - if (codec == AV_CODEC_ID_H264) - movieCapture->setEncoderOptions(app->core->getConfig()->x264EncoderOptions); - else - movieCapture->setEncoderOptions(app->core->getConfig()->ffvhEncoderOptions); - - bool success = movieCapture->start(filename, resolution[0], resolution[1], fps); - if (success) - { - app->core->initMovieCapture(movieCapture); - } - else - { - delete movieCapture; - - GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Error initializing movie capture."); - gtk_dialog_run(GTK_DIALOG(errBox)); - gtk_widget_destroy(errBox); - } -} -#endif - -/* Runs a dialog that displays text; should be replaced at some point with - a more elegant solution. */ -static void textInfoDialog(const char *txt, const char *title, AppData* app) -{ - /* I would use a gnome_message_box dialog for this, except they don't seem - * to notice that the texts are so big that they create huge windows, and - * would work better with a scrolled window. Deon */ - GtkWidget* dialog = gtk_dialog_new_with_buttons(title, - GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL); - GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_box_pack_start(GTK_BOX(content_area), scrolled_window, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_widget_show(scrolled_window); - - GtkWidget *text = gtk_label_new(txt); - gtk_widget_modify_font(text, pango_font_description_from_string("mono")); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), GTK_WIDGET(text)); - gtk_widget_show(text); - - gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400); /* Absolute Size, urghhh */ - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -} - - -/* Calculates and sets the render-flag int */ -static void setRenderFlag(AppData* a, uint64_t flag, gboolean state) -{ - uint64_t rf = (a->renderer->getRenderFlags() & ~flag) | (state ? flag : 0); - a->renderer->setRenderFlags(rf); - - #ifdef GNOME - /* Update GConf */ - gcSetRenderFlag(flag, state, a->client); - #endif /* GNOME */ -} - - -/* Calculates and sets the orbit-mask int */ -static void setOrbitMask(AppData* a, int mask, gboolean state) -{ - int om = (a->renderer->getOrbitMask() & ~mask) | (state ? mask : 0); - a->renderer->setOrbitMask(om); - - #ifdef GNOME - /* Update GConf */ - gcSetOrbitMask(mask, state, a->client); - #endif /* GNOME */ -} - - -/* Calculates and sets the label-mode int */ -static void setLabelMode(AppData* a, int mode, gboolean state) -{ - int lm = (a->renderer->getLabelMode() & ~mode) | (state ? mode : 0); - a->renderer->setLabelMode(lm); - - #ifdef GNOME - /* Update GConf */ - gcSetLabelMode(mode, state, a->client); - #endif /* GNOME */ -} - - /* Synchronizes the Label Actions with the state of the core */ -void resyncLabelActions(AppData* app) +void +resyncLabelActions(AppData* app) { - GtkAction* action; - const char* actionName; - /* Simply for readability */ int f = app->renderer->getLabelMode(); for (int i = Renderer::StarLabels; i <= Renderer::GlobularLabels; i *= 2) { + const char* actionName; switch (i) { case Renderer::StarLabels: actionName = "LabelStars"; break; @@ -1257,13 +1206,13 @@ void resyncLabelActions(AppData* app) case Renderer::OpenClusterLabels: actionName = "LabelOpenClusters"; break; case Renderer::GlobularLabels: actionName = "LabelGlobulars"; break; case Renderer::I18nConstellationLabels: /* Not used yet */ - default: actionName = NULL; + default: actionName = nullptr; break; } - if (actionName != NULL) + if (actionName != nullptr) { /* Get the action */ - action = gtk_action_group_get_action(app->agLabel, actionName); + GtkAction* action = gtk_action_group_get_action(app->agLabel, actionName); /* The current i anded with the labelMode gives state of flag */ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), (i & f)); @@ -1271,22 +1220,20 @@ void resyncLabelActions(AppData* app) } } - /* Synchronizes the Render Actions with the state of the core */ -void resyncRenderActions(AppData* app) +void +resyncRenderActions(AppData* app) { - GtkAction* action; - const char* actionName; - /* Simply for readability */ - uint64_t rf = app->renderer->getRenderFlags(); + const std::uint64_t rf = app->renderer->getRenderFlags(); /* Unlike the other interfaces, which go through each menu item and set * the corresponding renderFlag, we go the other way and set the menu * based on the renderFlag. Last one is ShowPlanetRings. */ - for (uint64_t i = Renderer::ShowStars; i <= Renderer::ShowPlanetRings; i *= 2) + for (std::uint64_t i = Renderer::ShowStars; i <= Renderer::ShowPlanetRings; i *= 2) { + const char* actionName; switch (i) { case Renderer::ShowStars: actionName = "RenderStars"; break; @@ -1313,22 +1260,22 @@ void resyncRenderActions(AppData* app) case Renderer::ShowAutoMag: actionName = "RenderAutoMagnitude"; break; case Renderer::ShowCometTails: actionName = "RenderCometTails"; break; case Renderer::ShowMarkers: actionName = "RenderMarkers"; break; - case Renderer::ShowPartialTrajectories: actionName = NULL; break; /* Not useful yet */ + case Renderer::ShowPartialTrajectories: actionName = nullptr; break; /* Not useful yet */ case Renderer::ShowNebulae: actionName = "RenderNebulae"; break; case Renderer::ShowOpenClusters: actionName = "RenderOpenClusters"; break; case Renderer::ShowGlobulars: actionName = "RenderGlobulars"; break; - case Renderer::ShowCloudShadows: actionName = NULL; break; /* Not implemented yet */ + case Renderer::ShowCloudShadows: actionName = nullptr; break; /* Not implemented yet */ case Renderer::ShowGalacticGrid: actionName = "RenderGalacticGrid"; break; case Renderer::ShowEclipticGrid: actionName = "RenderEclipticGrid"; break; case Renderer::ShowHorizonGrid: actionName = "RenderHorizontalGrid"; break; - case Renderer::ShowEcliptic: actionName = NULL; break; /* Not implemented yet */ - default: actionName = NULL; + case Renderer::ShowEcliptic: actionName = nullptr; break; /* Not implemented yet */ + default: actionName = nullptr; break; } - if (actionName != NULL) + if (actionName != nullptr) { /* Get the action */ - action = gtk_action_group_get_action(app->agRender, actionName); + GtkAction* action = gtk_action_group_get_action(app->agRender, actionName); /* The current i anded with the renderFlags gives state of flag */ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), (i & rf) != 0); @@ -1336,18 +1283,16 @@ void resyncRenderActions(AppData* app) } } - /* Synchronizes the Orbit Actions with the state of the core */ -void resyncOrbitActions(AppData* app) +void +resyncOrbitActions(AppData* app) { - GtkAction* action; - const char* actionName; - /* Simply for readability */ int om = app->renderer->getOrbitMask(); for (int i = Body::Planet; i <= Body::Spacecraft; i *= 2) { + const char* actionName; switch (i) { case Body::Planet: actionName = "OrbitPlanets"; break; @@ -1355,13 +1300,13 @@ void resyncOrbitActions(AppData* app) case Body::Asteroid: actionName = "OrbitAsteroids"; break; case Body::Comet: actionName = "OrbitComets"; break; case Body::Spacecraft: actionName = "OrbitSpacecraft"; break; - default: actionName = NULL; + default: actionName = nullptr; break; } - if (actionName != NULL) + if (actionName != nullptr) { /* Get the action */ - action = gtk_action_group_get_action(app->agOrbit, actionName); + GtkAction* action = gtk_action_group_get_action(app->agOrbit, actionName); /* The current i anded with the orbitMask gives state of flag */ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), (i & om)); @@ -1369,13 +1314,11 @@ void resyncOrbitActions(AppData* app) } } - /* Synchronizes the Verbosity Actions with the state of the core */ -void resyncVerbosityActions(AppData* app) +void +resyncVerbosityActions(AppData* app) { - GtkAction* action; const char* actionName; - switch (app->core->getHudDetail()) { case 0: actionName = "HudNone"; break; @@ -1385,22 +1328,22 @@ void resyncVerbosityActions(AppData* app) } /* Get the action, set the widget */ - action = gtk_action_group_get_action(app->agVerbosity, actionName); + GtkAction* action = gtk_action_group_get_action(app->agVerbosity, actionName); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } - /* Synchronizes the TimeZone Action with the state of the core */ -void resyncTimeZoneAction(AppData* app) +void +resyncTimeZoneAction(AppData* app) { /* Get the action, set the widget */ GtkAction* action = gtk_action_group_get_action(app->agMain, "TimeLocal"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), app->showLocalTime); } - /* Synchronizes the Ambient Light Actions with the state of the core */ -void resyncAmbientActions(AppData* app) +void +resyncAmbientActions(AppData* app) { GtkAction* action; @@ -1417,17 +1360,11 @@ void resyncAmbientActions(AppData* app) action = gtk_action_group_get_action(app->agAmbient, "AmbientMedium"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); - - #ifdef GNOME - /* The action callback only occurs when one of the None/Low/Medium barriers - * is surpassed, so an update is forced. */ - gconf_client_set_float(app->client, "/apps/celestia/ambientLight", ambient, NULL); - #endif } - /* Synchronizes the Verbosity Actions with the state of the core */ -void resyncStarStyleActions(AppData* app) +void +resyncStarStyleActions(AppData* app) { GtkAction* action; const char* actionName; @@ -1445,22 +1382,18 @@ void resyncStarStyleActions(AppData* app) gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } - /* Placeholder for when galaxy brightness is added as an action */ -void resyncGalaxyGainActions(AppData* app) +void +resyncGalaxyGainActions(AppData* app) { - #ifdef GNOME - float gain = Galaxy::getLightGain(); - gconf_client_set_float(app->client, "/apps/celestia/galaxyLightGain", gain, NULL); - #endif + /* no-op */ } - /* Synchronizes the Texture Resolution with the state of the core */ -void resyncTextureResolutionActions(AppData* app) +void +resyncTextureResolutionActions(AppData* app) { - #ifdef GNOME - int resolution = app->renderer->getResolution(); - gconf_client_set_int(app->client, "/apps/celestia/textureResolution", resolution, NULL); - #endif /* GNOME */ + /* no-op */ } + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/actions.h b/src/celestia/gtk/actions.h index 45dc6ff667..1fb5c51693 100644 --- a/src/celestia/gtk/actions.h +++ b/src/celestia/gtk/actions.h @@ -16,6 +16,8 @@ #include "common.h" +namespace celestia::gtk +{ /* Main Actions */ void actionCopyURL(GtkAction*, AppData*); @@ -133,10 +135,7 @@ void resyncStarStyleActions(AppData* app); void resyncGalaxyGainActions(AppData* app); void resyncTextureResolutionActions(AppData* app); - /* Information for the about box */ -#ifdef GNOME -#define FRONTEND "GNOME" -#else #define FRONTEND "GTK+" -#endif + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/common.cpp b/src/celestia/gtk/common.cpp index 758e918e1d..6e668e7bdf 100644 --- a/src/celestia/gtk/common.cpp +++ b/src/celestia/gtk/common.cpp @@ -21,28 +21,28 @@ #include "common.h" -using namespace std; - -namespace astro = celestia::astro; +namespace celestia::gtk +{ /* Returns the offset of the timezone at date */ -gint tzOffsetAtDate(const astro::Date& date) +gint +tzOffsetAtDate(const astro::Date& date) { #ifdef WIN32 /* This does not correctly handle DST. Unfortunately, no way to find * out what UTC offset is at specified date in Windows */ return -timezone; #else - time_t time = (time_t)astro::julianDateToSeconds(date - astro::Date(1970, 1, 1)); - struct tm *d = localtime(&time); + std::time_t time = (time_t)astro::julianDateToSeconds(date - astro::Date(1970, 1, 1)); + struct std::tm *d = localtime(&time); - return (gint)d->tm_gmtoff; + return static_cast(d->tm_gmtoff); #endif } - /* Updates the time zone in the core based on valid timezone data */ -void updateTimeZone(AppData* app, gboolean local) +void +updateTimeZone(AppData* app, gboolean local) { if (local) /* Always base current time zone on simulation date */ @@ -51,9 +51,9 @@ void updateTimeZone(AppData* app, gboolean local) app->core->setTimeZoneBias(0); } - /* Creates a button. Used in several dialogs. */ -gint buttonMake(GtkWidget *hbox, const char *txt, GCallback func, gpointer data) +gint +buttonMake(GtkWidget *hbox, const char *txt, GCallback func, gpointer data) { GtkWidget* button = gtk_button_new_with_label(txt); @@ -63,11 +63,11 @@ gint buttonMake(GtkWidget *hbox, const char *txt, GCallback func, gpointer data) return 0; } - /* creates a group of radioButtons. Used in several dialogs. */ -void makeRadioItems(const char* const *labels, GtkWidget *box, GCallback sigFunc, GtkToggleButton **gads, gpointer data) +void +makeRadioItems(const char* const *labels, GtkWidget *box, GCallback sigFunc, GtkToggleButton **gads, gpointer data) { - GSList *group = NULL; + GSList *group = nullptr; for (gint i=0; labels[i]; i++) { @@ -83,17 +83,17 @@ void makeRadioItems(const char* const *labels, GtkWidget *box, GCallback sigFunc gtk_widget_show (button); g_signal_connect(G_OBJECT(button), "pressed", sigFunc, GINT_TO_POINTER(i)); - if (data != NULL) + if (data != nullptr) g_object_set_data(G_OBJECT(button), "data", data); } } - /* Gets the contents of a file and sanitizes formatting */ -char *readFromFile(const char *fname) +char* +readFromFile(const char *fname) { - ifstream textFile(fname, ios::in); - string s(""); + std::ifstream textFile(fname, std::ios::in); + std::string s(""); if (!textFile.is_open()) { s = "Unable to open file '"; @@ -114,9 +114,9 @@ char *readFromFile(const char *fname) return g_strdup(s.c_str()); } - /* Returns width of the non-fullscreen window */ -int getWinWidth(AppData* app) +int +getWinWidth(AppData* app) { if (app->fullScreen) return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app->mainWindow), "sizeX")); @@ -126,9 +126,9 @@ int getWinWidth(AppData* app) return allocation.width; } - /* Returns height of the non-fullscreen window */ -int getWinHeight(AppData* app) +int +getWinHeight(AppData* app) { if (app->fullScreen) return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app->mainWindow), "sizeY")); @@ -138,9 +138,9 @@ int getWinHeight(AppData* app) return allocation.height; } - /* Returns X-position of the non-fullscreen window */ -int getWinX(AppData* app) +int +getWinX(AppData* app) { int positionX; @@ -148,14 +148,14 @@ int getWinX(AppData* app) return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app->mainWindow), "positionX")); else { - gtk_window_get_position(GTK_WINDOW(app->mainWindow), &positionX, NULL); + gtk_window_get_position(GTK_WINDOW(app->mainWindow), &positionX, nullptr); return positionX; } } - /* Returns Y-position of the non-fullscreen window */ -int getWinY(AppData* app) +int +getWinY(AppData* app) { int positionY; @@ -163,14 +163,14 @@ int getWinY(AppData* app) return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app->mainWindow), "positionY")); else { - gtk_window_get_position(GTK_WINDOW(app->mainWindow), NULL, &positionY); + gtk_window_get_position(GTK_WINDOW(app->mainWindow), nullptr, &positionY); return positionY; } } - /* Sanitizes and sets Ambient Light */ -void setSaneAmbientLight(AppData* app, float value) +void +setSaneAmbientLight(AppData* app, float value) { if (value < 0.0 || value > 1.0) value = amLevels[1]; /* Default to "Low" */ @@ -178,9 +178,9 @@ void setSaneAmbientLight(AppData* app, float value) app->renderer->setAmbientLightLevel(value); } - /* Sanitizes and sets Visual Magnitude */ -void setSaneVisualMagnitude(AppData* app, float value) +void +setSaneVisualMagnitude(AppData* app, float value) { if (value < 0.0 || value > 100.0) value = 8.5f; /* Default from Simulation::Simulation() */ @@ -188,9 +188,9 @@ void setSaneVisualMagnitude(AppData* app, float value) app->simulation->setFaintestVisible(value); } - /* Sanitizes and sets Galaxy Light Gain */ -void setSaneGalaxyLightGain(float value) +void +setSaneGalaxyLightGain(float value) { if (value < 0.0 || value > 1.0) value = 0.0f; /* Default */ @@ -198,9 +198,9 @@ void setSaneGalaxyLightGain(float value) Galaxy::setLightGain(value); } - /* Sanitizes and sets Distance Limit */ -void setSaneDistanceLimit(AppData* app, int value) +void +setSaneDistanceLimit(AppData* app, int value) { if (value < 0 || value > 1000000) value = 1000000; /* Default to maximum */ @@ -209,7 +209,8 @@ void setSaneDistanceLimit(AppData* app, int value) } /* Sanitizes and sets HUD Verbosity */ -void setSaneVerbosity(AppData* app, int value) +void +setSaneVerbosity(AppData* app, int value) { if (value < 0 || value > 2) value = 1; /* Default to "Terse" */ @@ -217,9 +218,9 @@ void setSaneVerbosity(AppData* app, int value) app->core->setHudDetail(value); } - /* Sanitizes and sets Star Style */ -void setSaneStarStyle(AppData* app, Renderer::StarStyle value) +void +setSaneStarStyle(AppData* app, Renderer::StarStyle value) { if (value < Renderer::FuzzyPointStars || value > Renderer::ScaledDiscStars) value = Renderer::FuzzyPointStars; @@ -227,9 +228,9 @@ void setSaneStarStyle(AppData* app, Renderer::StarStyle value) app->renderer->setStarStyle(value); } - /* Sanitizes and sets Texture Resolution */ -void setSaneTextureResolution(AppData* app, int value) +void +setSaneTextureResolution(AppData* app, int value) { if (value < 0 || value > MultiResTexture::kTextureResolution) value = medres; /* Default to "Medium" */ @@ -237,19 +238,19 @@ void setSaneTextureResolution(AppData* app, int value) app->renderer->setResolution(value); } - /* Sanitizes and sets Altername Surface Name */ -void setSaneAltSurface(AppData* app, char* value) +void +setSaneAltSurface(AppData* app, char* value) { - if (value == NULL) + if (value == nullptr) value = (char*)""; app->simulation->getActiveObserver()->setDisplayedSurface(value); } - /* Sanitizes and sets Window Size */ -void setSaneWinSize(AppData* app, int x, int y) +void +setSaneWinSize(AppData* app, int x, int y) { int screenX = gdk_screen_get_width(gdk_screen_get_default()); int screenY = gdk_screen_get_height(gdk_screen_get_default()); @@ -263,9 +264,9 @@ void setSaneWinSize(AppData* app, int x, int y) gtk_widget_set_size_request(app->glArea, x, y); } - /* Sanitizes and sets Window Position */ -void setSaneWinPosition(AppData* app, int x, int y) +void +setSaneWinPosition(AppData* app, int x, int y) { int screenX = gdk_screen_get_width(gdk_screen_get_default()); int screenY = gdk_screen_get_height(gdk_screen_get_default()); @@ -277,9 +278,11 @@ void setSaneWinPosition(AppData* app, int x, int y) } } - /* Sets default render flags. Exists because the defaults are a little lame. */ -void setDefaultRenderFlags(AppData* app) +void +setDefaultRenderFlags(AppData* app) { app->renderer->setRenderFlags(Renderer::DefaultRenderFlags); } + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/common.h b/src/celestia/gtk/common.h index bff281bd62..bd9c2466b4 100644 --- a/src/celestia/gtk/common.h +++ b/src/celestia/gtk/common.h @@ -13,16 +13,15 @@ #pragma once #include +#include #include -#ifdef GNOME -#include -#endif /* GNOME */ - #include #include #include +namespace celestia::gtk +{ typedef struct _AppData AppData; struct _AppData { @@ -48,11 +47,7 @@ struct _AppData { GtkActionGroup* agAmbient; /* Settings */ - #ifdef GNOME - GConfClient* client; - #else GKeyFile* settingsFile; - #endif /* GNOME */ /* Ready to render? */ gboolean bReady; @@ -96,9 +91,8 @@ void setSaneWinSize(AppData* app, int x, int y); void setSaneWinPosition(AppData* app, int x, int y); void setDefaultRenderFlags(AppData* app); - /* Constants used throughout */ -const char * const monthOptions[] = +constexpr inline std::array monthOptions { "January", "February", @@ -112,17 +106,17 @@ const char * const monthOptions[] = "October", "November", "December", - NULL + static_cast(nullptr), }; -static const float amLevels[] = +constexpr inline std::array amLevels { - 0.0, - 0.1, - 0.25 + 0.0f, + 0.1f, + 0.25f, }; -static const int resolutions[] = +constexpr inline std::array resolutions = { 0, /* Must start with 0 */ 640, @@ -136,4 +130,6 @@ static const int resolutions[] = }; /* This is the spacing used for widgets throughout the program */ -#define CELSPACING 8 +constexpr inline gint CELSPACING = 8; + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-eclipse.cpp b/src/celestia/gtk/dialog-eclipse.cpp index 828e21c653..d78d2d3998 100644 --- a/src/celestia/gtk/dialog-eclipse.cpp +++ b/src/celestia/gtk/dialog-eclipse.cpp @@ -10,6 +10,13 @@ * $Id: dialog-eclipse.cpp,v 1.2 2005-12-10 06:34:21 suwalski Exp $ */ +#include +#include +#include +#include + +#include + #include #include @@ -22,190 +29,82 @@ #include "dialog-eclipse.h" #include "common.h" -using namespace Eigen; -using namespace std; - -namespace astro = celestia::astro; -namespace math = celestia::math; - -/* Definitions: Callbacks */ -static void calDateSelect(GtkCalendar *calendar, GtkToggleButton *button); -static void showCalPopup(GtkToggleButton *button, EclipseData *ed); -static gint eclipseGoto(GtkButton*, EclipseData* ed); -static gint eclipse2Click(GtkWidget*, GdkEventButton* event, EclipseData* ed); -static void eclipseCompute(GtkButton* button, EclipseData* ed); -static void eclipseBodySelect(GtkComboBox* comboBox, EclipseData* ed); -static void eclipseTypeSelect(GtkComboBox* comboBox, EclipseData* ed); -static void listEclipseSelect(GtkTreeSelection* sel, EclipseData* ed); -static void eclipseDestroy(GtkWidget* w, gint, EclipseData* ed); - -/* Definitions: Helpers */ -static void setButtonDateString(GtkToggleButton *button, int year, int month, int day); - - -/* ENTRY: Navigation -> Eclipse Finder */ -void dialogEclipseFinder(AppData* app) +namespace celestia::gtk { - EclipseData* ed = g_new0(EclipseData, 1); - selDate* d1 = g_new0(selDate, 1); - selDate* d2 = g_new0(selDate, 1); - ed->d1 = d1; - ed->d2 = d2; - ed->app = app; - ed->eclipseList = NULL; - ed->eclipseListStore = NULL; - ed->type = Eclipse::Solar; - ed->body = eclipsePlanetTitles[0]; - ed->sel = NULL; - - ed->window = GTK_DIALOG(gtk_dialog_new_with_buttons("Eclipse Finder", - GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - NULL)); - gtk_window_set_modal(GTK_WINDOW(ed->window), FALSE); - - GtkWidget *mainbox = gtk_dialog_get_content_area(GTK_DIALOG(ed->window)); - gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING); - - GtkWidget *scrolled_win = gtk_scrolled_window_new(NULL, NULL); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0); - - /* Create listbox list. - * Six invisible ints at the end to hold actual time. - * This will save string parsing like in KDE version. - * Last field holds pointer to selected Body. */ - ed->eclipseListStore = gtk_list_store_new(12, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_POINTER); - ed->eclipseList = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ed->eclipseListStore)); - - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(ed->eclipseList), TRUE); - gtk_container_add(GTK_CONTAINER(scrolled_win), ed->eclipseList); - - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - /* Add the columns */ - for (int i=0; i<5; i++) { - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(eclipseTitles[i], renderer, "text", i, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(ed->eclipseList), column); - } - - /* Set up callback for when an eclipse is selected */ - GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ed->eclipseList)); - g_signal_connect(selection, "changed", G_CALLBACK(listEclipseSelect), ed); - - /* From now on, it's the bottom-of-the-window controls */ - GtkWidget *label; - GtkWidget *hbox; - - /* -------------------------------- */ - hbox = gtk_hbox_new(FALSE, CELSPACING); - - label = gtk_label_new("Find"); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - GtkWidget *menuTypeBox = gtk_combo_box_text_new(); - gtk_box_pack_start(GTK_BOX(hbox), menuTypeBox, FALSE, FALSE, 0); - label = gtk_label_new("eclipse on"); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - GtkWidget* menuBodyBox = gtk_combo_box_text_new(); - gtk_box_pack_start(GTK_BOX(hbox), menuBodyBox, FALSE, FALSE, 0); - - gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); - /* -------------------------------- */ - hbox = gtk_hbox_new(FALSE, CELSPACING); - - label = gtk_label_new("From"); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - /* Get current date */ - astro::Date datenow(app->simulation->getTime()); - - /* Set current time */ - ed->d1->year = datenow.year - 1; - ed->d1->month = datenow.month; - ed->d1->day = datenow.day; - - /* Set time a year from now */ - ed->d2->year = ed->d1->year + 2; - ed->d2->month = ed->d1->month; - ed->d2->day = ed->d1->day; +namespace +{ - GtkWidget* date1Button = gtk_toggle_button_new(); - setButtonDateString(GTK_TOGGLE_BUTTON(date1Button), ed->d1->year, ed->d1->month, ed->d1->day); - g_object_set_data(G_OBJECT(date1Button), "eclipsedata", ed->d1); - gtk_box_pack_start(GTK_BOX(hbox), date1Button, FALSE, FALSE, 0); +/* Local Data Structures */ +/* Date selection data type */ +typedef struct _selDate selDate; +struct _selDate { + int year; + int month; + int day; +}; - label = gtk_label_new("to"); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); +typedef struct _EclipseData EclipseData; +struct _EclipseData { + AppData* app; - GtkWidget* date2Button = gtk_toggle_button_new(); - setButtonDateString(GTK_TOGGLE_BUTTON(date2Button), ed->d2->year, ed->d2->month, ed->d2->day); - g_object_set_data(G_OBJECT(date2Button), "eclipsedata", ed->d2); - gtk_box_pack_start(GTK_BOX(hbox), date2Button, FALSE, FALSE, 0); + /* Start Time */ + selDate* d1; - gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); - /* -------------------------------- */ + /* End Time */ + selDate* d2; - /* Common Buttons */ - hbox = gtk_hbox_new(TRUE, CELSPACING); - if (buttonMake(hbox, "Compute", (GCallback)eclipseCompute, ed)) - return; - if (buttonMake(hbox, "Set Date and Go to Planet", (GCallback)eclipseGoto, ed)) - return; - gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); + int type; + const char* body; + GtkTreeSelection* sel; - /* Set up the drop-down boxes */ - for (int i = 0; eclipseTypeTitles[i] != NULL; i++) - { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(menuTypeBox), eclipseTypeTitles[i]); - } - gtk_combo_box_set_active(GTK_COMBO_BOX(menuTypeBox), 0); + GtkWidget *eclipseList; + GtkListStore *eclipseListStore; - for (int i = 0; eclipsePlanetTitles[i] != NULL; i++) - { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(menuBodyBox), eclipsePlanetTitles[i]); - } - gtk_combo_box_set_active(GTK_COMBO_BOX(menuBodyBox), 0); + GtkDialog* window; +}; - /* Hook up all the signals */ - g_signal_connect(G_OBJECT(menuTypeBox), "changed", G_CALLBACK(eclipseTypeSelect), ed); - g_signal_connect(G_OBJECT(menuBodyBox), "changed", G_CALLBACK(eclipseBodySelect), ed); +constexpr std::array eclipseTitles +{ + "Planet", + "Satellite", + "Date", + "Start", + "End", + static_cast(nullptr), +}; + +constexpr std::array eclipseTypeTitles +{ + "solar", + "moon", + static_cast(nullptr), +}; - /* Double-click handler */ - g_signal_connect(G_OBJECT(ed->eclipseList), "button-press-event", G_CALLBACK(eclipse2Click), ed); +constexpr std::array eclipsePlanetTitles +{ + "Earth", + "Jupiter", + "Saturn", + "Uranus", + "Neptune", + "Pluto", + static_cast(nullptr), +}; - g_signal_connect(G_OBJECT(date1Button), "toggled", G_CALLBACK(showCalPopup), ed); - g_signal_connect(G_OBJECT(date2Button), "toggled", G_CALLBACK(showCalPopup), ed); - g_signal_connect(ed->window, "response", G_CALLBACK(eclipseDestroy), ed); +/* HELPER: set a date string in a button */ +void +setButtonDateString(GtkToggleButton *button, int year, int month, int day) +{ + char date[50]; + std::sprintf(date, "%d %s %d", day, monthOptions[month - 1], year); - gtk_widget_set_size_request(GTK_WIDGET(ed->window), -1, 400); /* Absolute Size, urghhh */ - gtk_widget_show_all(GTK_WIDGET(ed->window)); + gtk_button_set_label(GTK_BUTTON(button), date); } - /* CALLBACK: When the GtkCalendar date is selected */ -static void calDateSelect(GtkCalendar *calendar, GtkToggleButton *button) +void +calDateSelect(GtkCalendar *calendar, GtkToggleButton *button) { /* Set the selected date */ guint year, month, day; @@ -224,9 +123,9 @@ static void calDateSelect(GtkCalendar *calendar, GtkToggleButton *button) gtk_toggle_button_set_active(button, !gtk_toggle_button_get_active(button)); } - /* CALLBACK: When a button is clicked to show a GtkCalendar */ -static void showCalPopup(GtkToggleButton *button, EclipseData *ed) +void +showCalPopup(GtkToggleButton *button, EclipseData *ed) { GtkWidget* calwindow = GTK_WIDGET(g_object_get_data(G_OBJECT(button), "calendar")); @@ -281,9 +180,9 @@ static void showCalPopup(GtkToggleButton *button, EclipseData *ed) } } - /* CALLBACK: "SetTime/Goto" in Eclipse Finder */ -static gint eclipseGoto(GtkButton*, EclipseData* ed) +gint +eclipseGoto(GtkButton*, EclipseData* ed) { GValue value = { 0, {{0}} }; /* Initialize GValue to 0 */ GtkTreeIter iter; @@ -331,15 +230,15 @@ static gint eclipseGoto(GtkButton*, EclipseData* ed) sim->update(0.0); double distance = target.radius() * 4.0; - sim->gotoLocation(UniversalCoord::Zero().offsetKm(Vector3d::UnitX() * distance), + sim->gotoLocation(UniversalCoord::Zero().offsetKm(Eigen::Vector3d::UnitX() * distance), (math::YRot90Conjugate * math::XRot90Conjugate), 2.5); return TRUE; } - /* CALLBACK: Double-click on the Eclipse Finder Listbox */ -static gint eclipse2Click(GtkWidget*, GdkEventButton* event, EclipseData* ed) +gint +eclipse2Click(GtkWidget*, GdkEventButton* event, EclipseData* ed) { if (event->type == GDK_2BUTTON_PRESS) { /* Double-click, same as hitting the select and go button */ @@ -349,9 +248,9 @@ static gint eclipse2Click(GtkWidget*, GdkEventButton* event, EclipseData* ed) return FALSE; } - /* CALLBACK: Compute button in Eclipse Finder */ -static void eclipseCompute(GtkButton* button, EclipseData* ed) +void +eclipseCompute(GtkButton* button, EclipseData* ed) { /* Set the cursor to a watch and force redraw */ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(button)), gdk_cursor_new(GDK_WATCH)); @@ -365,7 +264,7 @@ static void eclipseCompute(GtkButton* button, EclipseData* ed) astro::Date to(ed->d2->year, ed->d2->month, ed->d2->day); /* Initialize the eclipse finder */ - vector eclipseListRaw; + std::vector eclipseListRaw; const SolarSystem* sys = ed->app->core->getSimulation()->getNearestSolarSystem(); if (sys != nullptr && sys->getStar()->getIndex() == 0) { @@ -383,9 +282,9 @@ static void eclipseCompute(GtkButton* button, EclipseData* ed) astro::Date start(e.startTime); astro::Date end(e.endTime); - sprintf(d, "%d-%02d-%02d", start.year, start.month, start.day); - sprintf(strStart, "%02d:%02d:%02d", start.hour, start.minute, (int)start.seconds); - sprintf(strEnd, "%02d:%02d:%02d", end.hour, end.minute, (int)end.seconds); + std::sprintf(d, "%d-%02d-%02d", start.year, start.month, start.day); + std::sprintf(strStart, "%02d:%02d:%02d", start.hour, start.minute, (int)start.seconds); + std::sprintf(strEnd, "%02d:%02d:%02d", end.hour, end.minute, (int)end.seconds); /* Set time to middle time so that eclipse it right on earth */ astro::Date timeToSet = (start + end) / 2.0f; @@ -425,9 +324,9 @@ static void eclipseCompute(GtkButton* button, EclipseData* ed) gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(button)), gdk_cursor_new(GDK_LEFT_PTR)); } - /* CALLBACK: When Eclipse Body is selected */ -static void eclipseBodySelect(GtkComboBox* comboBox, EclipseData* ed) +void +eclipseBodySelect(GtkComboBox* comboBox, EclipseData* ed) { int itemIndex = gtk_combo_box_get_active(comboBox); @@ -435,9 +334,9 @@ static void eclipseBodySelect(GtkComboBox* comboBox, EclipseData* ed) ed->body = eclipsePlanetTitles[itemIndex]; } - /* CALLBACK: When Eclipse Type (Solar:Moon) is selected */ -static void eclipseTypeSelect(GtkComboBox* comboBox, EclipseData* ed) +void +eclipseTypeSelect(GtkComboBox* comboBox, EclipseData* ed) { int itemIndex = gtk_combo_box_get_active(comboBox); @@ -449,17 +348,17 @@ static void eclipseTypeSelect(GtkComboBox* comboBox, EclipseData* ed) ed->type = Eclipse::Lunar; } - /* CALLBACK: When Eclipse is selected in Eclipse Finder */ -static void listEclipseSelect(GtkTreeSelection* sel, EclipseData* ed) +void +listEclipseSelect(GtkTreeSelection* sel, EclipseData* ed) { /* Simply set the selection pointer to this data item */ ed->sel = sel; } - /* CALLBACK: Destroy Window */ -static void eclipseDestroy(GtkWidget* w, gint, EclipseData* ed) +void +eclipseDestroy(GtkWidget* w, gint, EclipseData* ed) { gtk_widget_destroy(GTK_WIDGET(w)); g_free(ed->d1); @@ -467,12 +366,167 @@ static void eclipseDestroy(GtkWidget* w, gint, EclipseData* ed) g_free(ed); } +} // end unnamed namespace -/* HELPER: set a date string in a button */ -static void setButtonDateString(GtkToggleButton *button, int year, int month, int day) +/* ENTRY: Navigation -> Eclipse Finder */ +void +dialogEclipseFinder(AppData* app) { - char date[50]; - sprintf(date, "%d %s %d", day, monthOptions[month - 1], year); + EclipseData* ed = g_new0(EclipseData, 1); + selDate* d1 = g_new0(selDate, 1); + selDate* d2 = g_new0(selDate, 1); + ed->d1 = d1; + ed->d2 = d2; + ed->app = app; + ed->eclipseList = NULL; + ed->eclipseListStore = NULL; + ed->type = Eclipse::Solar; + ed->body = eclipsePlanetTitles[0]; + ed->sel = NULL; - gtk_button_set_label(GTK_BUTTON(button), date); + ed->window = GTK_DIALOG(gtk_dialog_new_with_buttons("Eclipse Finder", + GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + NULL)); + gtk_window_set_modal(GTK_WINDOW(ed->window), FALSE); + + GtkWidget *mainbox = gtk_dialog_get_content_area(GTK_DIALOG(ed->window)); + gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING); + + GtkWidget *scrolled_win = gtk_scrolled_window_new(NULL, NULL); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0); + + /* Create listbox list. + * Six invisible ints at the end to hold actual time. + * This will save string parsing like in KDE version. + * Last field holds pointer to selected Body. */ + ed->eclipseListStore = gtk_list_store_new(12, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_POINTER); + ed->eclipseList = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ed->eclipseListStore)); + + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(ed->eclipseList), TRUE); + gtk_container_add(GTK_CONTAINER(scrolled_win), ed->eclipseList); + + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + /* Add the columns */ + for (int i=0; i<5; i++) { + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(eclipseTitles[i], renderer, "text", i, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(ed->eclipseList), column); + } + + /* Set up callback for when an eclipse is selected */ + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ed->eclipseList)); + g_signal_connect(selection, "changed", G_CALLBACK(listEclipseSelect), ed); + + /* From now on, it's the bottom-of-the-window controls */ + GtkWidget *label; + GtkWidget *hbox; + + /* -------------------------------- */ + hbox = gtk_hbox_new(FALSE, CELSPACING); + + label = gtk_label_new("Find"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + GtkWidget *menuTypeBox = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(hbox), menuTypeBox, FALSE, FALSE, 0); + + label = gtk_label_new("eclipse on"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + GtkWidget* menuBodyBox = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(hbox), menuBodyBox, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); + /* -------------------------------- */ + hbox = gtk_hbox_new(FALSE, CELSPACING); + + label = gtk_label_new("From"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + /* Get current date */ + astro::Date datenow(app->simulation->getTime()); + + /* Set current time */ + ed->d1->year = datenow.year - 1; + ed->d1->month = datenow.month; + ed->d1->day = datenow.day; + + /* Set time a year from now */ + ed->d2->year = ed->d1->year + 2; + ed->d2->month = ed->d1->month; + ed->d2->day = ed->d1->day; + + GtkWidget* date1Button = gtk_toggle_button_new(); + setButtonDateString(GTK_TOGGLE_BUTTON(date1Button), ed->d1->year, ed->d1->month, ed->d1->day); + g_object_set_data(G_OBJECT(date1Button), "eclipsedata", ed->d1); + gtk_box_pack_start(GTK_BOX(hbox), date1Button, FALSE, FALSE, 0); + + label = gtk_label_new("to"); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + GtkWidget* date2Button = gtk_toggle_button_new(); + setButtonDateString(GTK_TOGGLE_BUTTON(date2Button), ed->d2->year, ed->d2->month, ed->d2->day); + g_object_set_data(G_OBJECT(date2Button), "eclipsedata", ed->d2); + gtk_box_pack_start(GTK_BOX(hbox), date2Button, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); + /* -------------------------------- */ + + /* Common Buttons */ + hbox = gtk_hbox_new(TRUE, CELSPACING); + if (buttonMake(hbox, "Compute", (GCallback)eclipseCompute, ed)) + return; + if (buttonMake(hbox, "Set Date and Go to Planet", (GCallback)eclipseGoto, ed)) + return; + gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); + + /* Set up the drop-down boxes */ + for (int i = 0; eclipseTypeTitles[i] != NULL; i++) + { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(menuTypeBox), eclipseTypeTitles[i]); + } + gtk_combo_box_set_active(GTK_COMBO_BOX(menuTypeBox), 0); + + for (int i = 0; eclipsePlanetTitles[i] != NULL; i++) + { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(menuBodyBox), eclipsePlanetTitles[i]); + } + gtk_combo_box_set_active(GTK_COMBO_BOX(menuBodyBox), 0); + + /* Hook up all the signals */ + g_signal_connect(G_OBJECT(menuTypeBox), "changed", G_CALLBACK(eclipseTypeSelect), ed); + g_signal_connect(G_OBJECT(menuBodyBox), "changed", G_CALLBACK(eclipseBodySelect), ed); + + /* Double-click handler */ + g_signal_connect(G_OBJECT(ed->eclipseList), "button-press-event", G_CALLBACK(eclipse2Click), ed); + + g_signal_connect(G_OBJECT(date1Button), "toggled", G_CALLBACK(showCalPopup), ed); + g_signal_connect(G_OBJECT(date2Button), "toggled", G_CALLBACK(showCalPopup), ed); + g_signal_connect(ed->window, "response", G_CALLBACK(eclipseDestroy), ed); + + gtk_widget_set_size_request(GTK_WIDGET(ed->window), -1, 400); /* Absolute Size, urghhh */ + gtk_widget_show_all(GTK_WIDGET(ed->window)); } + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-eclipse.h b/src/celestia/gtk/dialog-eclipse.h index fe6e0e7601..96eb1563bf 100644 --- a/src/celestia/gtk/dialog-eclipse.h +++ b/src/celestia/gtk/dialog-eclipse.h @@ -17,65 +17,10 @@ #include "common.h" +namespace celestia::gtk +{ /* Entry Function */ void dialogEclipseFinder(AppData* app); - -/* Local Data Structures */ -/* Date selection data type */ -typedef struct _selDate selDate; -struct _selDate { - int year; - int month; - int day; -}; - -typedef struct _EclipseData EclipseData; -struct _EclipseData { - AppData* app; - - /* Start Time */ - selDate* d1; - - /* End Time */ - selDate* d2; - - int type; - const char* body; - GtkTreeSelection* sel; - - GtkWidget *eclipseList; - GtkListStore *eclipseListStore; - - GtkDialog* window; -}; - - -const char * const eclipseTitles[] = -{ - "Planet", - "Satellite", - "Date", - "Start", - "End", - NULL -}; - -const char * const eclipseTypeTitles[] = -{ - "solar", - "moon", - NULL -}; - -const char * const eclipsePlanetTitles[] = -{ - "Earth", - "Jupiter", - "Saturn", - "Uranus", - "Neptune", - "Pluto", - NULL -}; +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-goto.cpp b/src/celestia/gtk/dialog-goto.cpp index 651b058c50..d545f28191 100644 --- a/src/celestia/gtk/dialog-goto.cpp +++ b/src/celestia/gtk/dialog-goto.cpp @@ -10,6 +10,10 @@ * $Id: dialog-goto.cpp,v 1.1 2005-12-06 03:19:35 suwalski Exp $ */ +#include + +#include + #include #include @@ -19,22 +23,134 @@ #include "dialog-goto.h" #include "common.h" -using namespace Eigen; +namespace celestia::gtk +{ + +namespace +{ + +/* Local Data Structures */ +typedef struct _gotoObjectData gotoObjectData; +struct _gotoObjectData { + AppData* app; + + GtkWidget* dialog; + GtkWidget* nameEntry; + GtkWidget* latEntry; + GtkWidget* longEntry; + GtkWidget* distEntry; + + int units; +}; + +constexpr std::array unitLabels +{ + "km", + "radii", + "au", + static_cast(nullptr), +}; + +/* HELPER: Get the float value from one of the GtkEntrys */ +gboolean +GetEntryFloat(GtkWidget* w, float& f) +{ + GtkEntry* entry = GTK_ENTRY(w); + bool tmp; + if (entry == nullptr) + return false; -namespace astro = celestia::astro; -namespace math = celestia::math; + gchar* text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); + f = 0.0; + if (text == nullptr) + return false; -/* Declarations: Callbacks */ -static int changeGotoUnits(GtkButton* w, gpointer choice); -static void responseGotoObject(GtkDialog* w, gint response, gotoObjectData* d); + tmp = std::sscanf(text, " %f", &f) == 1; + g_free(text); + return tmp; +} + +/* HELPER: Goes to the object specified by gotoObjectData */ +void +GotoObject(gotoObjectData* gotoObjectDlg) +{ + const gchar* objectName = gtk_entry_get_text(GTK_ENTRY(gotoObjectDlg->nameEntry)); + + if (objectName != nullptr) + { + Simulation* simulation = gotoObjectDlg->app->simulation; + Selection sel = simulation->findObjectFromPath(objectName); + + if (!sel.empty()) + { + simulation->setSelection(sel); + simulation->follow(); + + auto distance = static_cast(sel.radius() * 5.0f); + if (GetEntryFloat(gotoObjectDlg->distEntry, distance)) + { + /* Adjust for km (0), radii (1), au (2) */ + if (gotoObjectDlg->units == 2) + distance = astro::AUtoKilometers(distance); + else if (gotoObjectDlg->units == 1) + distance = distance * (float) sel.radius(); -/* Declarations: Helpers */ -static gboolean GetEntryFloat(GtkWidget* w, float& f); -static void GotoObject(gotoObjectData* gotoObjectDlg); + distance += (float) sel.radius(); + } + + float longitude, latitude; + if (GetEntryFloat(gotoObjectDlg->latEntry, latitude) && + GetEntryFloat(gotoObjectDlg->longEntry, longitude)) + { + simulation->gotoSelectionLongLat(5.0, + distance, + math::degToRad(longitude), + math::degToRad(latitude), + Eigen::Vector3f::UnitY()); + } + else + { + simulation->gotoSelection(5.0, + distance, + Eigen::Vector3f::UnitY(), + ObserverFrame::ObserverLocal); + } + } + } +} + +/* CALLBACK: for km|radii|au in Goto Object dialog */ +int +changeGotoUnits(GtkButton* w, gpointer choice) +{ + gotoObjectData* data = (gotoObjectData *)g_object_get_data(G_OBJECT(w), "data"); + gint selection = GPOINTER_TO_INT(choice); + + data->units = selection; + + return TRUE; +} + +/* CALLBACK: response from this dialog. + * Need this because gtk_dialog_run produces a modal window. */ +void +responseGotoObject(GtkDialog* w, gint response, gotoObjectData* d) +{ + switch (response) { + case GTK_RESPONSE_OK: + GotoObject(d); + break; + case GTK_RESPONSE_CLOSE: + gtk_widget_destroy(GTK_WIDGET(w)); + g_free(d); + } +} +} // end unnamed namespace /* ENTRY: Navigation->Goto Object */ -void dialogGotoObject(AppData* app) +void +dialogGotoObject(AppData* app) { gotoObjectData *data = g_new0(gotoObjectData, 1); data->app = app; @@ -46,17 +162,17 @@ void dialogGotoObject(AppData* app) GTK_RESPONSE_OK, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); + nullptr); data->nameEntry = gtk_entry_new(); data->latEntry = gtk_entry_new(); data->longEntry = gtk_entry_new(); data->distEntry = gtk_entry_new(); - if (data->dialog == NULL || - data->nameEntry == NULL || - data->latEntry == NULL || - data->longEntry == NULL || - data->distEntry == NULL) + if (data->dialog == nullptr || + data->nameEntry == nullptr || + data->latEntry == nullptr || + data->longEntry == nullptr || + data->distEntry == nullptr) { /* Potential memory leak here ... */ return; @@ -67,15 +183,15 @@ void dialogGotoObject(AppData* app) app->simulation->getSelectionLongLat(distance, longitude, latitude); /* Display information in format appropriate for object */ - if (app->simulation->getSelection().body() != NULL) + if (app->simulation->getSelection().body() != nullptr) { char temp[20]; distance = distance - (double) app->simulation->getSelection().body()->getRadius(); - sprintf(temp, "%.1f", (float)distance); + std::sprintf(temp, "%.1f", (float)distance); gtk_entry_set_text(GTK_ENTRY(data->distEntry), temp); - sprintf(temp, "%.5f", (float)longitude); + std::sprintf(temp, "%.5f", (float)longitude); gtk_entry_set_text(GTK_ENTRY(data->longEntry), temp); - sprintf(temp, "%.5f", (float)latitude); + std::sprintf(temp, "%.5f", (float)latitude); gtk_entry_set_text(GTK_ENTRY(data->latEntry), temp); gtk_entry_set_text(GTK_ENTRY(data->nameEntry), (char*) app->simulation->getSelection().body()->getName().c_str()); } @@ -83,9 +199,9 @@ void dialogGotoObject(AppData* app) GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(data->dialog)); gtk_container_set_border_width(GTK_CONTAINER(vbox), CELSPACING); - GtkWidget* align = NULL; - GtkWidget* hbox = NULL; - GtkWidget* label = NULL; + GtkWidget* align = nullptr; + GtkWidget* hbox = nullptr; + GtkWidget* label = nullptr; /* Object name label and entry */ align = gtk_alignment_new(1, 0, 0, 0); @@ -125,7 +241,7 @@ void dialogGotoObject(AppData* app) /* Distance Options */ data->units = 0; hbox = gtk_hbox_new(FALSE, CELSPACING); - makeRadioItems(unitLabels, hbox, G_CALLBACK(changeGotoUnits), NULL, data); + makeRadioItems(unitLabels.data(), hbox, G_CALLBACK(changeGotoUnits), nullptr, data); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); g_signal_connect(data->dialog, "response", @@ -134,97 +250,4 @@ void dialogGotoObject(AppData* app) gtk_widget_show_all(data->dialog); } - -/* CALLBACK: for km|radii|au in Goto Object dialog */ -static int changeGotoUnits(GtkButton* w, gpointer choice) -{ - gotoObjectData* data = (gotoObjectData *)g_object_get_data(G_OBJECT(w), "data"); - gint selection = GPOINTER_TO_INT(choice); - - data->units = selection; - - return TRUE; -} - - -/* CALLBACK: response from this dialog. - * Need this because gtk_dialog_run produces a modal window. */ -static void responseGotoObject(GtkDialog* w, gint response, gotoObjectData* d) -{ - switch (response) { - case GTK_RESPONSE_OK: - GotoObject(d); - break; - case GTK_RESPONSE_CLOSE: - gtk_widget_destroy(GTK_WIDGET(w)); - g_free(d); - } -} - - -/* HELPER: Get the float value from one of the GtkEntrys */ -static gboolean GetEntryFloat(GtkWidget* w, float& f) -{ - GtkEntry* entry = GTK_ENTRY(w); - bool tmp; - if (entry == NULL) - return false; - - gchar* text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - f = 0.0; - if (text == NULL) - return false; - - tmp = sscanf(text, " %f", &f) == 1; - g_free(text); - return tmp; -} - - -/* HELPER: Goes to the object specified by gotoObjectData */ -static void GotoObject(gotoObjectData* gotoObjectDlg) -{ - const gchar* objectName = gtk_entry_get_text(GTK_ENTRY(gotoObjectDlg->nameEntry)); - - if (objectName != NULL) - { - Simulation* simulation = gotoObjectDlg->app->simulation; - Selection sel = simulation->findObjectFromPath(objectName); - - if (!sel.empty()) - { - simulation->setSelection(sel); - simulation->follow(); - - float distance = (float) (sel.radius() * 5.0f); - if (GetEntryFloat(gotoObjectDlg->distEntry, distance)) - { - /* Adjust for km (0), radii (1), au (2) */ - if (gotoObjectDlg->units == 2) - distance = astro::AUtoKilometers(distance); - else if (gotoObjectDlg->units == 1) - distance = distance * (float) sel.radius(); - - distance += (float) sel.radius(); - } - - float longitude, latitude; - if (GetEntryFloat(gotoObjectDlg->latEntry, latitude) && - GetEntryFloat(gotoObjectDlg->longEntry, longitude)) - { - simulation->gotoSelectionLongLat(5.0, - distance, - math::degToRad(longitude), - math::degToRad(latitude), - Vector3f::UnitY()); - } - else - { - simulation->gotoSelection(5.0, - distance, - Vector3f::UnitY(), - ObserverFrame::ObserverLocal); - } - } - } -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-goto.h b/src/celestia/gtk/dialog-goto.h index 3006040279..4396da5410 100644 --- a/src/celestia/gtk/dialog-goto.h +++ b/src/celestia/gtk/dialog-goto.h @@ -16,29 +16,10 @@ #include "common.h" +namespace celestia::gtk +{ /* Entry Function */ void dialogGotoObject(AppData* app); - -/* Local Data Structures */ -typedef struct _gotoObjectData gotoObjectData; -struct _gotoObjectData { - AppData* app; - - GtkWidget* dialog; - GtkWidget* nameEntry; - GtkWidget* latEntry; - GtkWidget* longEntry; - GtkWidget* distEntry; - - int units; -}; - -static const char * const unitLabels[] = -{ - "km", - "radii", - "au", - NULL -}; +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-options.cpp b/src/celestia/gtk/dialog-options.cpp index eb1c0d57e0..3dede4e4c4 100644 --- a/src/celestia/gtk/dialog-options.cpp +++ b/src/celestia/gtk/dialog-options.cpp @@ -10,34 +10,132 @@ * $Id: dialog-options.cpp,v 1.7 2008-01-21 04:55:19 suwalski Exp $ */ +#include +#include + #include #include "dialog-options.h" #include "common.h" #include "ui.h" +namespace celestia::gtk +{ + +namespace +{ + +/* Local data */ +constexpr int DistanceSliderRange = 10000; +constexpr float MaxDistanceLimit = 1.0e6f; + +constexpr std::array ambientLabels +{ + "None", + "Low", + "Medium", + static_cast(nullptr), +}; + +constexpr std::array infoLabels +{ + "None", + "Terse", + "Verbose", + static_cast(nullptr), +}; + +/* HELPER: Creates check buttons from a GtkActionGroup */ +void +checkButtonsFromAG(const GtkToggleActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box) +{ + for (int i = 0; i < size; i++) + { + GtkAction* action = gtk_action_group_get_action(ag, actions[i].name); + + /* Mnemonic work-around for bug in GTK 2.6 > 2.6.2, where the label + * is not set with action proxy. */ + GtkWidget* w = gtk_check_button_new_with_mnemonic(actions[i].label); + + gtk_activatable_set_related_action(GTK_ACTIVATABLE(w), action); + gtk_box_pack_start(GTK_BOX(box), w, TRUE, TRUE, 0); + } +} + +/* HELPER: Creates toggle (instead of radio) buttons from a GtkActionGroup. + * Cannot be GtkRadioButtons because of GTK limitations/bugs. */ +void +toggleButtonsFromAG(const GtkRadioActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box) +{ + for (int i = 0; i < size; i++) + { + GtkAction* action = gtk_action_group_get_action(ag, actions[i].name); + + /* Mnemonic work-around for bug in GTK 2.6 > 2.6.2, where the label + * is not set with action proxy. */ + GtkWidget* w = gtk_toggle_button_new_with_mnemonic(actions[i].label); + + gtk_activatable_set_related_action(GTK_ACTIVATABLE(w), action); + gtk_box_pack_start(GTK_BOX(box), w, TRUE, TRUE, 0); + } +} + +/* HELPER: gives a logarithmic value based on linear value */ +float +makeDistanceLimit(float value) +{ + float logDistanceLimit = value / DistanceSliderRange; + return std::pow(MaxDistanceLimit, logDistanceLimit); +} + +/* CALLBACK: React to changes in the star distance limit slider */ +gint +changeDistanceLimit(GtkRange *slider, AppData* app) +{ + GtkLabel* magLabel = (GtkLabel*)g_object_get_data(G_OBJECT(slider), "valueLabel"); + float limit = makeDistanceLimit(gtk_range_get_value(slider)); + app->renderer->setDistanceLimit(limit); + + char labeltext[16] = "100000 ly"; + sprintf(labeltext, "%ld ly", (long)(limit + 0.5)); + gtk_label_set_text(GTK_LABEL(magLabel), labeltext); + + return TRUE; +} -/* Definitions: Callbacks */ -static gint changeDistanceLimit(GtkRange *slider, AppData* app); -static gint changeTextureResolution(GtkRange *slider, AppData* app); -static gchar* formatTextureSlider(GtkRange*, gdouble value); +/* CALLBACK: React to changes in the texture resolution slider */ +gint +changeTextureResolution(GtkRange *slider, AppData* app) +{ + app->renderer->setResolution((int)gtk_range_get_value(slider)); -/* Definitions: Helpers */ -static void checkButtonsFromAG(const GtkToggleActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box); -static void toggleButtonsFromAG(const GtkRadioActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box); -static float makeDistanceLimit(float value); + /* Seeing as this is not a GtkAction, kick off the update function */ + resyncTextureResolutionActions(app); + return TRUE; +} -static const int DistanceSliderRange = 10000; -static const float MaxDistanceLimit = 1.0e6f; +/* CALLBACK: Format the label under the texture detail slider */ +gchar* +formatTextureSlider(GtkRange*, gdouble value) +{ + switch ((int)value) { + case 0: return g_strdup("Low"); + case 1: return g_strdup("Medium"); + case 2: return g_strdup("High"); + default: return g_strdup("Error"); + } +} +} // end unnamed namespace /* ENTRY: Options -> View Options... */ -void dialogViewOptions(AppData* app) +void +dialogViewOptions(AppData* app) { /* This dialog is hidden and shown because it is likely to be used a lot * and the actions->widgets operations are fairly intensive. */ - if (app->optionDialog != NULL) + if (app->optionDialog != nullptr) { gtk_window_present(GTK_WINDOW(app->optionDialog)); return; @@ -48,7 +146,7 @@ void dialogViewOptions(AppData* app) GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); + nullptr); /* Create the main layout boxes */ GtkWidget* hbox = gtk_hbox_new(FALSE, CELSPACING); @@ -116,12 +214,11 @@ void dialogViewOptions(AppData* app) gtk_container_set_border_width(GTK_CONTAINER(hbox), CELSPACING); float logDistanceLimit = log(app->renderer->getDistanceLimit()) / log((float)MaxDistanceLimit); - GtkAdjustment *adj = (GtkAdjustment *) - gtk_adjustment_new((gfloat)(logDistanceLimit * DistanceSliderRange), - 0.0, DistanceSliderRange, 1.0, 2.0, 0.0); + GtkAdjustment *adj = gtk_adjustment_new(static_cast(logDistanceLimit * DistanceSliderRange), + 0.0, DistanceSliderRange, 1.0, 2.0, 0.0); /* Distance limit slider */ - GtkWidget* magLabel = gtk_label_new(NULL); + GtkWidget* magLabel = gtk_label_new(nullptr); GtkWidget* slider = gtk_hscale_new(adj); g_object_set_data(G_OBJECT(slider), "valueLabel", magLabel); gtk_scale_set_draw_value(GTK_SCALE(slider), 0); @@ -137,13 +234,13 @@ void dialogViewOptions(AppData* app) gtk_range_set_value(GTK_RANGE(textureSlider), app->renderer->getResolution()); gtk_box_pack_start(GTK_BOX(textureBox), textureSlider, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(textureSlider), "value-changed", G_CALLBACK(changeTextureResolution), app); - g_signal_connect(G_OBJECT(textureSlider), "format-value", G_CALLBACK(formatTextureSlider), NULL); + g_signal_connect(G_OBJECT(textureSlider), "format-value", G_CALLBACK(formatTextureSlider), nullptr); - checkButtonsFromAG(actionsRenderFlags, G_N_ELEMENTS(actionsRenderFlags), app->agRender, showBox); - checkButtonsFromAG(actionsOrbitFlags, G_N_ELEMENTS(actionsOrbitFlags), app->agOrbit, orbitBox); - checkButtonsFromAG(actionsLabelFlags, G_N_ELEMENTS(actionsLabelFlags), app->agLabel, labelBox); - toggleButtonsFromAG(actionsVerbosity, G_N_ELEMENTS(actionsVerbosity), app->agVerbosity, infoBox); - toggleButtonsFromAG(actionsAmbientLight, G_N_ELEMENTS(actionsAmbientLight), app->agAmbient, ambientBox); + checkButtonsFromAG(actionsRenderFlags.data(), static_cast(actionsRenderFlags.size()), app->agRender, showBox); + checkButtonsFromAG(actionsOrbitFlags.data(), static_cast(actionsOrbitFlags.size()), app->agOrbit, orbitBox); + checkButtonsFromAG(actionsLabelFlags.data(), static_cast(actionsLabelFlags.size()), app->agLabel, labelBox); + toggleButtonsFromAG(actionsVerbosity.data(), static_cast(actionsVerbosity.size()), app->agVerbosity, infoBox); + toggleButtonsFromAG(actionsAmbientLight.data(), static_cast(actionsAmbientLight.size()), app->agAmbient, ambientBox); g_signal_connect(app->optionDialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), GTK_WIDGET(app->optionDialog)); @@ -156,88 +253,4 @@ void dialogViewOptions(AppData* app) gtk_window_present(GTK_WINDOW(app->optionDialog)); } - -/* CALLBACK: React to changes in the star distance limit slider */ -static gint changeDistanceLimit(GtkRange *slider, AppData* app) -{ - GtkLabel* magLabel = (GtkLabel*)g_object_get_data(G_OBJECT(slider), "valueLabel"); - float limit = makeDistanceLimit(gtk_range_get_value(slider)); - app->renderer->setDistanceLimit(limit); - - char labeltext[16] = "100000 ly"; - sprintf(labeltext, "%ld ly", (long)(limit + 0.5)); - gtk_label_set_text(GTK_LABEL(magLabel), labeltext); - - #ifdef GNOME - /* Distance limit changes do not trigger an event like the other - * render settings. Save setting here. */ - gconf_client_set_int(app->client, "/apps/celestia/distanceLimit", (int)(limit + 0.5), NULL); - #endif /* GNOME */ - - return TRUE; -} - - -/* CALLBACK: React to changes in the texture resolution slider */ -static gint changeTextureResolution(GtkRange *slider, AppData* app) -{ - app->renderer->setResolution((int)gtk_range_get_value(slider)); - - /* Seeing as this is not a GtkAction, kick off the update function */ - resyncTextureResolutionActions(app); - - return TRUE; -} - - -/* CALLBACK: Format the label under the texture detail slider */ -static gchar* formatTextureSlider(GtkRange*, gdouble value) -{ - switch ((int)value) { - case 0: return g_strdup("Low"); - case 1: return g_strdup("Medium"); - case 2: return g_strdup("High"); - default: return g_strdup("Error"); - } -} - - -/* HELPER: Creates check buttons from a GtkActionGroup */ -static void checkButtonsFromAG(const GtkToggleActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box) -{ - for (int i = 0; i < size; i++) { - GtkAction* action = gtk_action_group_get_action(ag, actions[i].name); - - /* Mnemonic work-around for bug in GTK 2.6 > 2.6.2, where the label - * is not set with action proxy. */ - GtkWidget* w = gtk_check_button_new_with_mnemonic(actions[i].label); - - gtk_activatable_set_related_action(GTK_ACTIVATABLE(w), action); - gtk_box_pack_start(GTK_BOX(box), w, TRUE, TRUE, 0); - } -} - - -/* HELPER: Creates toggle (instead of radio) buttons from a GtkActionGroup. - * Cannot be GtkRadioButtons because of GTK limitations/bugs. */ -static void toggleButtonsFromAG(const GtkRadioActionEntry actions[], int size, GtkActionGroup* ag, GtkWidget* box) -{ - for (int i = 0; i < size; i++) { - GtkAction* action = gtk_action_group_get_action(ag, actions[i].name); - - /* Mnemonic work-around for bug in GTK 2.6 > 2.6.2, where the label - * is not set with action proxy. */ - GtkWidget* w = gtk_toggle_button_new_with_mnemonic(actions[i].label); - - gtk_activatable_set_related_action(GTK_ACTIVATABLE(w), action); - gtk_box_pack_start(GTK_BOX(box), w, TRUE, TRUE, 0); - } -} - - -/* HELPER: gives a logarithmic value based on linear value */ -static float makeDistanceLimit(float value) -{ - float logDistanceLimit = value / DistanceSliderRange; - return (float) pow(MaxDistanceLimit, logDistanceLimit); -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-options.h b/src/celestia/gtk/dialog-options.h index 6c92ccac8b..0c1418734c 100644 --- a/src/celestia/gtk/dialog-options.h +++ b/src/celestia/gtk/dialog-options.h @@ -14,23 +14,10 @@ #include "common.h" +namespace celestia::gtk +{ + /* Entry Function */ void dialogViewOptions(AppData* app); - -/* Local data */ -static const char * const ambientLabels[]= -{ - "None", - "Low", - "Medium", - NULL -}; - -static const char * const infoLabels[]= -{ - "None", - "Terse", - "Verbose", - NULL -}; +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-solar.cpp b/src/celestia/gtk/dialog-solar.cpp index f28aec8105..c51f996a0e 100644 --- a/src/celestia/gtk/dialog-solar.cpp +++ b/src/celestia/gtk/dialog-solar.cpp @@ -10,6 +10,9 @@ * $Id: dialog-solar.cpp,v 1.2 2005-12-13 06:19:57 suwalski Exp $ */ +#include +#include + #include #include @@ -23,83 +26,22 @@ #include "actions.h" #include "common.h" - -/* Declarations: Callbacks */ -static void treeSolarSelect(GtkTreeSelection* sel, AppData* app); - -/* Declarations: Helpers */ -static void addPlanetarySystemToTree(const PlanetarySystem* sys, - GtkTreeStore* solarTreeStore, - GtkTreeIter* parent); -static void loadNearestStarSystem(AppData* data, GtkWidget* solarTree, - GtkTreeStore* solarTreeStore); - - -/* ENTRY: Navigation -> Solar System Browser... */ -void dialogSolarBrowser(AppData* app) +namespace celestia::gtk { - GtkWidget *solarTree = NULL; - GtkTreeStore *solarTreeStore = NULL; - - GtkWidget *browser = gtk_dialog_new_with_buttons("Solar System Browser", - GTK_WINDOW(app->mainWindow), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CLOSE, - GTK_RESPONSE_CLOSE, - NULL); - app->simulation->setSelection(Selection((Star *) NULL)); - - /* Solar System Browser */ - GtkWidget *mainbox = gtk_dialog_get_content_area(GTK_DIALOG(browser)); - gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING); - - GtkWidget *scrolled_win = gtk_scrolled_window_new(NULL, NULL); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0); - - /* Set the tree store to have 2 visible cols, two hidden. The hidden ones - * store pointer to the row's object and its Selection::Type. */ - solarTreeStore = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT); - solarTree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(solarTreeStore)); - - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(solarTree), TRUE); - gtk_container_add(GTK_CONTAINER(scrolled_win), solarTree); - - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - for (int i = 0; i < 2; i++) { - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(ssTitles[i], renderer, "text", i, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(solarTree), column); - gtk_tree_view_column_set_min_width(column, 200); - } - - loadNearestStarSystem(app, solarTree, solarTreeStore); - - GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(solarTree)); - g_signal_connect(selection, "changed", G_CALLBACK(treeSolarSelect), app); - - /* Common Buttons */ - GtkWidget *hbox = gtk_hbox_new(TRUE, CELSPACING); - if (buttonMake(hbox, "Center", (GCallback)actionCenterSelection, app)) - return; - if (buttonMake(hbox, "Go To", (GCallback)actionGotoSelection, app)) - return; - gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); - - g_signal_connect(browser, "response", G_CALLBACK(gtk_widget_destroy), browser); - - gtk_widget_set_size_request(browser, -1, 400); /* Absolute Size, urghhh */ - gtk_widget_show_all(browser); -} +namespace +{ +/* Local Data */ +constexpr std::array ssTitles +{ + "Name", + "Type" +}; /* CALLBACK: When Object is selected in Solar System Browser */ -static void treeSolarSelect(GtkTreeSelection* sel, AppData* app) +void +treeSolarSelect(GtkTreeSelection* sel, AppData* app) { gpointer item; SelectionType type; @@ -130,7 +72,8 @@ static void treeSolarSelect(GtkTreeSelection* sel, AppData* app) /* HELPER: Recursively populate GtkTreeView with objects in PlanetarySystem */ -static void addPlanetarySystemToTree(const PlanetarySystem* sys, GtkTreeStore* solarTreeStore, GtkTreeIter* parent) +void +addPlanetarySystemToTree(const PlanetarySystem* sys, GtkTreeStore* solarTreeStore, GtkTreeIter* parent) { const char *name; const char *type; @@ -185,15 +128,15 @@ static void addPlanetarySystemToTree(const PlanetarySystem* sys, GtkTreeStore* s -1); /* Recurse */ - if (satellites != NULL) + if (satellites != nullptr) addPlanetarySystemToTree(satellites, solarTreeStore, &child); } } - /* HELPER: Retrieves closest system and calls addPlanetarySystemToTree to * populate. */ -static void loadNearestStarSystem(AppData* app, GtkWidget* solarTree, GtkTreeStore* solarTreeStore) +void +loadNearestStarSystem(AppData* app, GtkWidget* solarTree, GtkTreeStore* solarTreeStore) { const char* name; char type[30]; @@ -206,15 +149,15 @@ static void loadNearestStarSystem(AppData* app, GtkWidget* solarTree, GtkTreeSto GtkTreeIter top; gtk_tree_store_clear(solarTreeStore); - gtk_tree_store_append(solarTreeStore, &top, NULL); + gtk_tree_store_append(solarTreeStore, &top, nullptr); - if (solarSys != NULL) + if (solarSys != nullptr) { nearestStar = solarSys->getStar(); name = g_strdup(stardb->getStarName(*nearestStar).c_str()); - sprintf(type, "%s Star", nearestStar->getSpectralType()); + std::sprintf(type, "%s Star", nearestStar->getSpectralType()); /* Set up the top-level node. */ gtk_tree_store_set(solarTreeStore, &top, @@ -225,7 +168,7 @@ static void loadNearestStarSystem(AppData* app, GtkWidget* solarTree, GtkTreeSto -1); const PlanetarySystem* planets = solarSys->getPlanets(); - if (planets != NULL) + if (planets != nullptr) addPlanetarySystemToTree(planets, solarTreeStore, &top); /* Open up the top node */ @@ -235,3 +178,71 @@ static void loadNearestStarSystem(AppData* app, GtkWidget* solarTree, GtkTreeSto else gtk_tree_store_set(solarTreeStore, &top, 0, "No Planetary Bodies", -1); } + +} // end unnamed namespace + +/* ENTRY: Navigation -> Solar System Browser... */ +void +dialogSolarBrowser(AppData* app) +{ + GtkWidget *solarTree = nullptr; + GtkTreeStore *solarTreeStore = nullptr; + + GtkWidget *browser = gtk_dialog_new_with_buttons("Solar System Browser", + GTK_WINDOW(app->mainWindow), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + nullptr); + app->simulation->setSelection(Selection((Star *) nullptr)); + + /* Solar System Browser */ + GtkWidget *mainbox = gtk_dialog_get_content_area(GTK_DIALOG(browser)); + gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING); + + GtkWidget *scrolled_win = gtk_scrolled_window_new(nullptr, nullptr); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0); + + /* Set the tree store to have 2 visible cols, two hidden. The hidden ones + * store pointer to the row's object and its Selection::Type. */ + solarTreeStore = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT); + solarTree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(solarTreeStore)); + + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(solarTree), TRUE); + gtk_container_add(GTK_CONTAINER(scrolled_win), solarTree); + + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + for (int i = 0; i < 2; i++) + { + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(ssTitles[i], renderer, "text", i, nullptr); + gtk_tree_view_append_column(GTK_TREE_VIEW(solarTree), column); + gtk_tree_view_column_set_min_width(column, 200); + } + + loadNearestStarSystem(app, solarTree, solarTreeStore); + + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(solarTree)); + g_signal_connect(selection, "changed", G_CALLBACK(treeSolarSelect), app); + + /* Common Buttons */ + GtkWidget *hbox = gtk_hbox_new(TRUE, CELSPACING); + if (buttonMake(hbox, "Center", (GCallback)actionCenterSelection, app)) + return; + if (buttonMake(hbox, "Go To", (GCallback)actionGotoSelection, app)) + return; + gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0); + + g_signal_connect(browser, "response", G_CALLBACK(gtk_widget_destroy), browser); + + gtk_widget_set_size_request(browser, -1, 400); /* Absolute Size, urghhh */ + gtk_widget_show_all(browser); +} + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-solar.h b/src/celestia/gtk/dialog-solar.h index db062c2bf6..8f797bab27 100644 --- a/src/celestia/gtk/dialog-solar.h +++ b/src/celestia/gtk/dialog-solar.h @@ -14,18 +14,12 @@ #include -#include - #include "common.h" +namespace celestia::gtk +{ /* Entry Function */ void dialogSolarBrowser(AppData* app); - -/* Local Data */ -static const char * const ssTitles[] = -{ - "Name", - "Type" -}; +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-star.cpp b/src/celestia/gtk/dialog-star.cpp index 4dcc4ee5f6..7342ec8ad3 100644 --- a/src/celestia/gtk/dialog-star.cpp +++ b/src/celestia/gtk/dialog-star.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -32,8 +33,8 @@ #include "actions.h" #include "common.h" -using namespace std; -namespace engine = celestia::engine; +namespace celestia::gtk +{ namespace { @@ -57,7 +58,8 @@ constexpr std::array sbRadioLabels }; /* Local Data Structures */ -struct sbData { +struct sbData +{ explicit sbData(AppData*); AppData* app; @@ -75,9 +77,9 @@ sbData::sbData(AppData* appData) : { } - /* HELPER: Clear and Add stars to the starListStore */ -static void addStars(sbData* sb) +void +addStars(sbData* sb) { const char *values[5]; GtkTreeIter iter; @@ -103,13 +105,13 @@ static void addStars(sbData* sb) values[0] = g_strdup(ReplaceGreekLetterAbbr((stardb->getStarName(*record.star, true))).c_str()); /* Calculate distance to star */ - sprintf(buf, " %.3f ", record.distance); + std::sprintf(buf, " %.3f ", record.distance); values[1] = g_strdup(buf); - sprintf(buf, " %.2f ", record.appMag); + std::sprintf(buf, " %.2f ", record.appMag); values[2] = g_strdup(buf); - sprintf(buf, " %.2f ", record.star->getAbsoluteMagnitude()); + std::sprintf(buf, " %.2f ", record.star->getAbsoluteMagnitude()); values[3] = g_strdup(buf); gtk_list_store_append(sb->starListStore, &iter); @@ -123,9 +125,9 @@ static void addStars(sbData* sb) } } - /* CALLBACK: When Star is selected in Star Browser */ -static void listStarSelect(GtkTreeSelection* sel, AppData* app) +void +listStarSelect(GtkTreeSelection* sel, AppData* app) { GValue value = { 0, {{0}} }; /* Initialize GValue to 0 */ GtkTreeIter iter; @@ -143,16 +145,16 @@ static void listStarSelect(GtkTreeSelection* sel, AppData* app) app->simulation->setSelection(Selection(const_cast(record->star))); } - /* CALLBACK: Refresh button is pressed. */ -static void refreshBrowser(GtkWidget*, sbData* sb) +void +refreshBrowser(GtkWidget*, sbData* sb) { addStars(sb); } - /* CALLBACK: One of the RadioButtons is pressed */ -static void radioClicked(GtkButton* r, gpointer choice) +void +radioClicked(GtkButton* r, gpointer choice) { sbData* sb = (sbData*)g_object_get_data(G_OBJECT(r), "data"); gint selection = GPOINTER_TO_INT(choice); @@ -179,16 +181,16 @@ static void radioClicked(GtkButton* r, gpointer choice) return; } - refreshBrowser(NULL, sb); + refreshBrowser(nullptr, sb); } - /* CALLBACK: Maximum stars EntryBox changed. */ -static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb) +void +listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb) { /* If not called by the slider, but rather by user. Prevents infinite recursion. */ - if (event != NULL) + if (event != nullptr) { std::string_view entryText = gtk_entry_get_text(entry); std::uint32_t numListStars; @@ -198,7 +200,7 @@ static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* s if (!sb->browser.setSize(numListStars)) { /* Call self to set text (NULL event = no recursion) */ - listStarEntryChange(entry, NULL, sb); + listStarEntryChange(entry, nullptr, sb); } gtk_range_set_value(GTK_RANGE(sb->scale), static_cast(numListStars)); @@ -206,31 +208,31 @@ static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* s else { /* Call self to set text (NULL event = no recursion) */ - listStarEntryChange(entry, NULL, sb); + listStarEntryChange(entry, nullptr, sb); } } /* Update value of this box */ char stars[4]; - sprintf(stars, "%" PRIu32, sb->browser.size()); + std::sprintf(stars, "%" PRIu32, sb->browser.size()); gtk_entry_set_text(entry, stars); } - /* CALLBACK: Maximum stars RangeSlider changed. */ -static void listStarSliderChange(GtkRange *range, sbData* sb) +void +listStarSliderChange(GtkRange *range, sbData* sb) { /* Update the value of the text entry box */ sb->browser.setSize(static_cast(gtk_range_get_value(GTK_RANGE(range)))); - listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb); + listStarEntryChange(GTK_ENTRY(sb->entry), nullptr, sb); /* Refresh the browser listbox */ - refreshBrowser(NULL, sb); + refreshBrowser(nullptr, sb); } - /* CALLBACK: Destroy Window */ -static void starDestroy(GtkWidget* w, gint responseId, sbData* sb) +void +starDestroy(GtkWidget* w, gint responseId, sbData* sb) { gtk_widget_destroy(GTK_WIDGET(w)); @@ -238,12 +240,11 @@ static void starDestroy(GtkWidget* w, gint responseId, sbData* sb) delete sb; } - } // end unnamed namespace - /* ENTRY: Navigation -> Star Browser... */ -void dialogStarBrowser(AppData* app) +void +dialogStarBrowser(AppData* app) { auto sb = new sbData(app); @@ -251,14 +252,14 @@ void dialogStarBrowser(AppData* app) GTK_WINDOW(app->mainWindow), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); + nullptr); app->simulation->setSelection(Selection()); /* Star System Browser */ GtkWidget *mainbox = gtk_dialog_get_content_area(GTK_DIALOG(browser)); gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING); - GtkWidget *scrolled_win = gtk_scrolled_window_new (NULL, NULL); + GtkWidget *scrolled_win = gtk_scrolled_window_new (nullptr, nullptr); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, @@ -284,11 +285,11 @@ void dialogStarBrowser(AppData* app) /* Add the columns */ for (int i=0; i<5; i++) { renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes (sbTitles[i], renderer, "text", i, NULL); + column = gtk_tree_view_column_new_with_attributes (sbTitles[i], renderer, "text", i, nullptr); if (i > 0 && i < 4) { /* Right align */ gtk_tree_view_column_set_alignment(column, 1.0); - g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); + g_object_set(G_OBJECT(renderer), "xalign", 1.0, nullptr); } gtk_tree_view_append_column(GTK_TREE_VIEW(starList), column); } @@ -327,13 +328,13 @@ void dialogStarBrowser(AppData* app) if (sb->browser.size() == engine::StarBrowser::MinListStars) { /* Force update manually (scale won't trigger event) */ - listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb); - refreshBrowser(NULL, sb); + listStarEntryChange(GTK_ENTRY(sb->entry), nullptr, sb); + refreshBrowser(nullptr, sb); } /* Radio Buttons */ vbox = gtk_vbox_new(TRUE, 0); - makeRadioItems(sbRadioLabels.data(), vbox, G_CALLBACK(radioClicked), NULL, sb); + makeRadioItems(sbRadioLabels.data(), vbox, G_CALLBACK(radioClicked), nullptr, sb); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); /* Common Buttons */ @@ -351,3 +352,5 @@ void dialogStarBrowser(AppData* app) gtk_widget_set_size_request(browser, -1, 400); /* Absolute Size, urghhh */ gtk_widget_show_all(browser); } + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-star.h b/src/celestia/gtk/dialog-star.h index 32c1f2f32c..e0f7429b73 100644 --- a/src/celestia/gtk/dialog-star.h +++ b/src/celestia/gtk/dialog-star.h @@ -16,5 +16,10 @@ #include "common.h" +namespace celestia::gtk +{ + /* Entry Function */ void dialogStarBrowser(AppData* app); + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-time.cpp b/src/celestia/gtk/dialog-time.cpp index 0d6a8020a1..2c7a3f58d5 100644 --- a/src/celestia/gtk/dialog-time.cpp +++ b/src/celestia/gtk/dialog-time.cpp @@ -10,8 +10,10 @@ * $Id: dialog-time.cpp,v 1.3 2005-12-13 03:54:40 suwalski Exp $ */ +#include +#include + #include -#include #include #include @@ -19,22 +21,107 @@ #include "dialog-time.h" #include "common.h" -namespace astro = celestia::astro; +namespace celestia::gtk +{ + +namespace +{ /* Labels for TimeZone dropdown */ -static const char* timeOptions[] = { "UTC", "Local", NULL }; +constexpr std::array timeOptions{ "UTC", "Local", static_cast(nullptr) }; + +/* CALLBACK: spinner value changed */ +gboolean +intAdjChanged(GtkAdjustment* adj, int *val) +{ + if (val) + { + *val = (int)gtk_adjustment_get_value(adj); + return TRUE; + } + return FALSE; +} + +/* CALLBACK: time zone selected from drop-down */ +gboolean +zoneChosen(GtkComboBox *menu, gboolean* timezone) +{ + *timezone = gtk_combo_box_get_active(menu) + 1; + return TRUE; +} + +/* CALLBACK: month selected from drop-down */ +gboolean +monthChosen(GtkComboBox *menu, int* month) +{ + if (month) + *month = gtk_combo_box_get_active(menu) + 1; + return TRUE; +} + +/* HELPER: creates one of the several drop-down boxes */ +void +chooseOption(GtkWidget *hbox, const char *str, char *choices[], int *val, GCallback chosen) +{ + GtkWidget *vbox = gtk_vbox_new(FALSE, 0); + GtkWidget *label = gtk_label_new(str); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + GtkWidget* combo = gtk_combo_box_text_new(); + + for(unsigned int i = 0; choices[i]; i++) + { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), choices[i]); + } + + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 7); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 2); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combo), (*val - 1)); + + g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(chosen), (gpointer)val); +} + +/* HELPER: creates spinner */ +void +intSpin(GtkWidget *hbox, const char *str, int min, int max, int *val, const char *sep) +{ + GtkWidget *vbox = gtk_vbox_new(FALSE, 0); + GtkWidget *label = gtk_label_new(str); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + GtkAdjustment *adj = (GtkAdjustment *) gtk_adjustment_new ((float)*val, (float) min, (float) max, + 1.0, 5.0, 0.0); + GtkWidget *spinner = gtk_spin_button_new (adj, 1.0, 0); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON (spinner), TRUE); + gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON (spinner),TRUE); + gtk_entry_set_max_length(GTK_ENTRY (spinner), ((max<99)?2:4) ); + + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); -/* Declarations: Callbacks */ -static gboolean intAdjChanged(GtkAdjustment* adj, int *val); -static gboolean zoneChosen(GtkComboBox *menu, int* timezone); -static gboolean monthChosen(GtkComboBox *menu, int* month); + if ((sep) && (*sep)) + { + gtk_widget_show (label); + GtkWidget *hbox2 = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(sep); + gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); + gtk_box_pack_start (GTK_BOX (hbox2), spinner, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 7); + gtk_widget_show (label); + gtk_widget_show (hbox2); + } + else + { + gtk_box_pack_start (GTK_BOX (vbox), spinner, TRUE, TRUE, 7); + } -/* Declarations: Helpers */ -static void chooseOption(GtkWidget *hbox, const char *str, char *choices[], - int *val, GCallback chosen); -static void intSpin(GtkWidget *hbox, const char *str, int min, int max, - int *val, const char *sep); + g_signal_connect(G_OBJECT(adj), "value-changed", + G_CALLBACK(intAdjChanged), val); +} +} // end unnamed namespace /* ENTRY: Dialog initializer */ void dialogSetTime(AppData* app) @@ -50,7 +137,7 @@ void dialogSetTime(AppData* app) GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL); + nullptr); if (app->showLocalTime) timezone = 2; @@ -77,7 +164,7 @@ void dialogSetTime(AppData* app) chooseOption(hbox, "Timezone", - (char **)timeOptions, + const_cast(timeOptions.data()), &timezone, G_CALLBACK(zoneChosen)); @@ -89,7 +176,7 @@ void dialogSetTime(AppData* app) chooseOption(hbox, "Month", - (char **)monthOptions, + const_cast(monthOptions.data()), &date.month, G_CALLBACK(monthChosen)); @@ -112,7 +199,7 @@ void dialogSetTime(AppData* app) if (button == GTK_RESPONSE_ACCEPT) /* Set current time and exit. */ - app->simulation->setTime((double)time(NULL) / 86400.0 + (double)astro::Date(1970, 1, 1)); + app->simulation->setTime((double)std::time(nullptr) / 86400.0 + (double)astro::Date(1970, 1, 1)); else if (button == GTK_RESPONSE_OK) /* Set entered time and exit */ app->simulation->setTime((double)date - ((timezone == 1) ? 0 : astro::secondsToJulianDate(tzOffsetAtDate(date)))); @@ -120,93 +207,4 @@ void dialogSetTime(AppData* app) gtk_widget_destroy(stimedialog); } - -/* CALLBACK: spinner value changed */ -static gboolean intAdjChanged(GtkAdjustment* adj, int *val) -{ - if (val) - { - *val = (int)gtk_adjustment_get_value(adj); - return TRUE; - } - return FALSE; -} - - -/* CALLBACK: time zone selected from drop-down */ -static gboolean zoneChosen(GtkComboBox *menu, gboolean* timezone) -{ - *timezone = gtk_combo_box_get_active(menu) + 1; - return TRUE; -} - - -/* CALLBACK: month selected from drop-down */ -static gboolean monthChosen(GtkComboBox *menu, int* month) -{ - if (month) - *month = gtk_combo_box_get_active(menu) + 1; - return TRUE; -} - - -/* HELPER: creates one of the several drop-down boxes */ -static void chooseOption(GtkWidget *hbox, const char *str, char *choices[], int *val, GCallback chosen) -{ - GtkWidget *vbox = gtk_vbox_new(FALSE, 0); - GtkWidget *label = gtk_label_new(str); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - GtkWidget* combo = gtk_combo_box_text_new(); - - for(unsigned int i = 0; choices[i]; i++) - { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), choices[i]); - } - - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 7); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 2); - - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), (*val - 1)); - - g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(chosen), (gpointer)val); -} - - -/* HELPER: creates spinner */ -static void intSpin(GtkWidget *hbox, const char *str, int min, int max, int *val, const char *sep) -{ - GtkWidget *vbox = gtk_vbox_new(FALSE, 0); - GtkWidget *label = gtk_label_new(str); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - GtkAdjustment *adj = (GtkAdjustment *) gtk_adjustment_new ((float)*val, (float) min, (float) max, - 1.0, 5.0, 0.0); - GtkWidget *spinner = gtk_spin_button_new (adj, 1.0, 0); - gtk_spin_button_set_numeric(GTK_SPIN_BUTTON (spinner), TRUE); - gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); - gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON (spinner),TRUE); - gtk_entry_set_max_length(GTK_ENTRY (spinner), ((max<99)?2:4) ); - - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); - - if ((sep) && (*sep)) - { - gtk_widget_show (label); - GtkWidget *hbox2 = gtk_hbox_new(FALSE, 3); - label = gtk_label_new(sep); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_box_pack_start (GTK_BOX (hbox2), spinner, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 7); - gtk_widget_show (label); - gtk_widget_show (hbox2); - } - else - { - gtk_box_pack_start (GTK_BOX (vbox), spinner, TRUE, TRUE, 7); - } - - g_signal_connect(G_OBJECT(adj), "value-changed", - G_CALLBACK(intAdjChanged), val); -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-time.h b/src/celestia/gtk/dialog-time.h index c05adb1051..488810b4c8 100644 --- a/src/celestia/gtk/dialog-time.h +++ b/src/celestia/gtk/dialog-time.h @@ -16,6 +16,10 @@ #include "common.h" +namespace celestia::gtk +{ /* Entry Function */ void dialogSetTime(AppData* app); + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-tour.cpp b/src/celestia/gtk/dialog-tour.cpp index 69ecfe4185..8cba6543f8 100644 --- a/src/celestia/gtk/dialog-tour.cpp +++ b/src/celestia/gtk/dialog-tour.cpp @@ -10,6 +10,8 @@ * $Id: dialog-tour.cpp,v 1.1 2005-12-06 03:19:35 suwalski Exp $ */ +#include + #include #include @@ -18,18 +20,88 @@ #include "dialog-tour.h" #include "common.h" -using namespace Eigen; +namespace celestia::gtk +{ + +namespace +{ + +/* Local Data Struct */ +typedef struct _TourData TourData; +struct _TourData { + AppData* app; + + Destination* selected; + GtkWidget* descLabel; +}; + +/* CALLBACK: tour list object selected */ +gint +TourGuideSelect(GtkComboBox* comboBox, TourData* td) +{ + int itemIndex = gtk_combo_box_get_active(comboBox); + + const DestinationList* destinations = td->app->core->getDestinations(); + if (destinations != nullptr && + itemIndex >= 0 && itemIndex < (int) destinations->size()) + { + td->selected = (*destinations)[itemIndex]; + } + + if (td->descLabel != nullptr && td->selected != nullptr) + { + gtk_label_set_text(GTK_LABEL(td->descLabel), td->selected->description.c_str()); + } + + return TRUE; +} + +/* CALLBACK: Goto button clicked */ +gint +TourGuideGoto(GtkWidget*, TourData* td) +{ + Simulation* simulation = td->app->simulation; + if (td->selected != nullptr && simulation != nullptr) + { + Selection sel = simulation->findObjectFromPath(td->selected->target); + if (!sel.empty()) + { + simulation->follow(); + simulation->setSelection(sel); + if (td->selected->distance <= 0) + { + /* Use the default distance */ + simulation->gotoSelection(5.0, + Eigen::Vector3f::UnitY(), + ObserverFrame::ObserverLocal); + } + else + { + simulation->gotoSelection(5.0, + td->selected->distance, + Eigen::Vector3f::UnitY(), + ObserverFrame::ObserverLocal); + } + } + } + return TRUE; +} -/* Declarations: Callbacks */ -static gint TourGuideSelect(GtkComboBox* comboBox, TourData* td); -static gint TourGuideGoto(GtkWidget*, TourData* td); -static void TourGuideDestroy(GtkWidget* w, gint, TourData* td); +/* CALLBACK: Destroy Window */ +void +TourGuideDestroy(GtkWidget* w, gint, TourData* td) +{ + gtk_widget_destroy(GTK_WIDGET(w)); + g_free(td); +} +} // end unnamed namespace /* ENTRY: Navigation->Tour Guide... */ -void dialogTourGuide(AppData* app) +void +dialogTourGuide(AppData* app) { TourData* td = g_new0(TourData, 1); td->app = app; @@ -39,7 +111,7 @@ void dialogTourGuide(AppData* app) GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); + nullptr); GtkWidget* hbox = gtk_hbox_new(FALSE, CELSPACING); gtk_container_set_border_width(GTK_CONTAINER(hbox), CELSPACING); @@ -66,13 +138,11 @@ void dialogTourGuide(AppData* app) const DestinationList* destinations = app->core->getDestinations(); int index = -1; - if (destinations != NULL) + if (destinations != nullptr) { - for (DestinationList::const_iterator iter = destinations->begin(); - iter != destinations->end(); iter++) + for (const Destination* dest : *destinations) { - Destination* dest = *iter; - if (dest != NULL) + if (dest != nullptr) { index = 0; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(comboBox), dest->name.c_str()); @@ -100,64 +170,4 @@ void dialogTourGuide(AppData* app) gtk_widget_show_all(dialog); } - -/* CALLBACK: tour list object selected */ -static gint TourGuideSelect(GtkComboBox* comboBox, TourData* td) -{ - int itemIndex = gtk_combo_box_get_active(comboBox); - - const DestinationList* destinations = td->app->core->getDestinations(); - if (destinations != NULL && - itemIndex >= 0 && itemIndex < (int) destinations->size()) - { - td->selected = (*destinations)[itemIndex]; - } - - if (td->descLabel != NULL && td->selected != NULL) - { - gtk_label_set_text(GTK_LABEL(td->descLabel), td->selected->description.c_str()); - } - - return TRUE; -} - - -/* CALLBACK: Goto button clicked */ -static gint TourGuideGoto(GtkWidget*, TourData* td) -{ - Simulation* simulation = td->app->simulation; - - if (td->selected != NULL && simulation != NULL) - { - Selection sel = simulation->findObjectFromPath(td->selected->target); - if (!sel.empty()) - { - simulation->follow(); - simulation->setSelection(sel); - if (td->selected->distance <= 0) - { - /* Use the default distance */ - simulation->gotoSelection(5.0, - Vector3f::UnitY(), - ObserverFrame::ObserverLocal); - } - else - { - simulation->gotoSelection(5.0, - td->selected->distance, - Vector3f::UnitY(), - ObserverFrame::ObserverLocal); - } - } - } - - return TRUE; -} - - -/* CALLBACK: Destroy Window */ -static void TourGuideDestroy(GtkWidget* w, gint, TourData* td) -{ - gtk_widget_destroy(GTK_WIDGET(w)); - g_free(td); -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/dialog-tour.h b/src/celestia/gtk/dialog-tour.h index 24b865c2d1..c5f1c0c256 100644 --- a/src/celestia/gtk/dialog-tour.h +++ b/src/celestia/gtk/dialog-tour.h @@ -16,16 +16,10 @@ #include "common.h" +namespace celestia::gtk +{ /* Entry Function */ void dialogTourGuide(AppData* app); - -/* Local Data Struct */ -typedef struct _TourData TourData; -struct _TourData { - AppData* app; - - Destination* selected; - GtkWidget* descLabel; -}; +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/glwidget.cpp b/src/celestia/gtk/glwidget.cpp index 02277af75d..23b45d45fc 100644 --- a/src/celestia/gtk/glwidget.cpp +++ b/src/celestia/gtk/glwidget.cpp @@ -24,68 +24,179 @@ #include "actions.h" #include "common.h" +namespace celestia::gtk +{ -/* Declarations: Callbacks */ -static gint glarea_idle(AppData* app); -static gint glarea_configure(GtkWidget* widget, GdkEventConfigure*, AppData* app); -#if GTK_MAJOR_VERSION == 2 -static gint glarea_expose(GtkWidget* widget, GdkEventExpose* event, AppData* app); +namespace +{ + +/* HELPER: GL Common Draw function. + * If everything checks out, call appCore->draw() */ +gint +glDrawFrame(AppData* app) +{ +#ifdef GTKGLEXT + GdkGLContext *glcontext = gtk_widget_get_gl_context(app->glArea); + GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(app->glArea); + + if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) + return FALSE; #else -static gint glarea_draw(GtkWidget*, cairo_t*, AppData* app); + if (!gtk_egl_drawable_make_current(app->glArea)) + return FALSE; #endif -static gint glarea_motion_notify(GtkWidget*, GdkEventMotion* event, AppData* app); -static gint glarea_mouse_scroll(GtkWidget*, GdkEventScroll* event, AppData* app); -static gint glarea_button_press(GtkWidget*, GdkEventButton* event, AppData* app); -static gint glarea_button_release(GtkWidget*, GdkEventButton* event, AppData* app); -static gint glarea_key_press(GtkWidget* widget, GdkEventKey* event, AppData* app); -static gint glarea_key_release(GtkWidget* widget, GdkEventKey* event, AppData* app); -/* Declarations: Helpers */ -static gint glDrawFrame(AppData* app); -static bool handleSpecialKey(int key, int state, bool down, AppData* app); + if (app->bReady) + { + app->core->draw(); +#ifdef GTKGLEXT + gdk_gl_drawable_swap_buffers(GDK_GL_DRAWABLE(gldrawable)); +#else + gtk_egl_drawable_swap_buffers(app->glArea); +#endif + } +#ifdef GTKGLEXT + gdk_gl_drawable_gl_end(gldrawable); +#endif + return TRUE; +} -/* ENTRY: Initialize/Bind all glArea Callbacks */ -void initGLCallbacks(AppData* app) +/* HELPER: Lookup function for keypress-action. Any key that is not part of + * the menu system must be listed here. */ +bool +handleSpecialKey(int key, int state, bool down, AppData* app) { -#if GTK_MAJOR_VERSION == 2 - g_signal_connect(G_OBJECT(app->glArea), "expose_event", - G_CALLBACK(glarea_expose), app); -#else - g_signal_connect(G_OBJECT(app->glArea), "draw", - G_CALLBACK(glarea_draw), app); -#endif - g_signal_connect(G_OBJECT(app->glArea), "configure_event", - G_CALLBACK(glarea_configure), app); - g_signal_connect(G_OBJECT(app->glArea), "button_press_event", - G_CALLBACK(glarea_button_press), app); - g_signal_connect(G_OBJECT(app->glArea), "button_release_event", - G_CALLBACK(glarea_button_release), app); - g_signal_connect(G_OBJECT(app->glArea), "scroll_event", - G_CALLBACK(glarea_mouse_scroll), app); - g_signal_connect(G_OBJECT(app->glArea), "motion_notify_event", - G_CALLBACK(glarea_motion_notify), app); - g_signal_connect(G_OBJECT(app->glArea), "key_press_event", - G_CALLBACK(glarea_key_press), app); - g_signal_connect(G_OBJECT(app->glArea), "key_release_event", - G_CALLBACK(glarea_key_release), app); + int k = -1; - /* Main call to execute redraw during GTK main loop */ - g_idle_add((GSourceFunc)glarea_idle, app); + switch (key) + { + case GDK_KEY_Up: + k = CelestiaCore::Key_Up; + break; + case GDK_KEY_Down: + k = CelestiaCore::Key_Down; + break; + case GDK_KEY_Left: + k = CelestiaCore::Key_Left; + break; + case GDK_KEY_Right: + k = CelestiaCore::Key_Right; + break; + case GDK_KEY_Home: + k = CelestiaCore::Key_Home; + break; + case GDK_KEY_End: + k = CelestiaCore::Key_End; + break; + case GDK_KEY_F1: + k = CelestiaCore::Key_F1; + break; + case GDK_KEY_F2: + k = CelestiaCore::Key_F2; + break; + case GDK_KEY_F3: + k = CelestiaCore::Key_F3; + break; + case GDK_KEY_F4: + k = CelestiaCore::Key_F4; + break; + case GDK_KEY_F5: + k = CelestiaCore::Key_F5; + break; + case GDK_KEY_F6: + k = CelestiaCore::Key_F6; + break; + case GDK_KEY_F7: + k = CelestiaCore::Key_F7; + break; + case GDK_KEY_F10: + if (down) + actionCaptureImage(nullptr, app); + break; + case GDK_KEY_F11: + k = CelestiaCore::Key_F11; + break; + case GDK_KEY_F12: + k = CelestiaCore::Key_F12; + break; + case GDK_KEY_KP_Insert: + case GDK_KEY_KP_0: + k = CelestiaCore::Key_NumPad0; + break; + case GDK_KEY_KP_End: + case GDK_KEY_KP_1: + k = CelestiaCore::Key_NumPad1; + break; + case GDK_KEY_KP_Down: + case GDK_KEY_KP_2: + k = CelestiaCore::Key_NumPad2; + break; + case GDK_KEY_KP_Next: + case GDK_KEY_KP_3: + k = CelestiaCore::Key_NumPad3; + break; + case GDK_KEY_KP_Left: + case GDK_KEY_KP_4: + k = CelestiaCore::Key_NumPad4; + break; + case GDK_KEY_KP_Begin: + case GDK_KEY_KP_5: + k = CelestiaCore::Key_NumPad5; + break; + case GDK_KEY_KP_Right: + case GDK_KEY_KP_6: + k = CelestiaCore::Key_NumPad6; + break; + case GDK_KEY_KP_Home: + case GDK_KEY_KP_7: + k = CelestiaCore::Key_NumPad7; + break; + case GDK_KEY_KP_Up: + case GDK_KEY_KP_8: + k = CelestiaCore::Key_NumPad8; + break; + case GDK_KEY_KP_Prior: + case GDK_KEY_KP_9: + k = CelestiaCore::Key_NumPad9; + break; + case GDK_KEY_A: + case GDK_KEY_a: + k = 'A'; + break; + case GDK_KEY_Z: + case GDK_KEY_z: + k = 'Z'; + break; + } + if (k >= 0) + { + if (down) + app->core->keyDown(k, (state & GDK_SHIFT_MASK) + ? CelestiaCore::ShiftKey + : 0); + else + app->core->keyUp(k); + return (k < 'A' || k > 'Z'); + } + else + { + return false; + } } - /* CALLBACK: GL Function for main update (in GTK idle loop) */ -static gint glarea_idle(AppData* app) +gint +glarea_idle(AppData* app) { app->core->tick(); return glDrawFrame(app); } - /* CALLBACK: GL Function for event "configure_event" */ -static gint glarea_configure(GtkWidget* widget, GdkEventConfigure*, AppData* app) +gint +glarea_configure(GtkWidget* widget, GdkEventConfigure*, AppData* app) { #ifdef GTKGLEXT GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); @@ -110,10 +221,10 @@ static gint glarea_configure(GtkWidget* widget, GdkEventConfigure*, AppData* app return TRUE; } - #if GTK_MAJOR_VERSION == 2 /* CALLBACK: GL Function for event "expose_event" */ -static gint glarea_expose(GtkWidget*, GdkEventExpose* event, AppData* app) +gint +glarea_expose(GtkWidget*, GdkEventExpose* event, AppData* app) { /* Draw only the last expose */ if (event->count > 0) @@ -124,15 +235,16 @@ static gint glarea_expose(GtkWidget*, GdkEventExpose* event, AppData* app) } #else /* CALLBACK: GL Function for event "draw" */ -static gint glarea_draw(GtkWidget*, cairo_t*, AppData* app) +gint +glarea_draw(GtkWidget*, cairo_t*, AppData* app) { return glDrawFrame(app); } #endif - /* CALLBACK: GL Function for event "motion_notify_event" */ -static gint glarea_motion_notify(GtkWidget*, GdkEventMotion* event, AppData* app) +gint +glarea_motion_notify(GtkWidget*, GdkEventMotion* event, AppData* app) { int x = (int) event->x; int y = (int) event->y; @@ -157,9 +269,9 @@ static gint glarea_motion_notify(GtkWidget*, GdkEventMotion* event, AppData* app return TRUE; } - /* CALLBACK: GL Function for event "scroll_event" */ -static gint glarea_mouse_scroll(GtkWidget*, GdkEventScroll* event, AppData* app) +gint +glarea_mouse_scroll(GtkWidget*, GdkEventScroll* event, AppData* app) { if (event->direction == GDK_SCROLL_UP) app->core->mouseWheel(-1.0f, 0); @@ -169,9 +281,9 @@ static gint glarea_mouse_scroll(GtkWidget*, GdkEventScroll* event, AppData* app) return TRUE; } - /* CALLBACK: GL Function for event "button_press_event" */ -static gint glarea_button_press(GtkWidget*, GdkEventButton* event, AppData* app) +gint +glarea_button_press(GtkWidget*, GdkEventButton* event, AppData* app) { app->lastX = (int) event->x; app->lastY = (int) event->y; @@ -186,9 +298,9 @@ static gint glarea_button_press(GtkWidget*, GdkEventButton* event, AppData* app) return TRUE; } - /* CALLBACK: GL Function for event "button_release_event" */ -static gint glarea_button_release(GtkWidget*, GdkEventButton* event, AppData* app) +gint +glarea_button_release(GtkWidget*, GdkEventButton* event, AppData* app) { app->lastX = (int) event->x; app->lastY = (int) event->y; @@ -203,9 +315,9 @@ static gint glarea_button_release(GtkWidget*, GdkEventButton* event, AppData* ap return TRUE; } - /* CALLBACK: GL Function for event "key_press_event" */ -static gint glarea_key_press(GtkWidget* widget, GdkEventKey* event, AppData* app) +gint +glarea_key_press(GtkWidget* widget, GdkEventKey* event, AppData* app) { switch (event->keyval) { @@ -234,7 +346,7 @@ static gint glarea_key_press(GtkWidget* widget, GdkEventKey* event, AppData* app default: if (!handleSpecialKey(event->keyval, event->state, true, app)) { - if ((event->string != NULL) && (*(event->string))) + if ((event->string != nullptr) && (*(event->string))) { /* See if our key accelerators will handle this event. */ if (app->core->getTextEnterMode() != celestia::Hud::TextEnterMode::Normal && @@ -259,164 +371,42 @@ static gint glarea_key_press(GtkWidget* widget, GdkEventKey* event, AppData* app return TRUE; } - /* CALLBACK: GL Function for event "key_release_event" */ -static gint glarea_key_release(GtkWidget* widget, GdkEventKey* event, AppData* app) +gint +glarea_key_release(GtkWidget* widget, GdkEventKey* event, AppData* app) { return handleSpecialKey(event->keyval, event->state, false, app); } +} // end unnamed namespace -/* HELPER: GL Common Draw function. - * If everything checks out, call appCore->draw() */ -static gint glDrawFrame(AppData* app) +/* ENTRY: Initialize/Bind all glArea Callbacks */ +void initGLCallbacks(AppData* app) { -#ifdef GTKGLEXT - GdkGLContext *glcontext = gtk_widget_get_gl_context(app->glArea); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(app->glArea); - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - return FALSE; -#else - if (!gtk_egl_drawable_make_current(app->glArea)) - return FALSE; -#endif - - if (app->bReady) - { - app->core->draw(); -#ifdef GTKGLEXT - gdk_gl_drawable_swap_buffers(GDK_GL_DRAWABLE(gldrawable)); +#if GTK_MAJOR_VERSION == 2 + g_signal_connect(G_OBJECT(app->glArea), "expose_event", + G_CALLBACK(glarea_expose), app); #else - gtk_egl_drawable_swap_buffers(app->glArea); + g_signal_connect(G_OBJECT(app->glArea), "draw", + G_CALLBACK(glarea_draw), app); #endif - } + g_signal_connect(G_OBJECT(app->glArea), "configure_event", + G_CALLBACK(glarea_configure), app); + g_signal_connect(G_OBJECT(app->glArea), "button_press_event", + G_CALLBACK(glarea_button_press), app); + g_signal_connect(G_OBJECT(app->glArea), "button_release_event", + G_CALLBACK(glarea_button_release), app); + g_signal_connect(G_OBJECT(app->glArea), "scroll_event", + G_CALLBACK(glarea_mouse_scroll), app); + g_signal_connect(G_OBJECT(app->glArea), "motion_notify_event", + G_CALLBACK(glarea_motion_notify), app); + g_signal_connect(G_OBJECT(app->glArea), "key_press_event", + G_CALLBACK(glarea_key_press), app); + g_signal_connect(G_OBJECT(app->glArea), "key_release_event", + G_CALLBACK(glarea_key_release), app); -#ifdef GTKGLEXT - gdk_gl_drawable_gl_end(gldrawable); -#endif - return TRUE; + /* Main call to execute redraw during GTK main loop */ + g_idle_add((GSourceFunc)glarea_idle, app); } - -/* HELPER: Lookup function for keypress-action. Any key that is not part of - * the menu system must be listed here. */ -static bool handleSpecialKey(int key, int state, bool down, AppData* app) -{ - int k = -1; - - switch (key) - { - case GDK_KEY_Up: - k = CelestiaCore::Key_Up; - break; - case GDK_KEY_Down: - k = CelestiaCore::Key_Down; - break; - case GDK_KEY_Left: - k = CelestiaCore::Key_Left; - break; - case GDK_KEY_Right: - k = CelestiaCore::Key_Right; - break; - case GDK_KEY_Home: - k = CelestiaCore::Key_Home; - break; - case GDK_KEY_End: - k = CelestiaCore::Key_End; - break; - case GDK_KEY_F1: - k = CelestiaCore::Key_F1; - break; - case GDK_KEY_F2: - k = CelestiaCore::Key_F2; - break; - case GDK_KEY_F3: - k = CelestiaCore::Key_F3; - break; - case GDK_KEY_F4: - k = CelestiaCore::Key_F4; - break; - case GDK_KEY_F5: - k = CelestiaCore::Key_F5; - break; - case GDK_KEY_F6: - k = CelestiaCore::Key_F6; - break; - case GDK_KEY_F7: - k = CelestiaCore::Key_F7; - break; - case GDK_KEY_F10: - if (down) actionCaptureImage(NULL, app); - break; - case GDK_KEY_F11: - k = CelestiaCore::Key_F11; - break; - case GDK_KEY_F12: - k = CelestiaCore::Key_F12; - break; - case GDK_KEY_KP_Insert: - case GDK_KEY_KP_0: - k = CelestiaCore::Key_NumPad0; - break; - case GDK_KEY_KP_End: - case GDK_KEY_KP_1: - k = CelestiaCore::Key_NumPad1; - break; - case GDK_KEY_KP_Down: - case GDK_KEY_KP_2: - k = CelestiaCore::Key_NumPad2; - break; - case GDK_KEY_KP_Next: - case GDK_KEY_KP_3: - k = CelestiaCore::Key_NumPad3; - break; - case GDK_KEY_KP_Left: - case GDK_KEY_KP_4: - k = CelestiaCore::Key_NumPad4; - break; - case GDK_KEY_KP_Begin: - case GDK_KEY_KP_5: - k = CelestiaCore::Key_NumPad5; - break; - case GDK_KEY_KP_Right: - case GDK_KEY_KP_6: - k = CelestiaCore::Key_NumPad6; - break; - case GDK_KEY_KP_Home: - case GDK_KEY_KP_7: - k = CelestiaCore::Key_NumPad7; - break; - case GDK_KEY_KP_Up: - case GDK_KEY_KP_8: - k = CelestiaCore::Key_NumPad8; - break; - case GDK_KEY_KP_Prior: - case GDK_KEY_KP_9: - k = CelestiaCore::Key_NumPad9; - break; - case GDK_KEY_A: - case GDK_KEY_a: - k = 'A'; - break; - case GDK_KEY_Z: - case GDK_KEY_z: - k = 'Z'; - break; - } - - if (k >= 0) - { - if (down) - app->core->keyDown(k, (state & GDK_SHIFT_MASK) - ? CelestiaCore::ShiftKey - : 0); - else - app->core->keyUp(k); - return (k < 'A' || k > 'Z'); - } - else - { - return false; - } -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/glwidget.h b/src/celestia/gtk/glwidget.h index 77d078a040..a7dbf1626b 100644 --- a/src/celestia/gtk/glwidget.h +++ b/src/celestia/gtk/glwidget.h @@ -17,6 +17,10 @@ #include "common.h" +namespace celestia::gtk +{ /* Initialization Functions */ void initGLCallbacks(AppData* app); + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/main.cpp b/src/celestia/gtk/main.cpp index 1346ffceef..4f09457678 100644 --- a/src/celestia/gtk/main.cpp +++ b/src/celestia/gtk/main.cpp @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -38,13 +39,6 @@ #include #include -/* Includes for the GNOME front-end */ -#ifdef GNOME -#include -#include -#include -#endif /* GNOME */ - /* Includes for the GTK front-end */ #include "common.h" #include "glwidget.h" @@ -53,47 +47,43 @@ #include "ui.h" /* Includes for the settings interface */ -#ifdef GNOME -#include "settings-gconf.h" -#else #include "settings-file.h" -#endif /* GNOME */ #ifndef DEBUG #define G_DISABLE_ASSERT #endif /* DEBUG */ +namespace celestia::gtk +{ -using namespace celestia; -using namespace std; - +namespace +{ /* Function Definitions */ -static void createMainMenu(GtkWidget* window, AppData* app); -static void initRealize(GtkWidget* widget, AppData* app); - +void createMainMenu(GtkWidget* window, AppData* app); +void initRealize(GtkWidget* widget, AppData* app); /* Command-Line Options */ -static gchar* configFile = NULL; -static gchar* installDir = NULL; -static gchar** extrasDir = NULL; -static gboolean fullScreen = FALSE; -static gboolean noSplash = FALSE; +gchar* configFile = nullptr; +gchar* installDir = nullptr; +gchar** extrasDir = nullptr; +gboolean fullScreen = FALSE; +gboolean noSplash = FALSE; /* Command-Line Options specification */ -static GOptionEntry optionEntries[] = +constexpr std::array optionEntries { - { "conf", 'c', 0, G_OPTION_ARG_FILENAME, &configFile, "Alternate configuration file", "file" }, - { "dir", 'd', 0, G_OPTION_ARG_FILENAME, &installDir, "Alternate installation directory", "directory" }, - { "extrasdir", 'e', 0, G_OPTION_ARG_FILENAME_ARRAY, &extrasDir, "Additional \"extras\" directory", "directory" }, - { "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullScreen, "Start full-screen", NULL }, - { "nosplash", 's', 0, G_OPTION_ARG_NONE, &noSplash, "Disable splash screen", NULL }, - { NULL, '\0', 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } + GOptionEntry{ "conf", 'c', 0, G_OPTION_ARG_FILENAME, &configFile, "Alternate configuration file", "file" }, + GOptionEntry{ "dir", 'd', 0, G_OPTION_ARG_FILENAME, &installDir, "Alternate installation directory", "directory" }, + GOptionEntry{ "extrasdir", 'e', 0, G_OPTION_ARG_FILENAME_ARRAY, &extrasDir, "Additional \"extras\" directory", "directory" }, + GOptionEntry{ "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullScreen, "Start full-screen", nullptr }, + GOptionEntry{ "nosplash", 's', 0, G_OPTION_ARG_NONE, &noSplash, "Disable splash screen", nullptr }, + GOptionEntry{ nullptr, '\0', 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr } }; - /* Initializes GtkActions and creates main menu */ -static void createMainMenu(GtkWidget* window, AppData* app) +void +createMainMenu(GtkWidget* window, AppData* app) { GtkUIManager *ui_manager; GtkAccelGroup *accel_group; @@ -108,14 +98,14 @@ static void createMainMenu(GtkWidget* window, AppData* app) app->agAmbient = gtk_action_group_new("AmbientActions"); /* All actions have the AppData structure passed */ - gtk_action_group_add_actions(app->agMain, actionsPlain, G_N_ELEMENTS(actionsPlain), app); - gtk_action_group_add_toggle_actions(app->agMain, actionsToggle, G_N_ELEMENTS(actionsToggle), app); - gtk_action_group_add_radio_actions(app->agVerbosity, actionsVerbosity, G_N_ELEMENTS(actionsVerbosity), 0, G_CALLBACK(actionVerbosity), app); - gtk_action_group_add_radio_actions(app->agStarStyle, actionsStarStyle, G_N_ELEMENTS(actionsStarStyle), 0, G_CALLBACK(actionStarStyle), app); - gtk_action_group_add_radio_actions(app->agAmbient, actionsAmbientLight, G_N_ELEMENTS(actionsAmbientLight), 0, G_CALLBACK(actionAmbientLight), app); - gtk_action_group_add_toggle_actions(app->agRender, actionsRenderFlags, G_N_ELEMENTS(actionsRenderFlags), app); - gtk_action_group_add_toggle_actions(app->agLabel, actionsLabelFlags, G_N_ELEMENTS(actionsLabelFlags), app); - gtk_action_group_add_toggle_actions(app->agOrbit, actionsOrbitFlags, G_N_ELEMENTS(actionsOrbitFlags), app); + gtk_action_group_add_actions(app->agMain, actionsPlain.data(), static_cast(actionsPlain.size()), app); + gtk_action_group_add_toggle_actions(app->agMain, actionsToggle.data(), static_cast(actionsToggle.size()), app); + gtk_action_group_add_radio_actions(app->agVerbosity, actionsVerbosity.data(), static_cast(actionsVerbosity.size()), 0, G_CALLBACK(actionVerbosity), app); + gtk_action_group_add_radio_actions(app->agStarStyle, actionsStarStyle.data(), static_cast(actionsStarStyle.size()), 0, G_CALLBACK(actionStarStyle), app); + gtk_action_group_add_radio_actions(app->agAmbient, actionsAmbientLight.data(), static_cast(actionsAmbientLight.size()), 0, G_CALLBACK(actionAmbientLight), app); + gtk_action_group_add_toggle_actions(app->agRender, actionsRenderFlags.data(), static_cast(actionsRenderFlags.size()), app); + gtk_action_group_add_toggle_actions(app->agLabel, actionsLabelFlags.data(), static_cast(actionsLabelFlags.size()), app); + gtk_action_group_add_toggle_actions(app->agOrbit, actionsOrbitFlags.data(), static_cast(actionsOrbitFlags.size()), app); ui_manager = gtk_ui_manager_new(); gtk_ui_manager_insert_action_group(ui_manager, app->agMain, 0); @@ -129,7 +119,7 @@ static void createMainMenu(GtkWidget* window, AppData* app) accel_group = gtk_ui_manager_get_accel_group(ui_manager); gtk_window_add_accel_group(GTK_WINDOW (window), accel_group); - error = NULL; + error = nullptr; if (!gtk_ui_manager_add_ui_from_file(ui_manager, "celestiaui.xml", &error)) { g_message("Building menus failed: %s", error->message); @@ -140,7 +130,6 @@ static void createMainMenu(GtkWidget* window, AppData* app) app->mainMenu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu"); } - /* Our own watcher. Celestiacore will call notifyChange() to tell us * we need to recheck the check menu items and option buttons. */ @@ -158,7 +147,8 @@ GtkWatcher::GtkWatcher(CelestiaCore* _appCore, AppData* _app) : { } -void GtkWatcher::notifyChange(CelestiaCore*, int property) +void +GtkWatcher::notifyChange(CelestiaCore*, int property) { if (property & CelestiaCore::LabelFlagsChanged) resyncLabelActions(app); @@ -242,10 +232,10 @@ class GtkAlerter : public CelestiaCore::Alerter } }; - /* CALLBACK: Event "realize" on the main GL area. Things that go here are those * that require the glArea to be set up. */ -static void initRealize(GtkWidget* widget, AppData* app) +void +initRealize(GtkWidget* widget, AppData* app) { #ifdef GL_ES constexpr int reqVersion = gl::GLES_2; @@ -271,15 +261,11 @@ static void initRealize(GtkWidget* widget, AppData* app) if (!app->core->initRenderer()) { - cerr << "Failed to initialize renderer.\n"; + std::cerr << "Failed to initialize renderer.\n"; } /* Read/Apply Settings */ - #ifdef GNOME - applySettingsGConfMain(app, app->client); - #else applySettingsFileMain(app, app->settingsFile); - #endif /* GNOME */ /* Synchronize all actions with core settings */ resyncLabelActions(app); @@ -294,7 +280,7 @@ static void initRealize(GtkWidget* widget, AppData* app) gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_action_group_get_action(app->agMain, "FullScreen")), TRUE); /* If URL at startup, make it so. */ - if (app->startURL != NULL) + if (app->startURL != nullptr) app->core->setStartURL(app->startURL); /* Set simulation time */ @@ -309,10 +295,15 @@ static void initRealize(GtkWidget* widget, AppData* app) gdk_window_set_cursor(gtk_widget_get_window(widget), gdk_cursor_new(GDK_CROSSHAIR)); } +} // end unnamed namespace + +} // end namespace celestia::gtk /* MAIN */ int main(int argc, char* argv[]) { + using namespace celestia::gtk; + setlocale(LC_ALL, ""); /* Force number displays into C locale. */ setlocale(LC_NUMERIC, "C"); @@ -336,16 +327,16 @@ int main(int argc, char* argv[]) app->lastY = 0; app->showLocalTime = FALSE; app->fullScreen = FALSE; - app->startURL = NULL; + app->startURL = nullptr; /* Command line option parsing */ - GError *error = NULL; + GError *error = nullptr; GOptionContext* context = g_option_context_new(""); - g_option_context_add_main_entries(context, optionEntries, NULL); + g_option_context_add_main_entries(context, optionEntries.data(), nullptr); g_option_context_add_group(context, gtk_get_option_group(TRUE)); g_option_context_parse(context, &argc, &argv, &error); - if (error != NULL) + if (error != nullptr) { g_print("Error in command line options. Use --help for full list.\n"); exit(1); @@ -360,25 +351,18 @@ int main(int argc, char* argv[]) if (argc > 1) app->startURL = argv[argc - 1]; - #ifdef GNOME - /* GNOME Initialization */ - GnomeProgram *program; - program = gnome_program_init("Celestia", VERSION, LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); - #else /* GTK-Only Initialization */ gtk_init(&argc, &argv); - #endif /* Turn on the splash screen */ SplashData* ss = splashStart(app, !noSplash, installDir, CONFIG_DATA_DIR); splashSetText(ss, "Initializing..."); - if (installDir == NULL) + if (installDir == nullptr) installDir = (gchar*)CONFIG_DATA_DIR; if (chdir(installDir) == -1) - cerr << "Cannot chdir to '" << installDir << "', probably due to improper installation.\n"; + std::cerr << "Cannot chdir to '" << installDir << "', probably due to improper installation.\n"; app->core = new CelestiaCore(); @@ -386,16 +370,16 @@ int main(int argc, char* argv[]) g_assert(app->renderer); /* Parse simulation arguments */ - string altConfig; - if (configFile != NULL) - altConfig = string(configFile); + std::string altConfig; + if (configFile != nullptr) + altConfig = std::string(configFile); - vector configDirs; - if (extrasDir != NULL) + std::vector configDirs; + if (extrasDir != nullptr) { /* Add each extrasDir to the vector */ int i = 0; - while (extrasDir[i] != NULL) + while (extrasDir[i] != nullptr) { configDirs.push_back(extrasDir[i]); i++; @@ -412,14 +396,9 @@ int main(int argc, char* argv[]) app->renderer->setSolarSystemMaxDistance(app->core->getConfig()->renderDetails.SolarSystemMaxDistance); app->renderer->setShadowMapSize(app->core->getConfig()->renderDetails.ShadowMapSize); - #ifdef GNOME - /* Create the main window (GNOME) */ - app->mainWindow = gnome_app_new("Celestia", "Celestia"); - #else /* Create the main window (GTK) */ app->mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(app->mainWindow), "Celestia"); - #endif /* GNOME */ /* Set pointer to AppData structure. This is for when a function is in a * *real* bind to get at this structure. */ @@ -439,7 +418,7 @@ int main(int argc, char* argv[]) GdkGLConfig* glconfig = gdk_gl_config_new_by_mode(static_cast (GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); - if (glconfig == NULL) + if (glconfig == nullptr) { g_print("*** Cannot find the double-buffered visual.\n"); g_print("*** Trying single-buffered visual.\n"); @@ -447,7 +426,7 @@ int main(int argc, char* argv[]) /* Try single-buffered visual */ glconfig = gdk_gl_config_new_by_mode(static_cast (GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH)); - if (glconfig == NULL) + if (glconfig == nullptr) { g_print ("*** No appropriate OpenGL-capable visual found.\n"); exit(1); @@ -456,11 +435,7 @@ int main(int argc, char* argv[]) #endif /* Initialize settings system */ - #ifdef GNOME - initSettingsGConf(app); - #else initSettingsFile(app); - #endif /* GNOME */ /* Create area to be used for OpenGL display */ app->glArea = gtk_drawing_area_new(); @@ -469,7 +444,7 @@ int main(int argc, char* argv[]) #ifdef GTKGLEXT gtk_widget_set_gl_capability(app->glArea, glconfig, - NULL, + nullptr, TRUE, GDK_GL_RGBA_TYPE); #else @@ -494,11 +469,7 @@ int main(int argc, char* argv[]) GDK_POINTER_MOTION_MASK); /* Load settings the can be applied before the simulation is initialized */ - #ifdef GNOME - applySettingsGConfPre(app, app->client); - #else applySettingsFilePre(app, app->settingsFile); - #endif /* GNOME */ /* Full-Screen option from the command line (overrides above). */ if (fullScreen) @@ -520,18 +491,13 @@ int main(int argc, char* argv[]) /* Set context menu handler for the core */ app->core->setContextMenuHandler(handler); - #ifdef GNOME - /* Set window contents (GNOME) */ - gnome_app_set_contents((GnomeApp *)app->mainWindow, GTK_WIDGET(mainBox)); - #else /* Set window contents (GTK) */ gtk_container_add(GTK_CONTAINER(app->mainWindow), GTK_WIDGET(mainBox)); - #endif /* GNOME */ gtk_box_pack_start(GTK_BOX(mainBox), app->mainMenu, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(mainBox), app->glArea, TRUE, TRUE, 0); - gtk_window_set_default_icon_from_file("celestia-logo.png", NULL); + gtk_window_set_default_icon_from_file("celestia-logo.png", nullptr); /* Set focus to glArea widget */ gtk_widget_set_can_focus(GTK_WIDGET(app->glArea), true); @@ -548,10 +514,6 @@ int main(int argc, char* argv[]) /* HACK: Now that window is drawn, set minimum window size */ gtk_widget_set_size_request(app->glArea, 320, 240); - #ifdef GNOME - initSettingsGConfNotifiers(app); - #endif /* GNOME */ - /* Set the ready flag */ app->bReady = TRUE; @@ -565,12 +527,12 @@ int main(int argc, char* argv[]) return 0; } - #ifdef WIN32 -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) +int APIENTRY +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) { return main(__argc, __argv); } diff --git a/src/celestia/gtk/menu-context.cpp b/src/celestia/gtk/menu-context.cpp index dc76089eda..a80e4f59dc 100644 --- a/src/celestia/gtk/menu-context.cpp +++ b/src/celestia/gtk/menu-context.cpp @@ -12,6 +12,9 @@ #include #include +#include +#include +#include #include @@ -24,142 +27,30 @@ #include "actions.h" #include "common.h" -using namespace std; - -/* Definitions: Callbacks */ -static void wrapAction(GtkAction* action); -static void menuMark(); -static void menuUnMark(); -static void handleContextPrimary(); -static void handleContextPlanet(gpointer data); -static void handleContextSurface(gpointer data); - -/* Definitions: Helpers */ -static GtkMenuItem* AppendMenu(GtkWidget* parent, GCallback callback, const gchar* name, gpointer extra); -static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySystem* psys); -template -static GtkMenu* CreateAlternateSurfaceMenu(const T& surfaces); - - -/* There is no way to pass the AppData struct to the menu at this time. This - * keeps the global variable local to this file, at least conceptually. */ -static AppData* app; - - -/* Initializer. Sets the appData */ -GTKContextMenuHandler::GTKContextMenuHandler(AppData* _app) : - CelestiaCore::ContextMenuHandler() +namespace celestia::gtk { - // FIXME: a workaround to have it referenced by any menu callback - app = _app; -} - -/* ENTRY: Context menu (event handled by appCore) - * Normally, float x and y, but unused, so removed. */ -void GTKContextMenuHandler::requestContextMenu(float, float, Selection sel) +namespace { - GtkWidget* popup = gtk_menu_new(); - string name; - - switch (sel.getType()) - { - case SelectionType::Body: - { - name = sel.body()->getName(); - AppendMenu(popup, NULL, name.c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); - AppendMenu(popup, NULL, NULL, 0); - AppendMenu(popup, NULL, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); - AppendMenu(popup, NULL, "_Follow", gtk_action_group_get_action(app->agMain, "FollowSelection")); - AppendMenu(popup, NULL, "S_ync Orbit", gtk_action_group_get_action(app->agMain, "SyncSelection")); - /* Add info eventually: - * AppendMenu(popup, NULL, "_Info", 0); */ - if (Helper::hasPrimary(sel.body())) - { - AppendMenu(popup, G_CALLBACK(handleContextPrimary), "Select _Primary Body", NULL); - } - - if (const PlanetarySystem* satellites = sel.body()->getSatellites(); - satellites != nullptr && satellites->getSystemSize() != 0) - { - GtkMenu* satMenu = CreatePlanetarySystemMenu(name, satellites); - gtk_menu_item_set_submenu(AppendMenu(popup, NULL, "_Satellites", 0), GTK_WIDGET(satMenu)); - } - - if (auto altSurfaces = sel.body()->getAlternateSurfaceNames(); - altSurfaces.has_value() && !altSurfaces->empty()) - { - GtkMenu* surfMenu = CreateAlternateSurfaceMenu(*altSurfaces); - gtk_menu_item_set_submenu(AppendMenu(popup, NULL, "_Alternate Surfaces", 0), GTK_WIDGET(surfMenu)); - } - } - break; - - case SelectionType::Star: - { - Simulation* sim = app->simulation; - name = ReplaceGreekLetterAbbr(sim->getUniverse()->getStarCatalog()->getStarName(*(sel.star()))); - AppendMenu(popup, NULL, name.c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); - AppendMenu(popup, NULL, NULL, 0); - AppendMenu(popup, NULL, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); - /* Add info eventually: - * AppendMenu(popup, NULL, "_Info", 0); */ - - const SolarSystem* solarSys = sim->getUniverse()->getSolarSystem(sel.star()); - if (solarSys != nullptr) - { - GtkMenu* planetsMenu = CreatePlanetarySystemMenu(name, solarSys->getPlanets()); - if (name == "Sol") - gtk_menu_item_set_submenu(AppendMenu(popup, NULL, "Orbiting Bodies", 0), GTK_WIDGET(planetsMenu)); - else - gtk_menu_item_set_submenu(AppendMenu(popup, NULL, "Planets", 0), GTK_WIDGET(planetsMenu)); - } - } - break; - - case SelectionType::DeepSky: - { - AppendMenu(popup, NULL, app->simulation->getUniverse()->getDSOCatalog()->getDSOName(sel.deepsky()).c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); - AppendMenu(popup, NULL, NULL, 0); - AppendMenu(popup, NULL, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); - AppendMenu(popup, NULL, "_Follow", gtk_action_group_get_action(app->agMain, "FollowSelection")); - /* Add info eventually: - * AppendMenu(popup, NULL, "_Info", 0); */ - } - break; - - case SelectionType::Location: - break; - - default: - break; - } - - if (app->simulation->getUniverse()->isMarked(sel, 1)) - AppendMenu(popup, menuUnMark, "_Unmark", 0); - else - AppendMenu(popup, menuMark, "_Mark", 0); - - app->simulation->setSelection(sel); - - gtk_widget_show_all(popup); - gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); -} +/* There is no way to pass the AppData struct to the menu at this time. This + * keeps the global variable local to this file, at least conceptually. */ +AppData* app; /* CALLBACK: Wrap a GtkAction. The whole context menu should be replaced at * some point */ -static void wrapAction(GtkAction* action) +void +wrapAction(GtkAction* action) { gtk_action_activate(action); } - /* CALLBACK: Mark the selected object. Might some day be a GtkAction. */ -static void menuMark() +void +menuMark() { Simulation* sim = app->simulation; - if (sim->getUniverse() != NULL) + if (sim->getUniverse() != nullptr) { using namespace celestia; MarkerRepresentation markerRep(MarkerRepresentation::Diamond, 10.0f, Color(0.0f, 1.0f, 0.0f, 0.9f)); @@ -167,18 +58,18 @@ static void menuMark() } } - /* CALLBACK: Unmark the selected object. Might some day be a GtkAction. */ -static void menuUnMark() +void +menuUnMark() { Simulation* sim = app->simulation; - if (sim->getUniverse() != NULL) + if (sim->getUniverse() != nullptr) sim->getUniverse()->unmarkObject(sim->getSelection(), 1); } - /* CALLBACK: Handle a planetary selection from the context menu. */ -static void handleContextPlanet(gpointer data) +void +handleContextPlanet(gpointer data) { int value = GPOINTER_TO_INT(data); @@ -210,20 +101,20 @@ static void handleContextPlanet(gpointer data) } } - /* CALLBACK: Handle an object's primary selection */ -static void handleContextPrimary() +void +handleContextPrimary() { Selection sel = app->simulation->getSelection(); - if (sel.body() != NULL) + if (sel.body() != nullptr) { app->simulation->setSelection(Helper::getPrimary(sel.body())); } } - /* CALLBACK: Handle an alternate surface from the context menu. */ -static void handleContextSurface(gpointer data) +void +handleContextSurface(gpointer data) { int value = GPOINTER_TO_INT(data); @@ -250,21 +141,21 @@ static void handleContextSurface(gpointer data) } } - /* HELPER: Append a menu item and return pointer. Used for context menu. */ -static GtkMenuItem* AppendMenu(GtkWidget* parent, GCallback callback, const gchar* name, gpointer extra) +GtkMenuItem* +AppendMenu(GtkWidget* parent, GCallback callback, const gchar* name, gpointer extra) { GtkWidget* menuitem; gpointer data; /* Check for separator */ - if (name == NULL) + if (name == nullptr) menuitem = gtk_separator_menu_item_new(); else menuitem = gtk_menu_item_new_with_mnemonic(name); /* If no callback was provided, pass GtkAction, else convert to pointer */ - if (callback == NULL && extra != 0) + if (callback == nullptr && extra != 0) { callback = G_CALLBACK(wrapAction); data = extra; @@ -273,7 +164,7 @@ static GtkMenuItem* AppendMenu(GtkWidget* parent, GCallback callback, const gcha data = GINT_TO_POINTER(extra); /* Add handler */ - if (callback != NULL) + if (callback != nullptr) g_signal_connect_swapped (G_OBJECT(menuitem), "activate", G_CALLBACK(callback), data); @@ -282,16 +173,15 @@ static GtkMenuItem* AppendMenu(GtkWidget* parent, GCallback callback, const gcha return GTK_MENU_ITEM(menuitem); } - /* Typedefs and structs for sorting objects by name in context menu. */ -typedef pair IntStrPair; -typedef vector IntStrPairVec; +using IntStrPair = std::pair; +using IntStrPairVec = std::vector; struct IntStrPairComparePredicate { IntStrPairComparePredicate() : dummy(0) {} - bool operator()(const IntStrPair pair1, const IntStrPair pair2) const + bool operator()(const IntStrPair& pair1, const IntStrPair& pair2) const { return (pair1.second.compare(pair2.second) < 0); } @@ -300,7 +190,8 @@ struct IntStrPairComparePredicate }; /* HELPER: Create planetary submenu for context menu, return menu pointer. */ -static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySystem* psys) +GtkMenu* +CreatePlanetarySystemMenu(const std::string& parentName, const PlanetarySystem* psys) { /* * Modified from winmain.cpp @@ -313,18 +204,18 @@ static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySyst */ /* Declare vector> objects for each classification of body */ - vector asteroids; - vector comets; - vector invisibles; - vector moons; - vector minorMoons; - vector planets; - vector dwarfPlanets; - vector spacecraft; + std::vector asteroids; + std::vector comets; + std::vector invisibles; + std::vector moons; + std::vector minorMoons; + std::vector planets; + std::vector dwarfPlanets; + std::vector spacecraft; /* We will use these objects to iterate over all the above vectors */ - vector objects; - vector menuNames; + std::vector objects; + std::vector menuNames; /* Place each body in the correct vector based on classification */ GtkWidget* menu = gtk_menu_new(); @@ -380,9 +271,9 @@ static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySyst /* Now sort each vector and generate submenus */ IntStrPairComparePredicate pred; - vector::iterator obj; - vector::iterator it; - vector::iterator menuName; + std::vector::iterator obj; + std::vector::iterator it; + std::vector::iterator menuName; GtkWidget* subMenu; int numSubMenus; @@ -421,7 +312,7 @@ static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySyst for(it=obj->begin(); it != obj->end(); it++) AppendMenu(subMenu, G_CALLBACK(handleContextPlanet), it->second.c_str(), GINT_TO_POINTER(it->first)); - gtk_menu_item_set_submenu(AppendMenu(menu, NULL, menuName->c_str(), 0), GTK_WIDGET(subMenu)); + gtk_menu_item_set_submenu(AppendMenu(menu, nullptr, menuName->c_str(), 0), GTK_WIDGET(subMenu)); } else { @@ -437,10 +328,10 @@ static GtkMenu* CreatePlanetarySystemMenu(string parentName, const PlanetarySyst return GTK_MENU(menu); } - /* HELPER: Create surface submenu for context menu, return menu pointer. */ template -static GtkMenu* CreateAlternateSurfaceMenu(const T& surfaces) +GtkMenu* +CreateAlternateSurfaceMenu(const T& surfaces) { GtkWidget* menu = gtk_menu_new(); @@ -454,3 +345,106 @@ static GtkMenu* CreateAlternateSurfaceMenu(const T& surfaces) return GTK_MENU(menu); } + +} // end unnamed namespace + +/* Initializer. Sets the appData */ +GTKContextMenuHandler::GTKContextMenuHandler(AppData* _app) : + CelestiaCore::ContextMenuHandler() +{ + // FIXME: a workaround to have it referenced by any menu callback + app = _app; +} + +/* ENTRY: Context menu (event handled by appCore) + * Normally, float x and y, but unused, so removed. */ +void GTKContextMenuHandler::requestContextMenu(float, float, Selection sel) +{ + GtkWidget* popup = gtk_menu_new(); + std::string name; + + switch (sel.getType()) + { + case SelectionType::Body: + { + name = sel.body()->getName(); + AppendMenu(popup, nullptr, name.c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); + AppendMenu(popup, nullptr, nullptr, 0); + AppendMenu(popup, nullptr, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); + AppendMenu(popup, nullptr, "_Follow", gtk_action_group_get_action(app->agMain, "FollowSelection")); + AppendMenu(popup, nullptr, "S_ync Orbit", gtk_action_group_get_action(app->agMain, "SyncSelection")); + /* Add info eventually: + * AppendMenu(popup, nullptr, "_Info", 0); */ + if (Helper::hasPrimary(sel.body())) + { + AppendMenu(popup, G_CALLBACK(handleContextPrimary), "Select _Primary Body", nullptr); + } + + if (const PlanetarySystem* satellites = sel.body()->getSatellites(); + satellites != nullptr && satellites->getSystemSize() != 0) + { + GtkMenu* satMenu = CreatePlanetarySystemMenu(name, satellites); + gtk_menu_item_set_submenu(AppendMenu(popup, nullptr, "_Satellites", 0), GTK_WIDGET(satMenu)); + } + + if (auto altSurfaces = sel.body()->getAlternateSurfaceNames(); + altSurfaces.has_value() && !altSurfaces->empty()) + { + GtkMenu* surfMenu = CreateAlternateSurfaceMenu(*altSurfaces); + gtk_menu_item_set_submenu(AppendMenu(popup, nullptr, "_Alternate Surfaces", 0), GTK_WIDGET(surfMenu)); + } + } + break; + + case SelectionType::Star: + { + Simulation* sim = app->simulation; + name = ReplaceGreekLetterAbbr(sim->getUniverse()->getStarCatalog()->getStarName(*(sel.star()))); + AppendMenu(popup, nullptr, name.c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); + AppendMenu(popup, nullptr, nullptr, 0); + AppendMenu(popup, nullptr, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); + /* Add info eventually: + * AppendMenu(popup, nullptr, "_Info", 0); */ + + const SolarSystem* solarSys = sim->getUniverse()->getSolarSystem(sel.star()); + if (solarSys != nullptr) + { + GtkMenu* planetsMenu = CreatePlanetarySystemMenu(name, solarSys->getPlanets()); + if (name == "Sol") + gtk_menu_item_set_submenu(AppendMenu(popup, nullptr, "Orbiting Bodies", 0), GTK_WIDGET(planetsMenu)); + else + gtk_menu_item_set_submenu(AppendMenu(popup, nullptr, "Planets", 0), GTK_WIDGET(planetsMenu)); + } + } + break; + + case SelectionType::DeepSky: + { + AppendMenu(popup, nullptr, app->simulation->getUniverse()->getDSOCatalog()->getDSOName(sel.deepsky()).c_str(), gtk_action_group_get_action(app->agMain, "CenterSelection")); + AppendMenu(popup, nullptr, nullptr, 0); + AppendMenu(popup, nullptr, "_Goto", gtk_action_group_get_action(app->agMain, "GotoSelection")); + AppendMenu(popup, nullptr, "_Follow", gtk_action_group_get_action(app->agMain, "FollowSelection")); + /* Add info eventually: + * AppendMenu(popup, nullptr, "_Info", 0); */ + } + break; + + case SelectionType::Location: + break; + + default: + break; + } + + if (app->simulation->getUniverse()->isMarked(sel, 1)) + AppendMenu(popup, menuUnMark, "_Unmark", 0); + else + AppendMenu(popup, menuMark, "_Mark", 0); + + app->simulation->setSelection(sel); + + gtk_widget_show_all(popup); + gtk_menu_popup(GTK_MENU(popup), nullptr, nullptr, nullptr, nullptr, 0, gtk_get_current_event_time()); +} + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/menu-context.h b/src/celestia/gtk/menu-context.h index f4fd72dd93..6f91388041 100644 --- a/src/celestia/gtk/menu-context.h +++ b/src/celestia/gtk/menu-context.h @@ -20,6 +20,9 @@ #include "common.h" +namespace celestia::gtk +{ + class GTKContextMenuHandler : public CelestiaCore::ContextMenuHandler { public: @@ -27,3 +30,5 @@ class GTKContextMenuHandler : public CelestiaCore::ContextMenuHandler void requestContextMenu(float, float, Selection sel); }; + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/settings-file.cpp b/src/celestia/gtk/settings-file.cpp index 87e8567b43..8cdfae500c 100644 --- a/src/celestia/gtk/settings-file.cpp +++ b/src/celestia/gtk/settings-file.cpp @@ -10,6 +10,9 @@ * $Id: settings-file.cpp,v 1.5 2008-01-18 04:36:11 suwalski Exp $ */ +#include +#include + #include #include @@ -19,24 +22,51 @@ #include "settings-file.h" #include "common.h" +namespace celestia::gtk +{ + +namespace +{ + +/* HELPER: gets an or-group flag and handles error checking */ +void +getFlag(GKeyFile* file, int *flags, int setting, const gchar* section, const gchar* key, int* errors) +{ + GError* e = nullptr; + + *flags |= setting * g_key_file_get_boolean(file, section, key, &e); + + if (e != nullptr) + *errors += 1; +} + +void +getFlag64(GKeyFile* file, std::uint64_t *flags, std::uint64_t setting, const gchar* section, const gchar* key, int* errors) +{ + GError* e = nullptr; + + *flags |= setting * g_key_file_get_boolean(file, section, key, &e); + + if (e != nullptr) + *errors += 1; +} -/* Definitions: Helpers */ -static void getFlag(GKeyFile* file, int *flags, int setting, const gchar* section, const gchar* key, int* errors); -static void getFlag64(GKeyFile* file, uint64_t *flags, uint64_t setting, const gchar* section, const gchar* key, int* errors); +} // end unnamed namespace /* ENTRY: Initializes and reads into memory the preferences */ -void initSettingsFile(AppData* app) +void +initSettingsFile(AppData* app) { - GError *error = NULL; + GError *error = nullptr; app->settingsFile = g_key_file_new(); - char* fn = g_build_filename(g_get_home_dir(), CELESTIARC, NULL); + char* fn = g_build_filename(g_get_home_dir(), CELESTIARC, nullptr); g_key_file_load_from_file(app->settingsFile, fn, G_KEY_FILE_NONE, &error); /* Should check G_KEY_FILE_ERROR_NOT_FOUND, but bug in glib returns wrong * error code. */ - if (error != NULL && g_file_test(fn, G_FILE_TEST_EXISTS)) + if (error != nullptr && g_file_test(fn, G_FILE_TEST_EXISTS)) { g_print("Error reading '%s': %s.\n", fn, error->message); exit(1); @@ -45,9 +75,9 @@ void initSettingsFile(AppData* app) g_free(fn); } - /* ENTRY: Applies preferences needed before initializing the core */ -void applySettingsFilePre(AppData* app, GKeyFile* file) +void +applySettingsFilePre(AppData* app, GKeyFile* file) { int sizeX, sizeY, positionX, positionY; GError* e; @@ -55,26 +85,26 @@ void applySettingsFilePre(AppData* app, GKeyFile* file) /* Numbers require special treatment because if they are not found they * are not set to NULL like strings. So, if that is the case, we set them * to values that will cause setSane*() to set defaults. */ - e= NULL; + e= nullptr; sizeX = g_key_file_get_integer(file, "Window", "width", &e); - if (e != NULL) sizeX = -1; + if (e != nullptr) sizeX = -1; - e= NULL; + e= nullptr; sizeY = g_key_file_get_integer(file, "Window", "height", &e); - if (e != NULL) sizeY = -1; + if (e != nullptr) sizeY = -1; - e= NULL; + e= nullptr; positionX = g_key_file_get_integer(file, "Window", "x", &e); - if (e != NULL) positionX = -1; + if (e != nullptr) positionX = -1; - e= NULL; + e= nullptr; positionY = g_key_file_get_integer(file, "Window", "y", &e); - if (e != NULL) positionY = -1; + if (e != nullptr) positionY = -1; /* These next two cannot be checked for sanity, default set here */ - e= NULL; + e= nullptr; app->fullScreen = g_key_file_get_boolean(file, "Window", "fullScreen", &e); - if (e != NULL) app->fullScreen = FALSE; + if (e != nullptr) app->fullScreen = FALSE; /* Nothing is set here. The prefs structure is used to set things at the * corrent times. */ @@ -82,47 +112,47 @@ void applySettingsFilePre(AppData* app, GKeyFile* file) setSaneWinPosition(app, positionX, positionY); } - /* ENTRY: Applies preferences after the core is initialized */ -void applySettingsFileMain(AppData* app, GKeyFile* file) +void +applySettingsFileMain(AppData* app, GKeyFile* file) { GError* e; float ambientLight, visualMagnitude, galaxyLightGain; int errors, verbosity, starStyle, textureResolution, distanceLimit, om, lm; - uint64_t rf; + std::uint64_t rf; /* See comment in applySettingsFilePrefs() */ - e = NULL; + e = nullptr; ambientLight = (float)g_key_file_get_integer(file, "Main", "ambientLight", &e) / 1000.0; - if (e != NULL) ambientLight = -1.0; + if (e != nullptr) ambientLight = -1.0; - e = NULL; + e = nullptr; visualMagnitude = (float)g_key_file_get_integer(file, "Main", "visualMagnitude", &e) / 1000.0; - if (e != NULL) visualMagnitude = -1.0; + if (e != nullptr) visualMagnitude = -1.0; - e = NULL; + e = nullptr; galaxyLightGain = (float)g_key_file_get_integer(file, "Main", "galaxyLightGain", &e) / 1000.0; - if (e != NULL) galaxyLightGain = -1.0; + if (e != nullptr) galaxyLightGain = -1.0; - e = NULL; + e = nullptr; distanceLimit = g_key_file_get_integer(file, "Main", "distanceLimit", &e); - if (e != NULL) distanceLimit = -1; + if (e != nullptr) distanceLimit = -1; - e = NULL; + e = nullptr; verbosity = g_key_file_get_integer(file, "Main", "verbosity", &e); - if (e != NULL) verbosity = -1; + if (e != nullptr) verbosity = -1; - e = NULL; + e = nullptr; starStyle = g_key_file_get_integer(file, "Main", "starStyle", &e); - if (e != NULL) starStyle = -1; + if (e != nullptr) starStyle = -1; - e = NULL; + e = nullptr; textureResolution = g_key_file_get_integer(file, "Main", "textureResolution", &e); - if (e != NULL) textureResolution = -1; + if (e != nullptr) textureResolution = -1; - e = NULL; + e = nullptr; app->showLocalTime = g_key_file_get_boolean(file, "Main", "localTime", &e); - if (e != NULL) app->showLocalTime = FALSE; + if (e != nullptr) app->showLocalTime = FALSE; /* All settings that need sanity checks get them */ setSaneAmbientLight(app, ambientLight); @@ -132,7 +162,7 @@ void applySettingsFileMain(AppData* app, GKeyFile* file) setSaneVerbosity(app, verbosity); setSaneStarStyle(app, (Renderer::StarStyle)starStyle); setSaneTextureResolution(app, textureResolution); - setSaneAltSurface(app, g_key_file_get_string(file, "Main", "altSurfaceName", NULL)); + setSaneAltSurface(app, g_key_file_get_string(file, "Main", "altSurfaceName", nullptr)); /* Render Flags */ errors = 0; @@ -215,32 +245,32 @@ void applySettingsFileMain(AppData* app, GKeyFile* file) app->renderer->setLabelMode(lm); } - /* ENTRY: Saves settings to file */ -void saveSettingsFile(AppData* app) +void +saveSettingsFile(AppData* app) { int om, lm; - uint64_t rf; + std::uint64_t rf; GKeyFile* file = app->settingsFile; - char* fn = g_build_filename(g_get_home_dir(), CELESTIARC, NULL); - FILE* outfile; + char* fn = g_build_filename(g_get_home_dir(), CELESTIARC, nullptr); + std::FILE* outfile; g_key_file_set_integer(file, "Main", "ambientLight", (int)(1000 * app->renderer->getAmbientLightLevel())); - g_key_file_set_comment(file, "Main", "ambientLight", "ambientLight = (int)(1000 * AmbientLightLevel)", NULL); + g_key_file_set_comment(file, "Main", "ambientLight", "ambientLight = (int)(1000 * AmbientLightLevel)", nullptr); g_key_file_set_integer(file, "Main", "visualMagnitude", (int)(1000 * app->simulation->getFaintestVisible())); - g_key_file_set_comment(file, "Main", "visualMagnitude", "visualMagnitude = (int)(1000 * FaintestVisible)", NULL); + g_key_file_set_comment(file, "Main", "visualMagnitude", "visualMagnitude = (int)(1000 * FaintestVisible)", nullptr); g_key_file_set_integer(file, "Main", "galaxyLightGain", (int)(1000 * Galaxy::getLightGain())); - g_key_file_set_comment(file, "Main", "galaxyLightGain", "galaxyLightGain = (int)(1000 * GalaxyLightGain)", NULL); + g_key_file_set_comment(file, "Main", "galaxyLightGain", "galaxyLightGain = (int)(1000 * GalaxyLightGain)", nullptr); g_key_file_set_integer(file, "Main", "distanceLimit", (int)app->renderer->getDistanceLimit()); - g_key_file_set_comment(file, "Main", "distanceLimit", "Rendering limit in light-years", NULL); + g_key_file_set_comment(file, "Main", "distanceLimit", "Rendering limit in light-years", nullptr); g_key_file_set_boolean(file, "Main", "localTime", app->showLocalTime); - g_key_file_set_comment(file, "Main", "localTime", "Display time in terms of local time zone", NULL); + g_key_file_set_comment(file, "Main", "localTime", "Display time in terms of local time zone", nullptr); g_key_file_set_integer(file, "Main", "verbosity", app->core->getHudDetail()); - g_key_file_set_comment(file, "Main", "verbosity", "Level of Detail in the heads-up-display. 0=None, 1=Terse, 2=Verbose", NULL); + g_key_file_set_comment(file, "Main", "verbosity", "Level of Detail in the heads-up-display. 0=None, 1=Terse, 2=Verbose", nullptr); g_key_file_set_integer(file, "Main", "starStyle", app->renderer->getStarStyle()); - g_key_file_set_comment(file, "Main", "starStyle", "Style of star rendering. 0=Fuzzy Points, 1=Points, 2=Scaled Discs", NULL); + g_key_file_set_comment(file, "Main", "starStyle", "Style of star rendering. 0=Fuzzy Points, 1=Points, 2=Scaled Discs", nullptr); g_key_file_set_integer(file, "Main", "textureResolution", app->renderer->getResolution()); - g_key_file_set_comment(file, "Main", "textureResolution", "Resolution of textures. 0=Low, 1=Medium, 2=High", NULL); + g_key_file_set_comment(file, "Main", "textureResolution", "Resolution of textures. 0=Low, 1=Medium, 2=High", nullptr); g_key_file_set_string(file, "Main", "altSurfaceName", app->simulation->getActiveObserver()->getDisplayedSurface().c_str()); g_key_file_set_integer(file, "Window", "width", getWinWidth(app)); @@ -308,40 +338,19 @@ void saveSettingsFile(AppData* app) g_key_file_set_boolean(file, "LabelMode", "i18n", lm & Renderer::I18nConstellationLabels); g_key_file_set_boolean(file, "LabelMode", "globular", lm & Renderer::GlobularLabels); - g_key_file_set_comment(file, "RenderFlags", NULL, "All Render Flag values must be true or false", NULL); - g_key_file_set_comment(file, "OrbitMask", NULL, "All Orbit Mask values must be true or false", NULL); - g_key_file_set_comment(file, "LabelMode", NULL, "All Label Mode values must be true or false", NULL); + g_key_file_set_comment(file, "RenderFlags", nullptr, "All Render Flag values must be true or false", nullptr); + g_key_file_set_comment(file, "OrbitMask", nullptr, "All Orbit Mask values must be true or false", nullptr); + g_key_file_set_comment(file, "LabelMode", nullptr, "All Label Mode values must be true or false", nullptr); /* Write the settings to a file */ - outfile = fopen(fn, "w"); + outfile = std::fopen(fn, "w"); - if (outfile == NULL) + if (outfile == nullptr) g_print("Error writing '%s'.\n", fn); - fputs(g_key_file_to_data(file, NULL, NULL), outfile); + std::fputs(g_key_file_to_data(file, nullptr, nullptr), outfile); g_free(fn); } - -/* HELPER: gets an or-group flag and handles error checking */ -static void getFlag(GKeyFile* file, int *flags, int setting, const gchar* section, const gchar* key, int* errors) -{ - GError* e = NULL; - - *flags |= setting * g_key_file_get_boolean(file, section, key, &e); - - if (e != NULL) - *errors += 1; -} - - -static void getFlag64(GKeyFile* file, uint64_t *flags, uint64_t setting, const gchar* section, const gchar* key, int* errors) -{ - GError* e = NULL; - - *flags |= setting * g_key_file_get_boolean(file, section, key, &e); - - if (e != NULL) - *errors += 1; -} +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/settings-file.h b/src/celestia/gtk/settings-file.h index 34df15763a..174bad68a6 100644 --- a/src/celestia/gtk/settings-file.h +++ b/src/celestia/gtk/settings-file.h @@ -16,9 +16,11 @@ #include "common.h" - #define CELESTIARC ".celestiarc" +namespace celestia::gtk +{ + /* Initialize Settings File */ void initSettingsFile(AppData* app); @@ -28,3 +30,5 @@ void applySettingsFileMain(AppData* app, GKeyFile* file); /* Save Settings to File */ void saveSettingsFile(AppData* app); + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/settings-gconf.cpp b/src/celestia/gtk/settings-gconf.cpp deleted file mode 100644 index 39b43e574c..0000000000 --- a/src/celestia/gtk/settings-gconf.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Celestia GTK+ Front-End - * Copyright (C) 2005 Pat Suwalski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * $Id: settings-gconf.cpp,v 1.4 2008-01-18 04:36:11 suwalski Exp $ - */ - -#include -#include - -#include -#include -#include - -#include "settings-gconf.h" -#include "common.h" - - -/* Definitions: GConf Callbacks */ -static void confLabels(GConfClient*, guint, GConfEntry*, AppData* app); -static void confRender(GConfClient*, guint, GConfEntry*, AppData* app); -static void confOrbits(GConfClient*, guint, GConfEntry*, AppData* app); -static void confWinWidth(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confWinHeight(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confWinX(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confWinY(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confAmbientLight(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confVisualMagnitude(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confGalaxyLightGain(GConfClient*, guint, GConfEntry* e, AppData*); -static void confDistanceLimit(GConfClient*, guint, GConfEntry* e, AppData*); -static void confShowLocalTime(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confVerbosity(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confFullScreen(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confStarStyle(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confTextureResolution(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confAltSurfaceName(GConfClient*, guint, GConfEntry* e, AppData* app); -static void confVideoSync(GConfClient*, guint, GConfEntry* e, AppData* app); - -/* Definitions: Helpers */ -static int readGConfRender(GConfClient* client); -static int readGConfOrbits(GConfClient* client); -static int readGConfLabels(GConfClient* client); -static void gcSetFlag(int type, const char* name, gboolean value, GConfClient* client); - - -/* ENTRY: Initializes the GConf connection */ -void initSettingsGConf(AppData* app) -{ - app->client = gconf_client_get_default(); - gconf_client_add_dir(app->client, "/apps/celestia", GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); -} - - -/* ENTRY: Connects GConf keys to their callbacks */ -void initSettingsGConfNotifiers(AppData* app) -{ - /* Add preference client notifiers. */ - gconf_client_notify_add (app->client, "/apps/celestia/labels", (GConfClientNotifyFunc)confLabels, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/render", (GConfClientNotifyFunc)confRender, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/orbits", (GConfClientNotifyFunc)confOrbits, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/winWidth", (GConfClientNotifyFunc)confWinWidth, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/winHeight", (GConfClientNotifyFunc)confWinHeight, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/winX", (GConfClientNotifyFunc)confWinX, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/winY", (GConfClientNotifyFunc)confWinY, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/ambientLight", (GConfClientNotifyFunc)confAmbientLight, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/visualMagnitude", (GConfClientNotifyFunc)confVisualMagnitude, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/galaxyLightGain", (GConfClientNotifyFunc)confGalaxyLightGain, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/distanceLimit", (GConfClientNotifyFunc)confDistanceLimit, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/showLocalTime", (GConfClientNotifyFunc)confShowLocalTime, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/verbosity", (GConfClientNotifyFunc)confVerbosity, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/fullScreen", (GConfClientNotifyFunc)confFullScreen, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/starStyle", (GConfClientNotifyFunc)confStarStyle, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/textureResolution", (GConfClientNotifyFunc)confTextureResolution, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/altSurfaceName", (GConfClientNotifyFunc)confAltSurfaceName, app, NULL, NULL); - gconf_client_notify_add (app->client, "/apps/celestia/videoSync", (GConfClientNotifyFunc)confVideoSync, app, NULL, NULL); -} - - -/* ENTRY: Reads preferences required before initializing simulation */ -void applySettingsGConfPre(AppData* app, GConfClient* client) -{ - int sizeX, sizeY, positionX, positionY; - - /* Error checking occurs as values are used */ - sizeX = gconf_client_get_int(client, "/apps/celestia/winWidth", NULL); - sizeY = gconf_client_get_int(client, "/apps/celestia/winHeight", NULL); - positionX = gconf_client_get_int(client, "/apps/celestia/winX", NULL); - positionY = gconf_client_get_int(client, "/apps/celestia/winY", NULL); - app->fullScreen = gconf_client_get_bool(client, "/apps/celestia/fullScreen", NULL); - - setSaneWinSize(app, sizeX, sizeY); - setSaneWinPosition(app, positionX, positionY); -} - - -/* ENTRY: Reads and applies basic preferences */ -void applySettingsGConfMain(AppData* app, GConfClient* client) -{ - int rf, om, lm; - - /* All settings that need sanity checks get them */ - setSaneAmbientLight(app, gconf_client_get_float(client, "/apps/celestia/ambientLight", NULL)); - setSaneVisualMagnitude(app, gconf_client_get_float(client, "/apps/celestia/visualMagnitude", NULL)); - setSaneGalaxyLightGain(gconf_client_get_float(client, "/apps/celestia/galaxyLightGain", NULL)); - setSaneDistanceLimit(app, gconf_client_get_int(client, "/apps/celestia/distanceLimit", NULL)); - setSaneVerbosity(app, gconf_client_get_int(client, "/apps/celestia/verbosity", NULL)); - setSaneStarStyle(app, (Renderer::StarStyle)gconf_client_get_int(client, "/apps/celestia/starStyle", NULL)); - setSaneTextureResolution(app, gconf_client_get_int(client, "/apps/celestia/textureResolution", NULL)); - setSaneAltSurface(app, gconf_client_get_string(client, "/apps/celestia/altSurfaceName", NULL)); - - app->showLocalTime = gconf_client_get_bool(client, "/apps/celestia/showLocalTime", NULL); - - app->renderer->setVideoSync(gconf_client_get_bool(client, "/apps/celestia/videoSync", NULL)); - - /* Render Flags */ - rf = readGConfRender(app->client); - app->renderer->setRenderFlags(rf); - - /* Orbit Mode */ - om = readGConfOrbits(app->client); - app->renderer->setOrbitMask(om); - - /* Label Mode */ - lm = readGConfLabels(app->client); - app->renderer->setLabelMode(lm); -} - - -/* ENTRY: Saves the final settings that are not updated on-the-fly */ -void saveSettingsGConf(AppData* app) -{ - /* Save window position */ - gconf_client_set_int(app->client, "/apps/celestia/winX", getWinX(app), NULL); - gconf_client_set_int(app->client, "/apps/celestia/winY", getWinY(app), NULL); - - /* Save window size */ - gconf_client_set_int(app->client, "/apps/celestia/winWidth", getWinWidth(app), NULL); - gconf_client_set_int(app->client, "/apps/celestia/winHeight", getWinHeight(app), NULL); - - /* These do not produce notification when changed */ - gconf_client_set_int(app->client, "/apps/celestia/textureResolution", app->renderer->getResolution(), NULL); - gconf_client_set_int(app->client, "/apps/celestia/distanceLimit", (int)app->renderer->getDistanceLimit(), NULL); - - g_object_unref (G_OBJECT (app->client)); -} - - -/* UTILITY: Converts a binary render flag to individual keys */ -void gcSetRenderFlag(int flag, gboolean state, GConfClient* client) -{ - switch (flag) - { - case Renderer::ShowStars: gcSetFlag(Render, "stars", state, client); break; - case Renderer::ShowPlanets: gcSetFlag(Render, "planets", state, client); break; - case Renderer::ShowGalaxies: gcSetFlag(Render, "galaxies", state, client); break; - case Renderer::ShowDiagrams: gcSetFlag(Render, "diagrams", state, client); break; - case Renderer::ShowCloudMaps: gcSetFlag(Render, "cloudMaps", state, client); break; - case Renderer::ShowOrbits: gcSetFlag(Render, "orbits", state, client); break; - case Renderer::ShowCelestialSphere: gcSetFlag(Render, "celestialSphere", state, client); break; - case Renderer::ShowNightMaps: gcSetFlag(Render, "nightMaps", state, client); break; - case Renderer::ShowAtmospheres: gcSetFlag(Render, "atmospheres", state, client); break; - case Renderer::ShowSmoothLines: gcSetFlag(Render, "smoothLines", state, client); break; - case Renderer::ShowEclipseShadows: gcSetFlag(Render, "eclipseShadows", state, client); break; - case Renderer::ShowRingShadows: gcSetFlag(Render, "ringShadows", state, client); break; - case Renderer::ShowBoundaries: gcSetFlag(Render, "boundaries", state, client); break; - case Renderer::ShowAutoMag: gcSetFlag(Render, "autoMag", state, client); break; - case Renderer::ShowCometTails: gcSetFlag(Render, "cometTails", state, client); break; - case Renderer::ShowMarkers: gcSetFlag(Render, "markers", state, client); break; - case Renderer::ShowPartialTrajectories: gcSetFlag(Render, "partialTrajectories", state, client); break; - case Renderer::ShowNebulae: gcSetFlag(Render, "nebulae", state, client); break; - case Renderer::ShowOpenClusters: gcSetFlag(Render, "openClusters", state, client); break; - case Renderer::ShowGlobulars: gcSetFlag(Render, "globulars", state, client); break; - case Renderer::ShowGalacticGrid: gcSetFlag(Render, "gridGalactic", state, client); break; - case Renderer::ShowEclipticGrid: gcSetFlag(Render, "gridEcliptic", state, client); break; - case Renderer::ShowHorizonGrid: gcSetFlag(Render, "gridHorizontal", state, client); break; - } -} - - -/* UTILITY: Converts a binary orbit mask to individual keys */ -void gcSetOrbitMask(int flag, gboolean state, GConfClient* client) -{ - switch (flag) - { - case Body::Planet: gcSetFlag(Orbit, "planet", state, client); break; - case Body::Moon: gcSetFlag(Orbit, "moon", state, client); break; - case Body::Asteroid: gcSetFlag(Orbit, "asteroid", state, client); break; - case Body::Spacecraft: gcSetFlag(Orbit, "spacecraft", state, client); break; - case Body::Comet: gcSetFlag(Orbit, "comet", state, client); break; - case Body::Invisible: gcSetFlag(Orbit, "invisible", state, client); break; - case Body::Unknown: gcSetFlag(Orbit, "unknown", state, client); break; - } -} - - -/* UTILITY: Converts a binary label mode to individual keys */ -void gcSetLabelMode(int flag, gboolean state, GConfClient* client) -{ - switch (flag) - { - case Renderer::StarLabels: gcSetFlag(Label, "star", state, client); break; - case Renderer::PlanetLabels: gcSetFlag(Label, "planet", state, client); break; - case Renderer::MoonLabels: gcSetFlag(Label, "moon", state, client); break; - case Renderer::ConstellationLabels: gcSetFlag(Label, "constellation", state, client); break; - case Renderer::GalaxyLabels: gcSetFlag(Label, "galaxy", state, client); break; - case Renderer::AsteroidLabels: gcSetFlag(Label, "asteroid", state, client); break; - case Renderer::SpacecraftLabels: gcSetFlag(Label, "spacecraft", state, client); break; - case Renderer::LocationLabels: gcSetFlag(Label, "location", state, client); break; - case Renderer::CometLabels: gcSetFlag(Label, "comet", state, client); break; - case Renderer::NebulaLabels: gcSetFlag(Label, "nebula", state, client); break; - case Renderer::OpenClusterLabels: gcSetFlag(Label, "openCluster", state, client); break; - case Renderer::I18nConstellationLabels: gcSetFlag(Label, "i18n", state, client); break; - case Renderer::GlobularLabels: gcSetFlag(Label, "globular", state, client); break; - } -} - - -/* GCONF CALLBACK: Reloads labels upon change */ -static void confLabels(GConfClient*, guint, GConfEntry*, AppData* app) -{ - int oldLabels = app->renderer->getLabelMode(); - - /* Reload all the labels */ - int newLabels = readGConfLabels(app->client); - - /* Set label flags */ - if (newLabels != oldLabels) - app->renderer->setLabelMode(newLabels); -} - - -/* GCONF CALLBACK: Reloads render flags upon change */ -static void confRender(GConfClient*, guint, GConfEntry*, AppData* app) -{ - int oldRender = app->renderer->getRenderFlags(); - - /* Reload all the render flags */ - int newRender = readGConfRender(app->client); - - /* Set render flags */ - if (newRender != oldRender) - app->renderer->setRenderFlags(newRender); -} - - -/* GCONF CALLBACK: Reloads orbits upon change */ -static void confOrbits(GConfClient*, guint, GConfEntry*, AppData* app) -{ - int oldOrbit = app->renderer->getOrbitMask(); - - /* Reload all the orbits */ - int newOrbit = readGConfOrbits(app->client); - - /* Set orbit flags */ - if (newOrbit != oldOrbit) - app->renderer->setOrbitMask(newOrbit); -} - - -/* GCONF CALLBACK: Sets window width upon change */ -static void confWinWidth(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int w = gconf_value_get_int(e->value); - - if (w != getWinWidth(app)) - setSaneWinSize(app, w, getWinHeight(app)); -} - - -/* GCONF CALLBACK: Sets window height upon change */ -static void confWinHeight(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int h = gconf_value_get_int(e->value); - - if (h != getWinHeight(app)) - setSaneWinSize(app, getWinWidth(app), h); -} - - -/* GCONF CALLBACK: Sets window X position upon change */ -static void confWinX(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int x = gconf_value_get_int(e->value); - - if (x != getWinX(app)) - setSaneWinPosition(app, x, getWinY(app)); -} - - -/* GCONF CALLBACK: Sets window Y position upon change */ -static void confWinY(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int y = gconf_value_get_int(e->value); - - if (y != getWinY(app)) - setSaneWinPosition(app, getWinX(app), y); -} - - -/* GCONF CALLBACK: Reloads ambient light setting upon change */ -static void confAmbientLight(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - float value = gconf_value_get_float(e->value); - - /* Comparing floats is tricky. Three decimal places is "close enough." */ - if (abs(value - app->renderer->getAmbientLightLevel()) < 0.001) - return; - - setSaneAmbientLight(app, value); -} - - -/* GCONF CALLBACK: Reloads visual magnitude setting upon change */ -static void confVisualMagnitude(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - float value = gconf_value_get_float(e->value); - - if (abs(value - app->simulation->getFaintestVisible()) < 0.001) - return; - - setSaneVisualMagnitude(app, value); -} - - -/* GCONF CALLBACK: Reloads galaxy light gain setting upon change */ -static void confGalaxyLightGain(GConfClient*, guint, GConfEntry* e, AppData*) -{ - float value = gconf_value_get_float(e->value); - - if (abs(value - Galaxy::getLightGain()) < 0.001) - return; - - setSaneGalaxyLightGain(value); -} - - -/* GCONF CALLBACK: Sets texture resolution when changed */ -static void confDistanceLimit(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int value = gconf_value_get_int(e->value); - - if (value == app->renderer->getDistanceLimit()) - return; - - setSaneDistanceLimit(app, value); -} - - -/* GCONF CALLBACK: Sets "show local time" setting upon change */ -static void confShowLocalTime(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - gboolean value = gconf_value_get_bool(e->value); - - if (value == app->showLocalTime) - return; - - app->showLocalTime = value; - updateTimeZone(app, app->showLocalTime); -} - - -/* GCONF CALLBACK: Sets HUD detail when changed */ -static void confVerbosity(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int value = gconf_value_get_int(e->value); - - if (value == app->core->getHudDetail()) - return; - - setSaneVerbosity(app, value); -} - - -/* GCONF CALLBACK: Sets window to fullscreen when change occurs */ -static void confFullScreen(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - gboolean value = gconf_value_get_bool(e->value); - - /* There is no way to determine if the window is actually full screen */ - if (value == app->fullScreen) - return; - - /* The Action handler for full-screen toggles for us, so we set it opposite - * of what is wanted, and... */ - app->fullScreen = !value; - - /* ... tickle it. */ - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_action_group_get_action(app->agMain, "FullScreen")), value); -} - - -/* GCONF CALLBACK: Sets star style when changed */ -static void confStarStyle(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int value = gconf_value_get_int(e->value); - - if (value == app->renderer->getStarStyle()) - return; - - setSaneStarStyle(app, (Renderer::StarStyle)value); -} - - -/* GCONF CALLBACK: Sets texture resolution when changed */ -static void confTextureResolution(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - int value = gconf_value_get_int(e->value); - - if (value == (int)app->renderer->getResolution()) - return; - - setSaneTextureResolution(app, value); -} - - -/* GCONF CALLBACK: Sets alternate surface texture when changed */ -static void confAltSurfaceName(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - const char* value = gconf_value_get_string(e->value); - - if (string(value) == app->simulation->getActiveObserver()->getDisplayedSurface()) - return; - - setSaneAltSurface(app, (char*)value); -} - - -/* GCONF CALLBACK: Sets video framerate sync when changed */ -static void confVideoSync(GConfClient*, guint, GConfEntry* e, AppData* app) -{ - gboolean value = gconf_value_get_bool(e->value); - - if (value == app->renderer->getVideoSync()) - return; - - app->renderer->setVideoSync(value); -} - - -/* HELPER: Reads in GConf->Render preferences and returns as int mask */ -static int readGConfRender(GConfClient* client) -{ - int rf = Renderer::ShowNothing; - rf |= Renderer::ShowStars * gconf_client_get_bool(client, "/apps/celestia/render/stars", NULL); - rf |= Renderer::ShowPlanets * gconf_client_get_bool(client, "/apps/celestia/render/planets", NULL); - rf |= Renderer::ShowGalaxies * gconf_client_get_bool(client, "/apps/celestia/render/galaxies", NULL); - rf |= Renderer::ShowDiagrams * gconf_client_get_bool(client, "/apps/celestia/render/diagrams", NULL); - rf |= Renderer::ShowCloudMaps * gconf_client_get_bool(client, "/apps/celestia/render/cloudMaps", NULL); - rf |= Renderer::ShowOrbits * gconf_client_get_bool(client, "/apps/celestia/render/orbits", NULL); - rf |= Renderer::ShowCelestialSphere * gconf_client_get_bool(client, "/apps/celestia/render/celestialSphere", NULL); - rf |= Renderer::ShowNightMaps * gconf_client_get_bool(client, "/apps/celestia/render/nightMaps", NULL); - rf |= Renderer::ShowAtmospheres * gconf_client_get_bool(client, "/apps/celestia/render/atmospheres", NULL); - rf |= Renderer::ShowSmoothLines * gconf_client_get_bool(client, "/apps/celestia/render/smoothLines", NULL); - rf |= Renderer::ShowEclipseShadows * gconf_client_get_bool(client, "/apps/celestia/render/eclipseShadows", NULL); - rf |= Renderer::ShowRingShadows * gconf_client_get_bool(client, "/apps/celestia/render/ringShadows", NULL); - rf |= Renderer::ShowBoundaries * gconf_client_get_bool(client, "/apps/celestia/render/boundaries", NULL); - rf |= Renderer::ShowAutoMag * gconf_client_get_bool(client, "/apps/celestia/render/autoMag", NULL); - rf |= Renderer::ShowCometTails * gconf_client_get_bool(client, "/apps/celestia/render/cometTails", NULL); - rf |= Renderer::ShowMarkers * gconf_client_get_bool(client, "/apps/celestia/render/markers", NULL); - rf |= Renderer::ShowPartialTrajectories * gconf_client_get_bool(client, "/apps/celestia/render/partialTrajectories", NULL); - rf |= Renderer::ShowNebulae * gconf_client_get_bool(client, "/apps/celestia/render/nebulae", NULL); - rf |= Renderer::ShowOpenClusters * gconf_client_get_bool(client, "/apps/celestia/render/openClusters", NULL); - rf |= Renderer::ShowGlobulars * gconf_client_get_bool(client, "/apps/celestia/render/globulars", NULL); - rf |= Renderer::ShowGalacticGrid * gconf_client_get_bool(client, "/apps/celestia/render/gridGalactic", NULL); - rf |= Renderer::ShowEclipticGrid * gconf_client_get_bool(client, "/apps/celestia/render/gridEcliptic", NULL); - rf |= Renderer::ShowHorizonGrid * gconf_client_get_bool(client, "/apps/celestia/render/gridHorizontal", NULL); - - return rf; -} - - -/* HELPER: Reads in GConf->Orbits preferences and returns as int mask */ -static int readGConfOrbits(GConfClient* client) -{ - int om = 0; - om |= Body::Planet * gconf_client_get_bool(client, "/apps/celestia/orbits/planet", NULL); - om |= Body::Moon * gconf_client_get_bool(client, "/apps/celestia/orbits/moon", NULL); - om |= Body::Asteroid * gconf_client_get_bool(client, "/apps/celestia/orbits/asteroid", NULL); - om |= Body::Comet * gconf_client_get_bool(client, "/apps/celestia/orbits/comet", NULL); - om |= Body::Spacecraft * gconf_client_get_bool(client, "/apps/celestia/orbits/spacecraft", NULL); - om |= Body::Invisible * gconf_client_get_bool(client, "/apps/celestia/orbits/invisible", NULL); - om |= Body::Unknown * gconf_client_get_bool(client, "/apps/celestia/orbits/unknown", NULL); - - return om; -} - - -/* HELPER: Reads in GConf->Labels preferences and returns as int mask */ -static int readGConfLabels(GConfClient* client) -{ - int lm = Renderer::NoLabels; - lm |= Renderer::StarLabels * gconf_client_get_bool(client, "/apps/celestia/labels/star", NULL); - lm |= Renderer::PlanetLabels * gconf_client_get_bool(client, "/apps/celestia/labels/planet", NULL); - lm |= Renderer::MoonLabels * gconf_client_get_bool(client, "/apps/celestia/labels/moon", NULL); - lm |= Renderer::ConstellationLabels * gconf_client_get_bool(client, "/apps/celestia/labels/constellation", NULL); - lm |= Renderer::GalaxyLabels * gconf_client_get_bool(client, "/apps/celestia/labels/galaxy", NULL); - lm |= Renderer::AsteroidLabels * gconf_client_get_bool(client, "/apps/celestia/labels/asteroid", NULL); - lm |= Renderer::SpacecraftLabels * gconf_client_get_bool(client, "/apps/celestia/labels/spacecraft", NULL); - lm |= Renderer::LocationLabels * gconf_client_get_bool(client, "/apps/celestia/labels/location", NULL); - lm |= Renderer::CometLabels * gconf_client_get_bool(client, "/apps/celestia/labels/comet", NULL); - lm |= Renderer::NebulaLabels * gconf_client_get_bool(client, "/apps/celestia/labels/nebula", NULL); - lm |= Renderer::OpenClusterLabels * gconf_client_get_bool(client, "/apps/celestia/labels/openCluster", NULL); - lm |= Renderer::I18nConstellationLabels * gconf_client_get_bool(client, "/apps/celestia/labels/i18n", NULL); - lm |= Renderer::GlobularLabels * gconf_client_get_bool(client, "/apps/celestia/labels/globular", NULL); - - return lm; -} - - -/* HELPER: Sets one of the flags according to provided type, key, and value */ -static void gcSetFlag(int type, const char* name, gboolean value, GConfClient* client) -{ - gchar key[60]; - switch (type) - { - case Render: sprintf(key, "%s%s", "/apps/celestia/render/", name); break; - case Orbit: sprintf(key, "%s%s", "/apps/celestia/orbits/", name); break; - case Label: sprintf(key, "%s%s", "/apps/celestia/labels/", name); break; - } - - gconf_client_set_bool(client, key, value, NULL); -} diff --git a/src/celestia/gtk/settings-gconf.h b/src/celestia/gtk/settings-gconf.h deleted file mode 100644 index 9dbe27889a..0000000000 --- a/src/celestia/gtk/settings-gconf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Celestia GTK+ Front-End - * Copyright (C) 2005 Pat Suwalski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * $Id: settings-gconf.h,v 1.1 2005-12-06 03:19:36 suwalski Exp $ - */ - -#pragma once - -#include - -#include "common.h" - - -/* Initialize GConf */ -void initSettingsGConf(AppData* app); -void initSettingsGConfNotifiers(AppData* app); - -/* Apply Settings */ -void applySettingsGConfPre(AppData* app, GConfClient* client); -void applySettingsGConfMain(AppData* app, GConfClient* client); - -/* Save Settings to GConf */ -void saveSettingsGConf(AppData* app); - -/* Utility Functions */ -void gcSetRenderFlag(int flag, gboolean state, GConfClient* client); -void gcSetOrbitMask(int flag, gboolean state, GConfClient* client); -void gcSetLabelMode(int flag, gboolean state, GConfClient* client); - - -enum { - Render = 0, - Orbit = 1, - Label = 2, -}; diff --git a/src/celestia/gtk/splash.cpp b/src/celestia/gtk/splash.cpp index 28502b85a8..2fefd2a602 100644 --- a/src/celestia/gtk/splash.cpp +++ b/src/celestia/gtk/splash.cpp @@ -10,6 +10,8 @@ * $Id: splash.cpp,v 1.4 2006-07-24 17:31:24 christey Exp $ */ +#include + #include #include #include @@ -21,28 +23,90 @@ #include "splash.h" #include "common.h" -using namespace std; +namespace celestia::gtk +{ +namespace +{ /* Declarations */ #if GTK_MAJOR_VERSION == 2 -static gboolean splashExpose(GtkWidget* win, GdkEventExpose *event, SplashData* ss); -#endif +/* CALLBACK: Called when the splash screen is exposed */ +gboolean +splashExpose(GtkWidget* win, GdkEventExpose *event, SplashData* ss) +{ + /* All of this code is only needed at the very first drawing. This + * operation is quite expensive. */ + if (ss->redraw != TRUE) return FALSE; + + GdkWindow *ww = gtk_widget_get_window(win); + + if (ss->hasARGB) + { + #ifdef CAIRO + /* Use cairo for true transparent windows */ + cairo_t *cr = gdk_cairo_create(ww); + + cairo_rectangle(cr, event->area.x, + event->area.y, + event->area.width, + event->area.height); + cairo_clip(cr); + + /* Draw a fully transparent rectangle the size of the window */ + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(cr); + cairo_destroy(cr); + #endif /* CAIRO */ + } + else + { + /* Fall back to compositing a screenshot of whatever is below the + * area we are drawing in. */ + GdkPixbuf* bg; + int x, y, w, h; + + gdk_window_get_root_origin(ww, &x, &y); + w = gdk_window_get_width(ww); + h = gdk_window_get_height(ww); + + bg = gdk_pixbuf_get_from_drawable(nullptr, + gtk_widget_get_root_window(win), + nullptr, x, y, 0, 0, w, h); + cairo_t *cr = gdk_cairo_create(ww); + gdk_cairo_set_source_pixbuf(cr, bg, x, y); + cairo_paint(cr); + cairo_destroy(cr); + g_object_unref(bg); + } + + /* Never redraw again */ + ss->redraw = FALSE; + + return FALSE; +} +#endif +} // end unnamed namespace /* OBJECT: Overrides ProgressNotifier to receive feedback from core */ GtkSplashProgressNotifier::GtkSplashProgressNotifier(SplashData* _splash) : - splash(_splash) {}; + splash(_splash) +{ +}; -void GtkSplashProgressNotifier::update(const string& filename) +void +GtkSplashProgressNotifier::update(const std::string& filename) { splashSetText(splash, filename.c_str()); } GtkSplashProgressNotifier::~GtkSplashProgressNotifier() {}; - /* ENTRY: Creates a new SplashData struct, starts the splash screen */ -SplashData* splashStart(AppData* app, gboolean showSplash, const gchar* installDir, const gchar* defaultDir) +SplashData* +splashStart(AppData* app, gboolean showSplash, const gchar* installDir, const gchar* defaultDir) { SplashData* ss = g_new0(SplashData, 1); @@ -65,7 +129,7 @@ SplashData* splashStart(AppData* app, gboolean showSplash, const gchar* installD /* Colormap Magic */ GdkScreen* screen = gtk_widget_get_screen(ss->splash); GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen); - if (colormap != NULL) + if (colormap != nullptr) { gtk_widget_set_colormap(ss->splash, colormap); ss->hasARGB = TRUE; @@ -97,7 +161,7 @@ SplashData* splashStart(AppData* app, gboolean showSplash, const gchar* installD /* The information label is right-aligned and biased to the lower-right * of the window. It's designed to be the full width and height of the * opaque parts of the splash. */ - ss->label = gtk_label_new(NULL); + ss->label = gtk_label_new(nullptr); gtk_misc_set_alignment(GTK_MISC(ss->label), 1, 1); gtk_label_set_justify(GTK_LABEL(ss->label), GTK_JUSTIFY_RIGHT); gtk_widget_modify_fg(ss->label, GTK_STATE_NORMAL, >k_widget_get_style(ss->label)->white); @@ -123,9 +187,9 @@ SplashData* splashStart(AppData* app, gboolean showSplash, const gchar* installD return ss; } - /* ENTRY: destroys the splash screen */ -void splashEnd(SplashData* ss) +void +splashEnd(SplashData* ss) { if (ss->splash) gtk_widget_destroy(ss->splash); @@ -137,16 +201,16 @@ void splashEnd(SplashData* ss) g_free(ss); } - /* ENTRY: Sets the text to be shown in the splash */ -void splashSetText(SplashData* ss, const char* text) +void +splashSetText(SplashData* ss, const char* text) { char message[255]; if (!ss->splash) return; - sprintf(message, "Version " VERSION "\n%s", text); + std::sprintf(message, "Version " VERSION "\n%s", text); gtk_label_set_text(GTK_LABEL(ss->label), message); @@ -154,61 +218,4 @@ void splashSetText(SplashData* ss, const char* text) while (gtk_events_pending()) gtk_main_iteration(); } -#if GTK_MAJOR_VERSION == 2 -/* CALLBACK: Called when the splash screen is exposed */ -static gboolean splashExpose(GtkWidget* win, GdkEventExpose *event, SplashData* ss) -{ - /* All of this code is only needed at the very first drawing. This - * operation is quite expensive. */ - if (ss->redraw != TRUE) return FALSE; - - GdkWindow *ww = gtk_widget_get_window(win); - - if (ss->hasARGB) - { - #ifdef CAIRO - /* Use cairo for true transparent windows */ - cairo_t *cr = gdk_cairo_create(ww); - - cairo_rectangle(cr, event->area.x, - event->area.y, - event->area.width, - event->area.height); - cairo_clip(cr); - - /* Draw a fully transparent rectangle the size of the window */ - cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0); - - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_paint(cr); - - cairo_destroy(cr); - #endif /* CAIRO */ - } - else - { - /* Fall back to compositing a screenshot of whatever is below the - * area we are drawing in. */ - GdkPixbuf* bg; - int x, y, w, h; - - gdk_window_get_root_origin(ww, &x, &y); - w = gdk_window_get_width(ww); - h = gdk_window_get_height(ww); - - bg = gdk_pixbuf_get_from_drawable(NULL, - gtk_widget_get_root_window(win), - NULL, x, y, 0, 0, w, h); - cairo_t *cr = gdk_cairo_create(ww); - gdk_cairo_set_source_pixbuf(cr, bg, x, y); - cairo_paint(cr); - cairo_destroy(cr); - g_object_unref(bg); - } - - /* Never redraw again */ - ss->redraw = FALSE; - - return FALSE; -} -#endif +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/splash.h b/src/celestia/gtk/splash.h index 5c01876a7d..7820297d7f 100644 --- a/src/celestia/gtk/splash.h +++ b/src/celestia/gtk/splash.h @@ -12,27 +12,19 @@ #pragma once +#include + #include "common.h" #include -typedef struct _SplashData SplashData; - -/* This class overrides the ProgressNotifier to receive splash event updates - * from the core. */ -class GtkSplashProgressNotifier : public ProgressNotifier +namespace celestia::gtk { - public: - GtkSplashProgressNotifier(SplashData* _splash); - virtual ~GtkSplashProgressNotifier(); - virtual void update(const std::string& filename); - - private: - SplashData* splash; -}; +class GtkSplashProgressNotifier; /* Struct holds all information relevant to the splash screen. */ +typedef struct _SplashData SplashData; struct _SplashData { AppData* app; @@ -45,8 +37,23 @@ struct _SplashData { gboolean redraw; }; +/* This class overrides the ProgressNotifier to receive splash event updates + * from the core. */ +class GtkSplashProgressNotifier : public ProgressNotifier +{ + public: + GtkSplashProgressNotifier(SplashData* _splash); + virtual ~GtkSplashProgressNotifier(); + + virtual void update(const std::string& filename); + + private: + SplashData* splash; +}; /* Entry Functions */ SplashData* splashStart(AppData* app, gboolean showSplash, const gchar* installDir, const gchar* defaultDir); void splashEnd(SplashData* ss); void splashSetText(SplashData* ss, const char* text); + +} // end namespace celestia::gtk diff --git a/src/celestia/gtk/ui.h b/src/celestia/gtk/ui.h index 7fef471d15..192093f225 100644 --- a/src/celestia/gtk/ui.h +++ b/src/celestia/gtk/ui.h @@ -12,182 +12,193 @@ #pragma once +#include + #include #include "actions.h" +namespace celestia::gtk +{ + /* By default all action widgets are turned off. They will be set later when * they are being synchronized with settings and with the core. */ /* Regular Actions */ -static const GtkActionEntry actionsPlain[] = { - { "FileMenu", NULL, "_File", NULL, NULL, NULL }, - { "CopyURL", GTK_STOCK_COPY, "Copy _URL", NULL, NULL, G_CALLBACK(actionCopyURL) }, - { "OpenURL", NULL, "Open UR_L", NULL, NULL, G_CALLBACK(actionOpenURL) }, - { "OpenScript", GTK_STOCK_OPEN, "_Open Script...", NULL, NULL, G_CALLBACK(actionOpenScript) }, - { "CaptureImage", GTK_STOCK_SAVE_AS, "_Capture Image...", NULL, NULL, G_CALLBACK(actionCaptureImage) }, - { "CaptureMovie", GTK_STOCK_SAVE_AS, "Capture _Movie...", NULL, NULL, G_CALLBACK(actionCaptureMovie) }, - { "RunDemo", GTK_STOCK_EXECUTE, "Run _Demo", NULL, NULL, G_CALLBACK(actionRunDemo) }, - { "Quit", GTK_STOCK_QUIT, "_Quit", "Q", NULL, G_CALLBACK(actionQuit) }, - - { "NavigationMenu", NULL, "_Navigation", NULL, NULL, NULL }, - { "SelectSol", GTK_STOCK_HOME, "Select _Sol", "H", NULL, G_CALLBACK(actionSelectSol) }, - { "TourGuide", NULL, "Tour G_uide...", NULL, NULL, G_CALLBACK(actionTourGuide) }, - { "SearchObject", GTK_STOCK_FIND, "Search for _Object...", NULL, NULL, G_CALLBACK(actionSearchObject) }, - { "GotoObject", NULL, "Go to Object...", NULL, NULL, G_CALLBACK(actionGotoObject) }, - { "CenterSelection", NULL, "_Center Selection", "c", NULL, G_CALLBACK(actionCenterSelection) }, - { "GotoSelection", GTK_STOCK_JUMP_TO, "_Go to Selection", "G", NULL, G_CALLBACK(actionGotoSelection) }, - { "FollowSelection", NULL, "_Follow Selection", "F", NULL, G_CALLBACK(actionFollowSelection) }, - { "SyncSelection", NULL, "S_ync Orbit Selection", "Y", NULL, G_CALLBACK(actionSyncSelection) }, - { "TrackSelection", NULL, "_Track Selection", "T", NULL, G_CALLBACK(actionTrackSelection) }, - { "SystemBrowser", NULL, "Solar System _Browser...", NULL, NULL, G_CALLBACK(actionSystemBrowser) }, - { "StarBrowser", NULL, "Star B_rowser...", NULL, NULL, G_CALLBACK(actionStarBrowser) }, - { "EclipseFinder", NULL, "_Eclipse Finder...", NULL, NULL, G_CALLBACK(actionEclipseFinder) }, - - { "TimeMenu", NULL, "_Time", NULL, NULL, NULL }, - { "TimeFaster", NULL, "2x _Faster", "L", NULL, G_CALLBACK(actionTimeFaster) }, - { "TimeSlower", NULL, "2x _Slower", "K", NULL, G_CALLBACK(actionTimeSlower) }, - { "TimeFreeze", NULL, "Free_ze", "space", NULL, G_CALLBACK(actionTimeFreeze) }, - { "TimeReal", NULL, "_Real Time", "backslash", NULL, G_CALLBACK(actionTimeReal) }, - { "TimeReverse", NULL, "Re_verse Time", "J", NULL, G_CALLBACK(actionTimeReverse) }, - { "TimeSet", NULL, "Set _Time...", NULL, NULL, G_CALLBACK(actionTimeSet) }, +const inline std::array actionsPlain +{ + GtkActionEntry{ "FileMenu", nullptr, "_File", nullptr, nullptr, nullptr }, + GtkActionEntry{ "CopyURL", GTK_STOCK_COPY, "Copy _URL", nullptr, nullptr, G_CALLBACK(actionCopyURL) }, + GtkActionEntry{ "OpenURL", nullptr, "Open UR_L", nullptr, nullptr, G_CALLBACK(actionOpenURL) }, + GtkActionEntry{ "OpenScript", GTK_STOCK_OPEN, "_Open Script...", nullptr, nullptr, G_CALLBACK(actionOpenScript) }, + GtkActionEntry{ "CaptureImage", GTK_STOCK_SAVE_AS, "_Capture Image...", nullptr, nullptr, G_CALLBACK(actionCaptureImage) }, + GtkActionEntry{ "CaptureMovie", GTK_STOCK_SAVE_AS, "Capture _Movie...", nullptr, nullptr, G_CALLBACK(actionCaptureMovie) }, + GtkActionEntry{ "RunDemo", GTK_STOCK_EXECUTE, "Run _Demo", nullptr, nullptr, G_CALLBACK(actionRunDemo) }, + GtkActionEntry{ "Quit", GTK_STOCK_QUIT, "_Quit", "Q", nullptr, G_CALLBACK(actionQuit) }, + + GtkActionEntry{ "NavigationMenu", nullptr, "_Navigation", nullptr, nullptr, nullptr }, + GtkActionEntry{ "SelectSol", GTK_STOCK_HOME, "Select _Sol", "H", nullptr, G_CALLBACK(actionSelectSol) }, + GtkActionEntry{ "TourGuide", nullptr, "Tour G_uide...", nullptr, nullptr, G_CALLBACK(actionTourGuide) }, + GtkActionEntry{ "SearchObject", GTK_STOCK_FIND, "Search for _Object...", nullptr, nullptr, G_CALLBACK(actionSearchObject) }, + GtkActionEntry{ "GotoObject", nullptr, "Go to Object...", nullptr, nullptr, G_CALLBACK(actionGotoObject) }, + GtkActionEntry{ "CenterSelection", nullptr, "_Center Selection", "c", nullptr, G_CALLBACK(actionCenterSelection) }, + GtkActionEntry{ "GotoSelection", GTK_STOCK_JUMP_TO, "_Go to Selection", "G", nullptr, G_CALLBACK(actionGotoSelection) }, + GtkActionEntry{ "FollowSelection", nullptr, "_Follow Selection", "F", nullptr, G_CALLBACK(actionFollowSelection) }, + GtkActionEntry{ "SyncSelection", nullptr, "S_ync Orbit Selection", "Y", nullptr, G_CALLBACK(actionSyncSelection) }, + GtkActionEntry{ "TrackSelection", nullptr, "_Track Selection", "T", nullptr, G_CALLBACK(actionTrackSelection) }, + GtkActionEntry{ "SystemBrowser", nullptr, "Solar System _Browser...", nullptr, nullptr, G_CALLBACK(actionSystemBrowser) }, + GtkActionEntry{ "StarBrowser", nullptr, "Star B_rowser...", nullptr, nullptr, G_CALLBACK(actionStarBrowser) }, + GtkActionEntry{ "EclipseFinder", nullptr, "_Eclipse Finder...", nullptr, nullptr, G_CALLBACK(actionEclipseFinder) }, + + GtkActionEntry{ "TimeMenu", nullptr, "_Time", nullptr, nullptr, nullptr }, + GtkActionEntry{ "TimeFaster", nullptr, "2x _Faster", "L", nullptr, G_CALLBACK(actionTimeFaster) }, + GtkActionEntry{ "TimeSlower", nullptr, "2x _Slower", "K", nullptr, G_CALLBACK(actionTimeSlower) }, + GtkActionEntry{ "TimeFreeze", nullptr, "Free_ze", "space", nullptr, G_CALLBACK(actionTimeFreeze) }, + GtkActionEntry{ "TimeReal", nullptr, "_Real Time", "backslash", nullptr, G_CALLBACK(actionTimeReal) }, + GtkActionEntry{ "TimeReverse", nullptr, "Re_verse Time", "J", nullptr, G_CALLBACK(actionTimeReverse) }, + GtkActionEntry{ "TimeSet", nullptr, "Set _Time...", nullptr, nullptr, G_CALLBACK(actionTimeSet) }, /* "Show Local Time" in toggle actions */ - { "OptionsMenu", NULL, "_Options", NULL, NULL, NULL }, - { "ViewOptions", GTK_STOCK_PREFERENCES, "View _Options...", NULL, NULL, G_CALLBACK(actionViewOptions) }, - { "ShowObjectsMenu", NULL, "Show Objects", NULL, NULL, NULL }, - { "ShowGridsMenu", NULL, "Show Grids", NULL, NULL, NULL }, - { "ShowLabelsMenu", NULL, "Show Labels", NULL, NULL, NULL }, - { "ShowOrbitsMenu", NULL, "Show Orbits", NULL, NULL, NULL }, - { "InfoTextMenu", NULL, "Info Text", NULL, NULL, NULL }, - /* "Info Text" in radio actions */ - { "StarStyleMenu", NULL, "Star St_yle", NULL, NULL, NULL }, - /* "Star Style" in radio actions */ - { "AmbientLightMenu", NULL, "_Ambient Light", NULL, NULL, NULL }, - /* "Ambient Light" in radio actions */ - { "StarsMore", NULL, "_More Stars Visible", "bracketright", NULL, G_CALLBACK(actionStarsMore) }, - { "StarsFewer", NULL, "_Fewer Stars Visible", "bracketleft", NULL, G_CALLBACK(actionStarsFewer) }, - - { "WindowMenu", NULL, "_Window", NULL, NULL, NULL }, - { "ViewerSize", GTK_STOCK_ZOOM_FIT, "Set Window Size...", NULL, NULL, G_CALLBACK(actionViewerSize) }, + GtkActionEntry{ "OptionsMenu", nullptr, "_Options", nullptr, nullptr, nullptr }, + GtkActionEntry{ "ViewOptions", GTK_STOCK_PREFERENCES, "View _Options...", nullptr, nullptr, G_CALLBACK(actionViewOptions) }, + GtkActionEntry{ "ShowObjectsMenu", nullptr, "Show Objects", nullptr, nullptr, nullptr }, + GtkActionEntry{ "ShowGridsMenu", nullptr, "Show Grids", nullptr, nullptr, nullptr }, + GtkActionEntry{ "ShowLabelsMenu", nullptr, "Show Labels", nullptr, nullptr, nullptr }, + GtkActionEntry{ "ShowOrbitsMenu", nullptr, "Show Orbits", nullptr, nullptr, nullptr }, + GtkActionEntry{ "InfoTextMenu", nullptr, "Info Text", nullptr, nullptr, nullptr }, + /* "Info Text" in radio actions */ + GtkActionEntry{ "StarStyleMenu", nullptr, "Star St_yle", nullptr, nullptr, nullptr }, + /* "Star Style" in radio actions */ + GtkActionEntry{ "AmbientLightMenu", nullptr, "_Ambient Light", nullptr, nullptr, nullptr }, + /* "Ambient Light" in radio actions */ + GtkActionEntry{ "StarsMore", nullptr, "_More Stars Visible", "bracketright", nullptr, G_CALLBACK(actionStarsMore) }, + GtkActionEntry{ "StarsFewer", nullptr, "_Fewer Stars Visible", "bracketleft", nullptr, G_CALLBACK(actionStarsFewer) }, + + GtkActionEntry{ "WindowMenu", nullptr, "_Window", nullptr, nullptr, nullptr }, + GtkActionEntry{ "ViewerSize", GTK_STOCK_ZOOM_FIT, "Set Window Size...", nullptr, nullptr, G_CALLBACK(actionViewerSize) }, /* "Full Screen" in toggle actions */ - { "MultiSplitH", NULL, "Split _Horizontally", "R", NULL, G_CALLBACK(actionMultiSplitH) }, - { "MultiSplitV", NULL, "Split _Vertically", "U", NULL, G_CALLBACK(actionMultiSplitV) }, - { "MultiCycle", NULL, "Cycle View", "Tab", NULL, G_CALLBACK(actionMultiCycle) }, - { "MultiDelete", NULL, "_Delete Active View", "Delete", NULL, G_CALLBACK(actionMultiDelete) }, - { "MultiSingle", NULL, "_Single View", "D", NULL, G_CALLBACK(actionMultiSingle) }, + GtkActionEntry{ "MultiSplitH", nullptr, "Split _Horizontally", "R", nullptr, G_CALLBACK(actionMultiSplitH) }, + GtkActionEntry{ "MultiSplitV", nullptr, "Split _Vertically", "U", nullptr, G_CALLBACK(actionMultiSplitV) }, + GtkActionEntry{ "MultiCycle", nullptr, "Cycle View", "Tab", nullptr, G_CALLBACK(actionMultiCycle) }, + GtkActionEntry{ "MultiDelete", nullptr, "_Delete Active View", "Delete", nullptr, G_CALLBACK(actionMultiDelete) }, + GtkActionEntry{ "MultiSingle", nullptr, "_Single View", "D", nullptr, G_CALLBACK(actionMultiSingle) }, /* "Show Frames" in toggle actions */ /* "Synchronize Time" in toggle actions */ - { "HelpMenu", NULL, "_Help", NULL, NULL, NULL }, - { "HelpControls", GTK_STOCK_HELP, "_Controls", NULL, NULL, G_CALLBACK(actionHelpControls) }, + GtkActionEntry{ "HelpMenu", nullptr, "_Help", nullptr, nullptr, nullptr }, + GtkActionEntry{ "HelpControls", GTK_STOCK_HELP, "_Controls", nullptr, nullptr, G_CALLBACK(actionHelpControls) }, #if GTK_CHECK_VERSION(2, 7, 0) - { "HelpOpenGL", GTK_STOCK_INFO, "OpenGL _Info", NULL, NULL, G_CALLBACK(actionHelpOpenGL) }, + GtkActionEntry{ "HelpOpenGL", GTK_STOCK_INFO, "OpenGL _Info", nullptr, nullptr, G_CALLBACK(actionHelpOpenGL) }, #else - { "HelpOpenGL", NULL, "OpenGL _Info", NULL, NULL, G_CALLBACK(actionHelpOpenGL) }, + GtkActionEntry{ "HelpOpenGL", nullptr, "OpenGL _Info", nullptr, nullptr, G_CALLBACK(actionHelpOpenGL) }, #endif - { "HelpAbout", GTK_STOCK_ABOUT, "_About", NULL, NULL, G_CALLBACK(actionHelpAbout) }, + GtkActionEntry{ "HelpAbout", GTK_STOCK_ABOUT, "_About", nullptr, nullptr, G_CALLBACK(actionHelpAbout) }, }; - /* Regular Checkbox Actions */ -static const GtkToggleActionEntry actionsToggle[] = { - { "TimeLocal", NULL, "Show _Local Time", NULL, NULL, G_CALLBACK(actionTimeLocal), FALSE }, +const inline std::array actionsToggle +{ + GtkToggleActionEntry{ "TimeLocal", nullptr, "Show _Local Time", nullptr, nullptr, G_CALLBACK(actionTimeLocal), FALSE }, #if GTK_CHECK_VERSION(2, 7, 0) - { "FullScreen", GTK_STOCK_FULLSCREEN, "_Full Screen", "Return", NULL, G_CALLBACK(actionFullScreen), FALSE }, + GtkToggleActionEntry{ "FullScreen", GTK_STOCK_FULLSCREEN, "_Full Screen", "Return", nullptr, G_CALLBACK(actionFullScreen), FALSE }, #else - { "FullScreen", NULL, "_Full Screen", "Return", NULL, G_CALLBACK(actionFullScreen), FALSE }, + GtkToggleActionEntry{ "FullScreen", nullptr, "_Full Screen", "Return", nullptr, G_CALLBACK(actionFullScreen), FALSE }, #endif /* GTK_CHECK_VERSION */ - { "MenuBarVisible", NULL, "_Menu Bar", "M", NULL, G_CALLBACK(actionMenuBarVisible), TRUE }, - { "MultiShowFrames", NULL, "Show _Frames", NULL, NULL, G_CALLBACK(actionMultiShowFrames), FALSE }, - { "MultiShowActive", NULL, "Active Frame Highlighted", NULL, NULL, G_CALLBACK(actionMultiShowActive), FALSE }, - { "MultiSyncTime", NULL, "Synchronize _Time", NULL, NULL, G_CALLBACK(actionMultiSyncTime), FALSE }, + GtkToggleActionEntry{ "MenuBarVisible", nullptr, "_Menu Bar", "M", nullptr, G_CALLBACK(actionMenuBarVisible), TRUE }, + GtkToggleActionEntry{ "MultiShowFrames", nullptr, "Show _Frames", nullptr, nullptr, G_CALLBACK(actionMultiShowFrames), FALSE }, + GtkToggleActionEntry{ "MultiShowActive", nullptr, "Active Frame Highlighted", nullptr, nullptr, G_CALLBACK(actionMultiShowActive), FALSE }, + GtkToggleActionEntry{ "MultiSyncTime", nullptr, "Synchronize _Time", nullptr, nullptr, G_CALLBACK(actionMultiSyncTime), FALSE }, }; - /* Regular Radio Button Actions */ -static const GtkRadioActionEntry actionsVerbosity[] = { - { "HudNone", NULL, "_None", NULL, NULL, 0 }, - { "HudTerse", NULL, "_Terse", NULL, NULL, 1}, - { "HudVerbose", NULL, "_Verbose", NULL, NULL, 2}, +constexpr inline std::array actionsVerbosity +{ + GtkRadioActionEntry{ "HudNone", nullptr, "_None", nullptr, nullptr, 0 }, + GtkRadioActionEntry{ "HudTerse", nullptr, "_Terse", nullptr, nullptr, 1}, + GtkRadioActionEntry{ "HudVerbose", nullptr, "_Verbose", nullptr, nullptr, 2}, }; -static const GtkRadioActionEntry actionsStarStyle[] = { - { "StarsFuzzy", NULL, "_Fuzzy Points", NULL, NULL, Renderer::FuzzyPointStars }, - { "StarsPoints", NULL, "_Points", NULL, NULL, Renderer::PointStars }, - { "StarsDiscs", NULL, "Scaled _Discs", NULL, NULL, Renderer::ScaledDiscStars }, +constexpr inline std::array actionsStarStyle +{ + GtkRadioActionEntry{ "StarsFuzzy", nullptr, "_Fuzzy Points", nullptr, nullptr, Renderer::FuzzyPointStars }, + GtkRadioActionEntry{ "StarsPoints", nullptr, "_Points", nullptr, nullptr, Renderer::PointStars }, + GtkRadioActionEntry{ "StarsDiscs", nullptr, "Scaled _Discs", nullptr, nullptr, Renderer::ScaledDiscStars }, }; -static const GtkRadioActionEntry actionsAmbientLight[] = { - { "AmbientNone", NULL, "_None", NULL, NULL, 0 }, - { "AmbientLow", NULL, "_Low", NULL, NULL, 1 }, - { "AmbientMedium", NULL, "_Medium", NULL, NULL, 2}, +constexpr inline std::array actionsAmbientLight +{ + GtkRadioActionEntry{ "AmbientNone", nullptr, "_None", nullptr, nullptr, 0 }, + GtkRadioActionEntry{ "AmbientLow", nullptr, "_Low", nullptr, nullptr, 1 }, + GtkRadioActionEntry{ "AmbientMedium", nullptr, "_Medium", nullptr, nullptr, 2}, }; - /* Render-Flag Actions */ -static const GtkToggleActionEntry actionsRenderFlags[] = { - { "RenderAA", NULL, "Antialiasing", "X", NULL, G_CALLBACK(actionRenderAA), FALSE }, - { "RenderAtmospheres", NULL, "Atmospheres", "A", NULL, G_CALLBACK(actionRenderAtmospheres), FALSE }, - { "RenderAutoMagnitude", NULL, "Auto Magnitude", "Y", NULL, G_CALLBACK(actionRenderAutoMagnitude), FALSE }, - { "RenderClouds", NULL, "Clouds", "I", NULL, G_CALLBACK(actionRenderClouds), FALSE }, - { "RenderCometTails", NULL, "Comet Tails", "T", NULL, G_CALLBACK(actionRenderCometTails), FALSE }, - { "RenderConstellationBoundaries", NULL, "Constellation Boundaries", NULL, NULL, G_CALLBACK(actionRenderConstellationBoundaries), FALSE }, - { "RenderConstellations", NULL, "Constellations", "slash", NULL, G_CALLBACK(actionRenderConstellations), FALSE }, - { "RenderEclipseShadows", NULL, "Eclipse Shadows", "E", NULL, G_CALLBACK(actionRenderEclipseShadows), FALSE }, - { "RenderGalaxies", NULL, "Galaxies", "U", NULL, G_CALLBACK(actionRenderGalaxies), FALSE }, - { "RenderGlobulars", NULL, "Globulars", "U", NULL, G_CALLBACK(actionRenderGlobulars), FALSE }, - { "RenderCelestialGrid", NULL, "Grid: Celestial", "semicolon", NULL, G_CALLBACK(actionRenderCelestialGrid), FALSE }, - { "RenderEclipticGrid", NULL, "Grid: Ecliptic", NULL, NULL, G_CALLBACK(actionRenderEclipticGrid), FALSE }, - { "RenderGalacticGrid", NULL, "Grid: Galactic", NULL, NULL, G_CALLBACK(actionRenderGalacticGrid), FALSE }, - { "RenderHorizontalGrid", NULL, "Grid: Horizontal", NULL, NULL, G_CALLBACK(actionRenderHorizontalGrid), FALSE }, - { "RenderMarkers", NULL, "Markers", "M", NULL, G_CALLBACK(actionRenderMarkers), FALSE }, - { "RenderNebulae", NULL, "Nebulae", "asciicircum", NULL, G_CALLBACK(actionRenderNebulae), FALSE }, - { "RenderNightLights", NULL, "Night Side Lights", "L", NULL, G_CALLBACK(actionRenderNightLights), FALSE }, - { "RenderOpenClusters", NULL, "Open Clusters", NULL, NULL, G_CALLBACK(actionRenderOpenClusters), FALSE }, - { "RenderOrbits", NULL, "Orbits", "O", NULL, G_CALLBACK(actionRenderOrbits), FALSE }, - { "RenderFadingOrbits", NULL, "Fading Orbits", NULL, NULL, G_CALLBACK(actionRenderFadingOrbits), FALSE }, - { "RenderPlanets", NULL, "Planets", NULL, NULL, G_CALLBACK(actionRenderPlanets), FALSE }, - { "RenderDwarfPlanets", NULL, "Dwarf Planets", NULL, NULL, G_CALLBACK(actionRenderDwarfPlanets), FALSE }, - { "RenderMoons", NULL, "Moons", NULL, NULL, G_CALLBACK(actionRenderMoons), FALSE }, - { "RenderMinorMoons", NULL, "Minor Moons", NULL, NULL, G_CALLBACK(actionRenderMinorMoons), FALSE }, - { "RenderComets", NULL, "Comets", NULL, NULL, G_CALLBACK(actionRenderComets), FALSE }, - { "RenderAsteroids", NULL, "Asteroids", NULL, NULL, G_CALLBACK(actionRenderAsteroids), FALSE }, - { "RenderSpacecrafts", NULL, "Spacecraft", NULL, NULL, G_CALLBACK(actionRenderSpacecrafts), FALSE }, - { "RenderPlanetRings", NULL, "Planet Rings", NULL, NULL, G_CALLBACK(actionRenderPlanetRings), FALSE }, - { "RenderRingShadows", NULL, "Ring Shadows", NULL, NULL, G_CALLBACK(actionRenderRingShadows), FALSE }, - { "RenderStars", NULL, "Stars", NULL, NULL, G_CALLBACK(actionRenderStars), FALSE }, +const inline std::array actionsRenderFlags +{ + GtkToggleActionEntry{ "RenderAA", nullptr, "Antialiasing", "X", nullptr, G_CALLBACK(actionRenderAA), FALSE }, + GtkToggleActionEntry{ "RenderAtmospheres", nullptr, "Atmospheres", "A", nullptr, G_CALLBACK(actionRenderAtmospheres), FALSE }, + GtkToggleActionEntry{ "RenderAutoMagnitude", nullptr, "Auto Magnitude", "Y", nullptr, G_CALLBACK(actionRenderAutoMagnitude), FALSE }, + GtkToggleActionEntry{ "RenderClouds", nullptr, "Clouds", "I", nullptr, G_CALLBACK(actionRenderClouds), FALSE }, + GtkToggleActionEntry{ "RenderCometTails", nullptr, "Comet Tails", "T", nullptr, G_CALLBACK(actionRenderCometTails), FALSE }, + GtkToggleActionEntry{ "RenderConstellationBoundaries", nullptr, "Constellation Boundaries", nullptr, nullptr, G_CALLBACK(actionRenderConstellationBoundaries), FALSE }, + GtkToggleActionEntry{ "RenderConstellations", nullptr, "Constellations", "slash", nullptr, G_CALLBACK(actionRenderConstellations), FALSE }, + GtkToggleActionEntry{ "RenderEclipseShadows", nullptr, "Eclipse Shadows", "E", nullptr, G_CALLBACK(actionRenderEclipseShadows), FALSE }, + GtkToggleActionEntry{ "RenderGalaxies", nullptr, "Galaxies", "U", nullptr, G_CALLBACK(actionRenderGalaxies), FALSE }, + GtkToggleActionEntry{ "RenderGlobulars", nullptr, "Globulars", "U", nullptr, G_CALLBACK(actionRenderGlobulars), FALSE }, + GtkToggleActionEntry{ "RenderCelestialGrid", nullptr, "Grid: Celestial", "semicolon", nullptr, G_CALLBACK(actionRenderCelestialGrid), FALSE }, + GtkToggleActionEntry{ "RenderEclipticGrid", nullptr, "Grid: Ecliptic", nullptr, nullptr, G_CALLBACK(actionRenderEclipticGrid), FALSE }, + GtkToggleActionEntry{ "RenderGalacticGrid", nullptr, "Grid: Galactic", nullptr, nullptr, G_CALLBACK(actionRenderGalacticGrid), FALSE }, + GtkToggleActionEntry{ "RenderHorizontalGrid", nullptr, "Grid: Horizontal", nullptr, nullptr, G_CALLBACK(actionRenderHorizontalGrid), FALSE }, + GtkToggleActionEntry{ "RenderMarkers", nullptr, "Markers", "M", nullptr, G_CALLBACK(actionRenderMarkers), FALSE }, + GtkToggleActionEntry{ "RenderNebulae", nullptr, "Nebulae", "asciicircum", nullptr, G_CALLBACK(actionRenderNebulae), FALSE }, + GtkToggleActionEntry{ "RenderNightLights", nullptr, "Night Side Lights", "L", nullptr, G_CALLBACK(actionRenderNightLights), FALSE }, + GtkToggleActionEntry{ "RenderOpenClusters", nullptr, "Open Clusters", nullptr, nullptr, G_CALLBACK(actionRenderOpenClusters), FALSE }, + GtkToggleActionEntry{ "RenderOrbits", nullptr, "Orbits", "O", nullptr, G_CALLBACK(actionRenderOrbits), FALSE }, + GtkToggleActionEntry{ "RenderFadingOrbits", nullptr, "Fading Orbits", nullptr, nullptr, G_CALLBACK(actionRenderFadingOrbits), FALSE }, + GtkToggleActionEntry{ "RenderPlanets", nullptr, "Planets", nullptr, nullptr, G_CALLBACK(actionRenderPlanets), FALSE }, + GtkToggleActionEntry{ "RenderDwarfPlanets", nullptr, "Dwarf Planets", nullptr, nullptr, G_CALLBACK(actionRenderDwarfPlanets), FALSE }, + GtkToggleActionEntry{ "RenderMoons", nullptr, "Moons", nullptr, nullptr, G_CALLBACK(actionRenderMoons), FALSE }, + GtkToggleActionEntry{ "RenderMinorMoons", nullptr, "Minor Moons", nullptr, nullptr, G_CALLBACK(actionRenderMinorMoons), FALSE }, + GtkToggleActionEntry{ "RenderComets", nullptr, "Comets", nullptr, nullptr, G_CALLBACK(actionRenderComets), FALSE }, + GtkToggleActionEntry{ "RenderAsteroids", nullptr, "Asteroids", nullptr, nullptr, G_CALLBACK(actionRenderAsteroids), FALSE }, + GtkToggleActionEntry{ "RenderSpacecrafts", nullptr, "Spacecraft", nullptr, nullptr, G_CALLBACK(actionRenderSpacecrafts), FALSE }, + GtkToggleActionEntry{ "RenderPlanetRings", nullptr, "Planet Rings", nullptr, nullptr, G_CALLBACK(actionRenderPlanetRings), FALSE }, + GtkToggleActionEntry{ "RenderRingShadows", nullptr, "Ring Shadows", nullptr, nullptr, G_CALLBACK(actionRenderRingShadows), FALSE }, + GtkToggleActionEntry{ "RenderStars", nullptr, "Stars", nullptr, nullptr, G_CALLBACK(actionRenderStars), FALSE }, }; - /* Orbit-Flag Actions */ -static const GtkToggleActionEntry actionsOrbitFlags[] = { - { "OrbitAsteroids", NULL, "Asteroids", NULL, NULL, G_CALLBACK(actionOrbitAsteroids), FALSE }, - { "OrbitComets", NULL, "Comets", NULL, NULL, G_CALLBACK(actionOrbitComets), FALSE }, - { "OrbitMoons", NULL, "Moons", NULL, NULL, G_CALLBACK(actionOrbitMoons), FALSE }, - { "OrbitPlanets", NULL, "Planets", NULL, NULL, G_CALLBACK(actionOrbitPlanets), FALSE }, - { "OrbitSpacecraft", NULL, "Spacecraft", NULL, NULL, G_CALLBACK(actionOrbitSpacecraft), FALSE }, +const inline std::array actionsOrbitFlags +{ + GtkToggleActionEntry{ "OrbitAsteroids", nullptr, "Asteroids", nullptr, nullptr, G_CALLBACK(actionOrbitAsteroids), FALSE }, + GtkToggleActionEntry{ "OrbitComets", nullptr, "Comets", nullptr, nullptr, G_CALLBACK(actionOrbitComets), FALSE }, + GtkToggleActionEntry{ "OrbitMoons", nullptr, "Moons", nullptr, nullptr, G_CALLBACK(actionOrbitMoons), FALSE }, + GtkToggleActionEntry{ "OrbitPlanets", nullptr, "Planets", nullptr, nullptr, G_CALLBACK(actionOrbitPlanets), FALSE }, + GtkToggleActionEntry{ "OrbitSpacecraft", nullptr, "Spacecraft", nullptr, nullptr, G_CALLBACK(actionOrbitSpacecraft), FALSE }, }; /* Label-Flag Actions */ -static const GtkToggleActionEntry actionsLabelFlags[] = { - { "LabelAsteroids", NULL, "Asteroids", "W", NULL, G_CALLBACK(actionLabelAsteroids), FALSE }, - { "LabelComets", NULL, "Comets", "W", NULL, G_CALLBACK(actionLabelComets), FALSE }, - { "LabelConstellations", NULL, "Constellations", "equal", NULL, G_CALLBACK(actionLabelConstellations), FALSE }, - { "LabelGalaxies", NULL, "Galaxies", "E", NULL, G_CALLBACK(actionLabelGalaxies), FALSE }, - { "LabelGlobulars", NULL, "Globulars", "E", NULL, G_CALLBACK(actionLabelGlobulars), FALSE }, - { "LabelLocations", NULL, "Locations", NULL, NULL, G_CALLBACK(actionLabelLocations), FALSE }, - { "LabelMoons", NULL, "Moons", "M", NULL, G_CALLBACK(actionLabelMoons), FALSE }, - { "LabelMinorMoons", NULL, "Minor Moons", "M", NULL, G_CALLBACK(actionLabelMinorMoons), FALSE }, - { "LabelNebulae", NULL, "Nebulae", NULL, NULL, G_CALLBACK(actionLabelNebulae), FALSE }, - { "LabelOpenClusters", NULL, "Open Clusters", NULL, NULL, G_CALLBACK(actionLabelOpenClusters), FALSE }, - { "LabelPlanets", NULL, "Planets", "P", NULL, G_CALLBACK(actionLabelPlanets), FALSE }, - { "LabelDwarfPlanets", NULL, "Dwarf Planets", "P", NULL, G_CALLBACK(actionLabelDwarfPlanets), FALSE }, - { "LabelSpacecraft", NULL, "Spacecraft", "N", NULL, G_CALLBACK(actionLabelSpacecraft), FALSE }, - { "LabelStars", NULL, "Stars", "B", NULL, G_CALLBACK(actionLabelStars), FALSE }, +const inline std::array actionsLabelFlags +{ + GtkToggleActionEntry{ "LabelAsteroids", nullptr, "Asteroids", "W", nullptr, G_CALLBACK(actionLabelAsteroids), FALSE }, + GtkToggleActionEntry{ "LabelComets", nullptr, "Comets", "W", nullptr, G_CALLBACK(actionLabelComets), FALSE }, + GtkToggleActionEntry{ "LabelConstellations", nullptr, "Constellations", "equal", nullptr, G_CALLBACK(actionLabelConstellations), FALSE }, + GtkToggleActionEntry{ "LabelGalaxies", nullptr, "Galaxies", "E", nullptr, G_CALLBACK(actionLabelGalaxies), FALSE }, + GtkToggleActionEntry{ "LabelGlobulars", nullptr, "Globulars", "E", nullptr, G_CALLBACK(actionLabelGlobulars), FALSE }, + GtkToggleActionEntry{ "LabelLocations", nullptr, "Locations", nullptr, nullptr, G_CALLBACK(actionLabelLocations), FALSE }, + GtkToggleActionEntry{ "LabelMoons", nullptr, "Moons", "M", nullptr, G_CALLBACK(actionLabelMoons), FALSE }, + GtkToggleActionEntry{ "LabelMinorMoons", nullptr, "Minor Moons", "M", nullptr, G_CALLBACK(actionLabelMinorMoons), FALSE }, + GtkToggleActionEntry{ "LabelNebulae", nullptr, "Nebulae", nullptr, nullptr, G_CALLBACK(actionLabelNebulae), FALSE }, + GtkToggleActionEntry{ "LabelOpenClusters", nullptr, "Open Clusters", nullptr, nullptr, G_CALLBACK(actionLabelOpenClusters), FALSE }, + GtkToggleActionEntry{ "LabelPlanets", nullptr, "Planets", "P", nullptr, G_CALLBACK(actionLabelPlanets), FALSE }, + GtkToggleActionEntry{ "LabelDwarfPlanets", nullptr, "Dwarf Planets", "P", nullptr, G_CALLBACK(actionLabelDwarfPlanets), FALSE }, + GtkToggleActionEntry{ "LabelSpacecraft", nullptr, "Spacecraft", "N", nullptr, G_CALLBACK(actionLabelSpacecraft), FALSE }, + GtkToggleActionEntry{ "LabelStars", nullptr, "Stars", "B", nullptr, G_CALLBACK(actionLabelStars), FALSE }, /* Does not appear to do anything yet: - { "LabelsLatin", NULL, "Labels in Latin", NULL, NULL, NULL, FALSE }, + GtkToggleActionEntry{ "LabelsLatin", nullptr, "Labels in Latin", nullptr, nullptr, nullptr, FALSE }, */ }; + +} // end namespace celestia::gtk From c27b5459480781bb6c54b8c9b8a3c7393ab946d8 Mon Sep 17 00:00:00 2001 From: Levin Li Date: Mon, 19 Feb 2024 19:26:43 +0800 Subject: [PATCH 8/8] Use locale specific strto functions --- src/celcompat/charconv_impl.cpp | 15 ++++++----- src/celutil/CMakeLists.txt | 1 + src/celutil/localeutil.h | 46 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/celutil/localeutil.h diff --git a/src/celcompat/charconv_impl.cpp b/src/celcompat/charconv_impl.cpp index 215d2fd753..1dc197645a 100644 --- a/src/celcompat/charconv_impl.cpp +++ b/src/celcompat/charconv_impl.cpp @@ -18,6 +18,8 @@ #include +#include + #include "charconv_impl.h" namespace celestia::compat @@ -30,6 +32,7 @@ constexpr std::size_t inf_length = 3; constexpr std::size_t infinity_length = 8; constexpr std::size_t nan_length = 3; constexpr std::size_t hex_prefix_length = 2; +locale_t numberParsingLocale = nullptr; enum class State { @@ -167,19 +170,19 @@ write_buffer(const char* first, const char* last, chars_format fmt, char* buffer inline void parse_value(const char* start, char** end, float& value) { - value = std::strtof(start, end); + value = strtof_l(start, end, numberParsingLocale); } inline void parse_value(const char* start, char** end, double& value) { - value = std::strtod(start, end); + value = strtod_l(start, end, numberParsingLocale); } inline void parse_value(const char* start, char** end, long double& value) { - value = std::strtold(start, end); + value = strtold_l(start, end, numberParsingLocale); } template @@ -191,8 +194,9 @@ from_chars_impl(const char* first, const char* last, T& value, chars_format fmt) from_chars_result result = write_buffer(first, last, fmt, buffer, hex_prefix); if (result.ec != std::errc{}) { return result; } - const char* savedLocale = std::setlocale(LC_NUMERIC, nullptr); - std::setlocale(LC_NUMERIC, "C"); + if (numberParsingLocale == nullptr) + numberParsingLocale = newlocale(LC_NUMERIC_MASK, "C", nullptr); + errno = 0; char* end; T parsed; @@ -213,7 +217,6 @@ from_chars_impl(const char* first, const char* last, T& value, chars_format fmt) result = { first + (end - buffer), std::errc{} }; } - std::setlocale(LC_NUMERIC, savedLocale); return result; } diff --git a/src/celutil/CMakeLists.txt b/src/celutil/CMakeLists.txt index 284c2b34df..5139605819 100644 --- a/src/celutil/CMakeLists.txt +++ b/src/celutil/CMakeLists.txt @@ -18,6 +18,7 @@ set(CELUTIL_SOURCES greek.h includeicu.h intrusiveptr.h + localeutil.h logger.cpp logger.h ranges.h diff --git a/src/celutil/localeutil.h b/src/celutil/localeutil.h new file mode 100644 index 0000000000..7c70aa3ad4 --- /dev/null +++ b/src/celutil/localeutil.h @@ -0,0 +1,46 @@ +// localeutil.h +// +// Copyright (C) 2024-present, the Celestia Development Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +#pragma once + +#include // for strtod_l +#if defined __APPLE__ || defined(__FreeBSD__) +# include // for LC_NUMERIC_MASK on OS X +#endif + +#ifdef _MSC_VER +typedef _locale_t locale_t; + +enum { LC_NUMERIC_MASK = LC_NUMERIC }; + +static inline locale_t newlocale(int category_mask, const char *locale, locale_t) +{ + return _create_locale(category_mask, locale); +} + +static inline void freelocale(locale_t locale) +{ + _free_locale(locale); +} + +static inline float strtof_l(const char *nptr, char **endptr, locale_t loc) +{ + return _strtof_l(nptr, endptr, loc); +} + +static inline double strtod_l(const char *nptr, char **endptr, locale_t loc) +{ + return _strtod_l(nptr, endptr, loc); +} + +static inline long double strtold_l(const char *nptr, char **endptr, locale_t loc) +{ + return _strtold_l(nptr, endptr, loc); +} +#endif