src/Pure/System/gui.scala
changeset 51619 95b7da3430d4
child 53452 8181bc357dc4
equal deleted inserted replaced
51618:a3577cd80c41 51619:95b7da3430d4
       
     1 /*  Title:      Pure/System/gui.scala
       
     2     Author:     Makarius
       
     3 
       
     4 Elementary GUI tools.
       
     5 */
       
     6 
       
     7 package isabelle
       
     8 
       
     9 
       
    10 import java.awt.{Image, Component, Toolkit}
       
    11 import javax.swing.{ImageIcon, JOptionPane, UIManager}
       
    12 
       
    13 import scala.swing.{ComboBox, TextArea, ScrollPane}
       
    14 import scala.swing.event.SelectionChanged
       
    15 
       
    16 
       
    17 object GUI
       
    18 {
       
    19   /* Swing look-and-feel */
       
    20 
       
    21   def get_laf(): String =
       
    22   {
       
    23     def laf(name: String): Option[String] =
       
    24       UIManager.getInstalledLookAndFeels().find(_.getName == name).map(_.getClassName)
       
    25 
       
    26     if (Platform.is_windows || Platform.is_macos)
       
    27       UIManager.getSystemLookAndFeelClassName()
       
    28     else
       
    29       laf("Nimbus") orElse laf("GTK+") getOrElse
       
    30         UIManager.getCrossPlatformLookAndFeelClassName()
       
    31   }
       
    32 
       
    33   def init_laf(): Unit = UIManager.setLookAndFeel(get_laf())
       
    34 
       
    35 
       
    36   /* simple dialogs */
       
    37 
       
    38   def scrollable_text(txt: String, width: Int = 60, editable: Boolean = false): ScrollPane =
       
    39   {
       
    40     val text = new TextArea(txt)
       
    41     if (width > 0) text.columns = width
       
    42     text.editable = editable
       
    43     new ScrollPane(text)
       
    44   }
       
    45 
       
    46   private def simple_dialog(kind: Int, default_title: String,
       
    47     parent: Component, title: String, message: Seq[Any])
       
    48   {
       
    49     Swing_Thread.now {
       
    50       val java_message = message map { case x: scala.swing.Component => x.peer case x => x }
       
    51       JOptionPane.showMessageDialog(parent,
       
    52         java_message.toArray.asInstanceOf[Array[AnyRef]],
       
    53         if (title == null) default_title else title, kind)
       
    54     }
       
    55   }
       
    56 
       
    57   def dialog(parent: Component, title: String, message: Any*) =
       
    58     simple_dialog(JOptionPane.PLAIN_MESSAGE, null, parent, title, message)
       
    59 
       
    60   def warning_dialog(parent: Component, title: String, message: Any*) =
       
    61     simple_dialog(JOptionPane.WARNING_MESSAGE, "Warning", parent, title, message)
       
    62 
       
    63   def error_dialog(parent: Component, title: String, message: Any*) =
       
    64     simple_dialog(JOptionPane.ERROR_MESSAGE, "Error", parent, title, message)
       
    65 
       
    66   def confirm_dialog(parent: Component, title: String, option_type: Int, message: Any*): Int =
       
    67     Swing_Thread.now {
       
    68       val java_message = message map { case x: scala.swing.Component => x.peer case x => x }
       
    69       JOptionPane.showConfirmDialog(parent,
       
    70         java_message.toArray.asInstanceOf[Array[AnyRef]], title,
       
    71           option_type, JOptionPane.QUESTION_MESSAGE)
       
    72     }
       
    73 
       
    74 
       
    75   /* zoom box */
       
    76 
       
    77   class Zoom_Box(apply_factor: Int => Unit) extends ComboBox[String](
       
    78     List("50%", "70%", "85%", "100%", "125%", "150%", "175%", "200%", "300%", "400%"))
       
    79   {
       
    80     val Factor = "([0-9]+)%?".r
       
    81     def parse(text: String): Int =
       
    82       text match {
       
    83         case Factor(s) =>
       
    84           val i = Integer.parseInt(s)
       
    85           if (10 <= i && i <= 1000) i else 100
       
    86         case _ => 100
       
    87       }
       
    88 
       
    89     def print(i: Int): String = i.toString + "%"
       
    90 
       
    91     def set_item(i: Int) {
       
    92       peer.getEditor match {
       
    93         case null =>
       
    94         case editor => editor.setItem(print(i))
       
    95       }
       
    96     }
       
    97 
       
    98     makeEditable()(c => new ComboBox.BuiltInEditor(c)(text => print(parse(text)), x => x))
       
    99     reactions += {
       
   100       case SelectionChanged(_) => apply_factor(parse(selection.item))
       
   101     }
       
   102     listenTo(selection)
       
   103     selection.index = 3
       
   104     prototypeDisplayValue = Some("00000%")
       
   105   }
       
   106 
       
   107 
       
   108   /* screen resolution */
       
   109 
       
   110   def resolution_scale(): Double = Toolkit.getDefaultToolkit.getScreenResolution.toDouble / 72
       
   111   def resolution_scale(i: Int): Int = (i.toDouble * resolution_scale()).round.toInt
       
   112 
       
   113 
       
   114   /* icon */
       
   115 
       
   116   def isabelle_icon(): ImageIcon =
       
   117     new ImageIcon(Isabelle_System.platform_path(Path.explode("~~/lib/logo/isabelle.gif")))
       
   118 
       
   119   def isabelle_image(): Image = isabelle_icon().getImage
       
   120 }
       
   121