Commit 8238ff70 authored by Felix Häcker's avatar Felix Häcker

Some UI improvements; Implement 'best fit' zoom mode

parent 471b33ef
......@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkPopoverMenu" id="connection_menu_popover">
<object class="GtkPopoverMenu" id="connection_popover">
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
......@@ -10,6 +10,67 @@
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRadioButton" id="view_optiscale">
<property name="label" translatable="yes">Best fit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="view_best_fit_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="view_fit_to_window">
<property name="label" translatable="yes">Fit to window</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">view_optiscale</property>
<signal name="clicked" handler="view_fit_window_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="view_original_size">
<property name="label" translatable="yes">Original size</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">view_optiscale</property>
<signal name="clicked" handler="view_original_size_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="view_only_checkbutton">
<property name="label" translatable="yes">View-Only mode</property>
......@@ -17,12 +78,23 @@
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="view_only_checkbutton_clicked" swapped="no"/>
<signal name="clicked" handler="view_only_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
......@@ -36,13 +108,12 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="submenu">main</property>
<property name="position">1</property>
</packing>
</child>
</object>
......@@ -222,111 +293,6 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="toggle_fullscreen_button">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-fullscreen-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButtonBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">expand</property>
<child>
<object class="GtkRadioButton" id="zoom_fit_window_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Fit window</property>
<property name="active">True</property>
<property name="draw_indicator">False</property>
<signal name="clicked" handler="zoom_fit_window_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">zoom-in-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="zoom_best_fit_button">
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Best fit</property>
<property name="active">True</property>
<property name="draw_indicator">False</property>
<property name="group">zoom_fit_window_button</property>
<signal name="clicked" handler="zoom_best_fit_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">zoom-fit-best-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="zoom_original_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Original Size</property>
<property name="active">True</property>
<property name="draw_indicator">False</property>
<property name="group">zoom_fit_window_button</property>
<signal name="clicked" handler="zoom_original_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">zoom-original-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="send_keyboardshortcut_button">
<property name="visible">True</property>
......@@ -355,12 +321,12 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="popover">connection_menu_popover</property>
<property name="popover">connection_popover</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">open-menu-symbolic</property>
<property name="icon_name">view-more-symbolic</property>
</object>
</child>
<style>
......@@ -487,4 +453,10 @@
</object>
</child>
</template>
<object class="GtkPopover" id="view_popover">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
</interface>
......@@ -47,6 +47,7 @@ public class Remotely.VncBox : Box {
public string host;
public string port;
private ZoomMode zoom_mode;
public VncBox (string host, string port) {
this.name = host;
......@@ -92,6 +93,9 @@ public class Remotely.VncBox : Box {
show_notification("Authentication is not supported");
connection_stack.set_visible_child_name("error");
});
this.size_allocate.connect(() => {
update_zoom_mode();
});
}
private void connect_to_client(){
......@@ -113,32 +117,51 @@ public class Remotely.VncBox : Box {
}
public void set_zoom_mode(ZoomMode mode){
switch(mode){
zoom_mode = mode;
update_zoom_mode();
}
public ZoomMode get_zoom_mode(){
return zoom_mode;
}
private void update_zoom_mode(){
// Set defaults
display.expand = false;
display.set_scaling(false);
scrolled_window.hscrollbar_policy = PolicyType.ALWAYS;
scrolled_window.vscrollbar_policy = PolicyType.ALWAYS;
vnc_box.set_halign(Gtk.Align.FILL);
vnc_box.set_valign(Gtk.Align.FILL);
switch(zoom_mode){
case ZoomMode.FIT_WINDOW: {
display.expand=true;
scrolled_window.hscrollbar_policy = PolicyType.NEVER;
scrolled_window.vscrollbar_policy = PolicyType.NEVER;
display.expand = true;
display.set_scaling(true);
display.height_request = 0;
display.width_request = 0;
scrolled_window.hscrollbar_policy = PolicyType.NEVER;
scrolled_window.vscrollbar_policy = PolicyType.NEVER;
break;
}
case ZoomMode.BEST_FIT: {
display.expand=false;
display.set_scaling(true);
//display.height_request = vnc_box.get_allocated_heigth();
//display.width_request = vnc_box.get_allocated_heigth();
scrolled_window.hscrollbar_policy = PolicyType.NEVER;
scrolled_window.vscrollbar_policy = PolicyType.NEVER;
int new_width;
int new_height;
optiscale(this.get_allocated_width(), this.get_allocated_height(), display.width, display.height, out new_width, out new_height);
display.width_request = new_width;
display.height_request = new_height;
vnc_box.set_halign(Gtk.Align.CENTER);
vnc_box.set_valign(Gtk.Align.CENTER);
break;
}
case ZoomMode.ORIGINAL_SIZE: {
display.expand=false;
display.set_scaling(false);
display.height_request = display.height;
display.width_request = display.width;
scrolled_window.hscrollbar_policy = PolicyType.ALWAYS;
scrolled_window.vscrollbar_policy = PolicyType.ALWAYS;
break;
}
}
......@@ -196,7 +219,24 @@ public class Remotely.VncBox : Box {
display.set_credential(DisplayCredential.CLIENTNAME, clientname_entry.get_text());
}
private void optiscale(int box_width, int box_heigth, int image_width, int image_heigth, out int newwidth, out int newheigth){
private void optiscale(int box_width, int box_height, int image_width, int image_height, out int new_width, out int new_height){
new_width = image_width;
new_height = image_height;
// first check if we need to scale width
if (image_width > box_width) {
//scale width to fit
new_width = box_width;
//scale height to maintain aspect ratio
new_height = (new_width * image_height) / image_width;
}
// then check if we need to scale even with the new height
if (new_height > box_height) {
//scale height to fit instead
new_height = box_height;
//scale width to maintain aspect ratio
new_width = (new_height * image_width) / image_height;
}
}
}
......@@ -31,6 +31,10 @@ public class Remotely.Window : Gtk.ApplicationWindow {
[GtkChild] Stack vnc_stack;
[GtkChild] HeaderBar header_bar;
[GtkChild] RadioButton view_original_size;
[GtkChild] RadioButton view_fit_to_window;
[GtkChild] RadioButton view_optiscale;
public Window (Gtk.Application app) {
Object (application: app);
......@@ -39,6 +43,11 @@ public class Remotely.Window : Gtk.ApplicationWindow {
vnc_notebook.switch_page.connect((page, num) => {
VncBox cbox = (VncBox)page;
header_bar.set_subtitle("%s:%s".printf(cbox.host, cbox.port));
switch(cbox.get_zoom_mode()){
case ZoomMode.BEST_FIT: view_optiscale.set_active(true); break;
case ZoomMode.FIT_WINDOW: view_fit_to_window.set_active(true); break;
case ZoomMode.ORIGINAL_SIZE: view_original_size.set_active(true); break;
}
});
}
......@@ -49,6 +58,7 @@ public class Remotely.Window : Gtk.ApplicationWindow {
if(int.parse(connection[1]) < 5900) connection[1] = (int.parse(connection[1])+5900).to_string();
VncBox cbox = new VncBox(connection[0],connection[1]);
cbox.set_zoom_mode(ZoomMode.BEST_FIT);
Gtk.Box titlebox = new Gtk.Box(Orientation.HORIZONTAL,0);
Gtk.Label title = new Gtk.Label (connect_entry.get_text());
......@@ -77,22 +87,22 @@ public class Remotely.Window : Gtk.ApplicationWindow {
}
[GtkCallback]
private void zoom_fit_window_button_clicked(){
get_current_vnc_box().set_zoom_mode(ZoomMode.FIT_WINDOW);
private void view_best_fit_button_clicked(){
get_current_vnc_box().set_zoom_mode(ZoomMode.BEST_FIT);
}
[GtkCallback]
private void zoom_best_fit_button_clicked(){
get_current_vnc_box().set_zoom_mode(ZoomMode.BEST_FIT);
private void view_fit_window_button_clicked(){
get_current_vnc_box().set_zoom_mode(ZoomMode.FIT_WINDOW);
}
[GtkCallback]
private void zoom_original_button_clicked(){
private void view_original_size_button_clicked(){
get_current_vnc_box().set_zoom_mode(ZoomMode.ORIGINAL_SIZE);
}
[GtkCallback]
private void view_only_checkbutton_clicked(){
private void view_only_button_clicked(){
get_current_vnc_box().set_view_only(view_only_checkbutton.active);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment