Shape text using Pango and HarfBuzz; gives us nice ligatures and exotic scripts.
[ccbs] / bigscreen / top5chosenscreen.cpp
1 #include <cstdio>
2 #include <algorithm>
3
4 #include "resolution.h"
5 #include "top5chosenscreen.h"
6 #include "fonts.h"
7 #include "theme.h"
8
9 #define RANK_X 30
10 #define SONG_X 70
11 #define FREQUENCY_X (LOGICAL_SCREEN_WIDTH - 55)
12 #define SONG_MAX_WIDTH (LOGICAL_SCREEN_WIDTH - 190)
13
14 Top5ChosenScreen::Top5ChosenScreen(pqxx::connection &conn, unsigned tournament)
15         : conn(conn), tournament(tournament), scores_changed(conn, "scores"), valid(false)
16 {
17 }
18
19 Top5ChosenScreen::~Top5ChosenScreen()
20 {
21 }
22
23 bool Top5ChosenScreen::check_invalidated()
24 {
25         if (!valid)
26                 return true;
27         if (!scores_changed.get_flag())
28                 return false;
29         scores_changed.reset_flag();
30
31         // check that there are indeed changes, otherwise don't bother
32         std::vector<TopChosen> scores;
33         conn.perform(FetchTopChosenSongsForTournament(tournament, 5, &scores));
34
35         for (std::vector<TopChosen>::const_iterator i = scores.begin(); i != scores.end(); ++i) {
36                 if (seen_topchosen.count(*i) == 0) {
37                         valid = false;
38                         return true;
39                 }       
40         }
41         
42         return false;
43 }
44
45 void Top5ChosenScreen::draw(unsigned char *buf, unsigned width, unsigned height)
46 {
47         scores_changed.reset_flag();
48         fill_background(buf, "top5chosenscreen", width, height);
49         set_screen_size(width, height);
50
51         // fetch the top 5 chosen songs
52         std::vector<TopChosen> scores;
53         conn.perform(FetchTopChosenSongsForTournament(tournament, 5, &scores));
54
55         {
56                 unsigned width = my_draw_text("Today's top 5 chosen songs", NULL, 40.0, "mainheading");
57                 my_draw_text("Today's top 5 chosen songs", buf, 40.0, "mainheading", LOGICAL_SCREEN_WIDTH/2 - width/2, 60);
58         }
59
60         // simple headings
61         my_draw_text("Song", buf, 12.0, "columnheading", SONG_X, 100);
62         width = my_draw_text("Frequency", NULL, 12.0, "columnheading");
63         my_draw_text("Frequency", buf, 12.0, "columnheading", FREQUENCY_X - width/2, 100);
64         
65         unsigned row = 1, y = 140;
66         for (std::vector<TopChosen>::const_iterator i = scores.begin(); i != scores.end(); ++i) {
67                 std::string suffix;
68                 if (row % 2 == 1) {
69                         suffix = ".odd";
70                 } else {
71                         suffix = ".even";
72                 }
73
74                 char str[16];
75                 std::string heading_theme_element = "top5chosensongs.rowheading" + suffix;
76                 std::string songname_theme_element = "top5chosensongs.songname" + suffix;
77                 std::string frequency_theme_element = "top5chosensongs.frequency" + suffix;
78
79                 // print new entries in red
80                 if (seen_topchosen.count(*i) == 0 && seen_topchosen.size() > 0) {
81                         heading_theme_element = "top5chosensongs.freshrowheading" + suffix;
82                         songname_theme_element = "top5chosensongs.freshsongname" + suffix;
83                         frequency_theme_element = "top5chosensongs.freshfrequency" + suffix;
84                 }
85
86                 std::sprintf(str, "%u", row++);
87                 unsigned width = my_draw_text(str, NULL, 24.0, heading_theme_element);
88                 my_draw_text(str, buf, 24.0, heading_theme_element, RANK_X - width/2, y);
89
90                 if (my_draw_text(i->title, NULL, 24.0, songname_theme_element) > SONG_MAX_WIDTH) {
91                         my_draw_text(i->shorttitle, buf, 24.0, songname_theme_element, SONG_X, y);
92                 } else {
93                         my_draw_text(i->title, buf, 24.0, songname_theme_element, SONG_X, y);
94                 }
95                 
96                 std::sprintf(str, "%u", i->frequency);
97                 width = my_draw_text(str, NULL, 24.0, frequency_theme_element);
98                 my_draw_text(str, buf, 24.0, frequency_theme_element, FREQUENCY_X - width/2, y);
99
100                 y += 40;
101         }
102         
103         valid = true;
104         
105         seen_topchosen.erase(seen_topchosen.begin(), seen_topchosen.end());
106         std::copy(scores.begin(), scores.end(), std::inserter(seen_topchosen, seen_topchosen.end()));
107 }
108