Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions vncviewer/ServerDialog.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ ServerDialog::ServerDialog()

serverName = new Fl_Input_Choice(LBLLEFT(x, y, w() - OUTER_MARGIN*2,
INPUT_HEIGHT, _("VNC server:")));
// Bug fix for wrong background
serverName->color(FL_BACKGROUND2_COLOR);
y += INPUT_HEIGHT + INNER_MARGIN;

x2 = x;
Expand Down
5 changes: 2 additions & 3 deletions vncviewer/fltk/Fl_Monitor_Arrangement.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ static const Fl_Boxtype FL_CHECKERED_BOX = FL_FREE_BOXTYPE;
Fl_Monitor_Arrangement::Fl_Monitor_Arrangement(
int x, int y, int w, int h)
: Fl_Group(x, y, w, h),
SELECTION_COLOR(fl_lighter(FL_BLUE)),
AVAILABLE_COLOR(fl_lighter(fl_lighter(fl_lighter(FL_BACKGROUND_COLOR))))
{
// Used for required monitors.
Expand Down Expand Up @@ -124,11 +123,11 @@ void Fl_Monitor_Arrangement::draw()

if (is_required(iter->first)) {
monitor->box(FL_CHECKERED_BOX);
monitor->color(SELECTION_COLOR);
monitor->color(FL_SELECTION_COLOR);
} else {
monitor->box(FL_BORDER_BOX);
monitor->color(AVAILABLE_COLOR);
monitor->selection_color(SELECTION_COLOR);
monitor->selection_color(FL_SELECTION_COLOR);
}
}

Expand Down
1 change: 0 additions & 1 deletion vncviewer/fltk/Fl_Monitor_Arrangement.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class Fl_Monitor_Arrangement: public Fl_Group {
virtual void draw();

private:
const Fl_Color SELECTION_COLOR;
const Fl_Color AVAILABLE_COLOR;
typedef std::map<int, Fl_Button *> MonitorMap;
MonitorMap monitors;
Expand Down
254 changes: 244 additions & 10 deletions vncviewer/fltk/theme.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,186 @@
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_ask.H>
#include <FL/fl_draw.H>

#include "theme.h"

const int RADIUS = 4;

/*
* fl_arc() and fl_pie() are broken on Windows, so we need to fudge the
* numbers a bit
*/
#ifdef WIN32
static void fixed_arc(int x,int y,int w,int h,double a1,double a2) {
if ((a1 != 0.0) || (a2 != 360.0)) {
a1 -= 10.0;
a2 += 10.0;
}
fl_arc(x, y, w, h, a1, a2);
}

static void fixed_pie(int x,int y,int w,int h,double a1,double a2) {
if ((a1 != 0.0) || (a2 != 360.0)) {
a1 -= 10.0;
a2 += 10.0;
}
fl_pie(x, y, w, h, a1, a2);
}

#define fl_arc fixed_arc
#define fl_pie fixed_pie
#endif

static Fl_Color light_border(Fl_Color c)
{
return fl_color_average(FL_BLACK, c, 0.12);
}

static Fl_Color dark_border(Fl_Color c)
{
return fl_color_average(FL_BLACK, c, 0.33);
}

static void theme_round_frame(bool up, int x, int y, int w, int h,
int r, Fl_Color c)
{
if (r > h/2)
r = h/2;

// Top
if (up)
Fl::set_box_color(light_border(c));
else
Fl::set_box_color(dark_border(c));

fl_xyline(x+r, y, x+w-r-1);

// Top corners
if (!up)
Fl::set_box_color(fl_color_average(light_border(c), dark_border(c), 0.5));

fl_arc(x, y, r*2, r*2, 90.0, 180.0);
fl_arc(x+w-(r*2), y, r*2, r*2, 0, 90.0);

// Left and right
Fl::set_box_color(light_border(c));

fl_yxline(x, y+r, y+h-r-1);
fl_yxline(x+w-1, y+r, y+h-r-1);

// Bottom corners
if (up)
Fl::set_box_color(fl_color_average(light_border(c), dark_border(c), 0.5));

fl_arc(x, y+h-(r*2), r*2, r*2, 180, 270.0);
fl_arc(x+w-(r*2), y+h-(r*2), r*2, r*2, 270, 360.0);

// Bottom
if (up)
Fl::set_box_color(dark_border(c));
else
Fl::set_box_color(light_border(c));

fl_xyline(x+r, y+h-1, x+w-r-1);
}

static void theme_up_frame(int x, int y, int w, int h, Fl_Color c)
{
theme_round_frame(true, x, y, w, h, RADIUS, c);
}

static void theme_down_frame(int x, int y, int w, int h, Fl_Color c)
{
theme_round_frame(false, x, y, w, h, RADIUS, c);
}

static void theme_round_rect(int x, int y, int w, int h, int r,
Fl_Color c, Fl_Color c2=-1)
{
if (r > h/2)
r = h/2;

if (c2 == (Fl_Color)-1)
c2 = c;

// Top
Fl::set_box_color(c);

fl_pie(x, y, r*2, r*2, 90.0, 180.0);
fl_rectf(x+r, y, w-(r*2), r);
fl_pie(x+w-(r*2), y, r*2, r*2, 0, 90.0);

// Middle
const int steps = h - r*2;
for (int i = 0; i < steps; i++) {
Fl::set_box_color(fl_color_average(c2, c, (double)i/steps));
fl_xyline(x, y+r+i, x+w-1);
}

// Bottom
Fl::set_box_color(c2);

fl_pie(x, y+h-(r*2), r*2, r*2, 180, 270.0);
fl_rectf(x+r, y+h-r, w-(r*2), r);
fl_pie(x+w-(r*2), y+h-(r*2), r*2, r*2, 270, 360.0);
}

static void theme_up_box(int x, int y, int w, int h, Fl_Color c)
{
theme_round_rect(x, y, w, h, RADIUS,
fl_color_average(FL_WHITE, c, 0.75));
theme_up_frame(x, y, w, h, c);
}

static void theme_down_box(int x, int y, int w, int h, Fl_Color c)
{
theme_round_rect(x, y, w, h, RADIUS, c);
theme_down_frame(x, y, w, h, c);
}

static void theme_thin_up_box(int x, int y, int w, int h, Fl_Color c)
{
theme_round_rect(x, y, w, h, RADIUS, c);
theme_up_frame(x, y, w, h, c);
}

static void theme_thin_down_box(int x, int y, int w, int h, Fl_Color c)
{
theme_round_rect(x, y, w, h, RADIUS, c);
theme_down_frame(x, y, w, h, c);
}

static void theme_round_up_box(int x, int y, int w, int h, Fl_Color c)
{
// Background
Fl::set_box_color(c);
fl_pie(x, y, w, h, 0.0, 360.0);

// Outline
Fl::set_box_color(light_border(c));
fl_arc(x, y, w, h, 0.0, 180.0);
Fl::set_box_color(dark_border(c));
fl_arc(x, y, w, h, 180.0, 360.0);
Fl::set_box_color(fl_color_average(light_border(c), dark_border(c), 0.5));
fl_arc(x, y, w, h, 225.0, 315.0);
}

static void theme_round_down_box(int x, int y, int w, int h, Fl_Color c)
{
// Background
Fl::set_box_color(c);
fl_pie(x, y, w, h, 0.0, 360.0);

// Outline
Fl::set_box_color(fl_color_average(light_border(c), dark_border(c), 0.5));
fl_arc(x, y, w, h, 0.0, 180.0);
Fl::set_box_color(dark_border(c));
fl_arc(x, y, w, h, 45.0, 135.0);
Fl::set_box_color(light_border(c));
fl_arc(x, y, w, h, 180.0, 360.0);
}

void init_theme()
{
#if defined(WIN32) || defined(__APPLE__)
Expand All @@ -48,19 +225,76 @@ void init_theme()
// Basic text size (10pt @ 96 dpi => 13px)
FL_NORMAL_SIZE = 13;

// Select a FLTK scheme and background color that looks somewhat
// close to modern systems
Fl::scheme("gtk+");
Fl::background(220, 220, 220);
// Modern colors based on the default appearance of Windows 11,
// macOS 12 and GNOME 41

// macOS has a slightly brighter default background though
#ifdef __APPLE__
Fl::background(240, 240, 240);
// FIXME: Should get these from the system,
// Fl::get_system_colors() is unfortunately not very capable
// FIXME: Should also handle dark mode

#if defined(WIN32)
// Windows 11
Fl::foreground(26, 26, 26);
Fl::background(243, 243, 243);
#elif defined(__APPLE__)
// FIXME: Text is rendered slightly lighter than what we specify here
// for some odd reason. The target is (38, 38, 38).
Fl::foreground(28, 28, 28);
Fl::background(246, 246, 246);
#else
// GNOME
Fl::foreground(46, 52, 54);
Fl::background(246, 245, 244);
#endif

// This makes the "icon" in dialogs rounded, which fits better
// with the above schemes.
fl_message_icon()->box(FL_UP_BOX);
#if defined(WIN32)
// Windows 11 default accent color
Fl::set_color(FL_SELECTION_COLOR, 0, 103, 192);
#elif defined(__APPLE__)
Fl::set_color(FL_SELECTION_COLOR, 0, 122, 255);
#else
// GNOME
Fl::set_color(FL_SELECTION_COLOR, 53, 132, 228);
#endif

// The arrow on Fl_Return_Button gets a invisible, so let's adjust it
// to compensate for our lighter buttons
Fl::set_color(FL_LIGHT3, light_border(fl_color_average(FL_WHITE, FL_BACKGROUND_COLOR, 0.5)));
Fl::set_color(FL_DARK3, dark_border(fl_color_average(FL_WHITE, FL_BACKGROUND_COLOR, 0.5)));

// We will override the box types later, but changing scheme affects
// more things than just those, so we still want to switch from the
// default
Fl::scheme("gtk+");

// Define our box types
const int PX = 2;
const int PY = 2;

Fl::set_boxtype(THEME_UP_FRAME, theme_up_frame, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_DOWN_FRAME, theme_down_frame, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_THIN_UP_FRAME, theme_up_frame, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_THIN_DOWN_FRAME, theme_down_frame, PX, PY, PX*2, PY*2);

Fl::set_boxtype(THEME_UP_BOX, theme_up_box, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_DOWN_BOX, theme_down_box, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_THIN_UP_BOX, theme_thin_up_box, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_THIN_DOWN_BOX, theme_thin_down_box, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_ROUND_UP_BOX, theme_round_up_box, PX, PY, PX*2, PY*2);
Fl::set_boxtype(THEME_ROUND_DOWN_BOX, theme_round_down_box, PX, PY, PX*2, PY*2);

// Make them the default
Fl::set_boxtype(FL_UP_FRAME, THEME_UP_FRAME);
Fl::set_boxtype(FL_DOWN_FRAME, THEME_UP_FRAME);
Fl::set_boxtype(FL_THIN_UP_FRAME, THEME_THIN_UP_FRAME);
Fl::set_boxtype(FL_THIN_DOWN_FRAME, THEME_THIN_DOWN_FRAME);

Fl::set_boxtype(FL_UP_BOX, THEME_UP_BOX);
Fl::set_boxtype(FL_DOWN_BOX, THEME_DOWN_BOX);
Fl::set_boxtype(FL_THIN_UP_BOX, THEME_THIN_UP_BOX);
Fl::set_boxtype(FL_THIN_DOWN_BOX, THEME_THIN_DOWN_BOX);
Fl::set_boxtype(_FL_ROUND_UP_BOX, THEME_ROUND_UP_BOX);
Fl::set_boxtype(_FL_ROUND_DOWN_BOX, THEME_ROUND_DOWN_BOX);

#if defined(WIN32)
NONCLIENTMETRICS metrics;
Expand Down
18 changes: 17 additions & 1 deletion vncviewer/fltk/theme.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright 2022 Pierre Ossman for Cendio AB
/* Copyright 2023 Pierre Ossman for Cendio AB
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
Expand All @@ -24,6 +24,22 @@
#ifndef __FLTK_THEME_H__
#define __FLTK_THEME_H__

#include <FL/Enumerations.H>

#define _THEME_BOX_BASE (FL_FREE_BOXTYPE+1000)

#define THEME_UP_FRAME (Fl_Boxtype)(_THEME_BOX_BASE+0)
#define THEME_DOWN_FRAME (Fl_Boxtype)(_THEME_BOX_BASE+1)
#define THEME_THIN_UP_FRAME (Fl_Boxtype)(_THEME_BOX_BASE+2)
#define THEME_THIN_DOWN_FRAME (Fl_Boxtype)(_THEME_BOX_BASE+3)

#define THEME_UP_BOX (Fl_Boxtype)(_THEME_BOX_BASE+4)
#define THEME_DOWN_BOX (Fl_Boxtype)(_THEME_BOX_BASE+5)
#define THEME_THIN_UP_BOX (Fl_Boxtype)(_THEME_BOX_BASE+6)
#define THEME_THIN_DOWN_BOX (Fl_Boxtype)(_THEME_BOX_BASE+7)
#define THEME_ROUND_UP_BOX (Fl_Boxtype)(_THEME_BOX_BASE+8)
#define THEME_ROUND_DOWN_BOX (Fl_Boxtype)(_THEME_BOX_BASE+9)

void init_theme();

#endif