1

I'm writing a simple calculator in GTK using Haskell and the gtk2hs bindings. I'm trying to implement a Basic/Scientific view like in windows calculator using Glade.

I've got a GTKTable of buttons, but when I try and hide some of them a blank space is left where the buttons where. To hide the buttons I'm have some code like this:

bSqrt <- xmlGetWidget xml castToButton "bSqrt"
widgetHide bSqrt

But when I hide the four buttons I want I have a gap like below on the right hand side: enter image description here

I'm new to GTK and I couldn't find layout managers like you get in java swing. Is there an easier way to do this? Can I somehow invoke the layout manager to resize the buttons for me? I haven't been able to find a method for doing this in the documentation.

Thanks in advance,

CalumMcCall
  • 1,665
  • 4
  • 24
  • 46
  • 3
    What layout manager are you using? Maybe you should paste some code and instructions for reproducing your problem. – Daniel Wagner Nov 29 '11 at 04:19
  • I'm using Glade-3. I've added some more detail above. My layout is pretty basic. VBox with a GTKTable inside it. I feel like I'm just ignorant of GTK basics. How do you re-layout buttons at runtime? is this possible in GTK? – CalumMcCall Nov 29 '11 at 20:15
  • Does `refresh` from [this answer](http://stackoverflow.com/questions/6915794/gtk2hs-request-recalculation-of-windows-size-after-removing-a-widget) work? – Daniel Wagner Nov 29 '11 at 21:48
  • it changes the window size, but it still leaves the space. This might be because the buttons are in a GTKTable inside a window, as opposed to being directly in a window in the example you linked to. I think I'll just give up on this, it's not worth the time to me at the moment. Thanks very much for all your help, I appreciate it – CalumMcCall Nov 29 '11 at 22:55
  • 1
    In that case, you probably need to remove the widgets from the table container and decrease the number of columns in the table. Without a bit more concrete code to test against, it's very difficult to answer for sure: as with other GUI code, the way to fix a problem is to poke at it until it does what you want. – Daniel Wagner Nov 29 '11 at 23:53
  • ah ok, I could just destroy the table and create a new one I guess. This is part of an assignment due soon, however this is just something I was hoping to add for fun. I can't afford to spend more time on it unfortunately, but I'll maybe have a go at trying your suggestions out this weekend, thanks again. – CalumMcCall Nov 30 '11 at 00:19

1 Answers1

1

Consider using a nested combination of HBox and VBox to achieve a table-like effect. Calling widgetHideAll on a VBox of "scientific" buttons will hide that column and refresh the display as desired.

import Control.Monad (forM_)
import Data.IORef as IORef
import qualified Graphics.UI.Gtk as Gtk

data Mode = Basic | Scientific

main = do
    Gtk.initGUI

    window <- Gtk.windowNew
    outerVbox <- Gtk.vBoxNew False 0

    -- Create a "table" of buttons as an HBox of VBoxes.
    hbox <- Gtk.hBoxNew True 5

    -- Load the "table" with dummy 'basic' buttons.
    forM_ [0..2] $ \i -> do
        vbox <- Gtk.vBoxNew False 5
        forM_ [0..2] $ \j -> do
            dummy <- Gtk.buttonNewWithLabel $ show (3*i+j :: Int)
            Gtk.boxPackStartDefaults vbox dummy
        Gtk.boxPackStartDefaults hbox vbox

    -- Load rightmost column with 'scientific' buttons.
    scibox <- Gtk.vBoxNew False 5
    forM_ [0..2] $ \j -> do
        dummy <- Gtk.buttonNewWithLabel $ "sci" ++ show (j :: Int)
        Gtk.boxPackStartDefaults scibox dummy
    Gtk.boxPackStartDefaults hbox scibox

    -- Begin in Scientific mode.
    let mode = Scientific
    modeRef <- IORef.newIORef mode

    -- Create a mode-toggling Button.
    button <- Gtk.buttonNewWithLabel $ getButtonText mode
    Gtk.on button Gtk.buttonActivated $
        toggleMode button modeRef scibox

    -- Pack the "table" and button vertically into window.
    Gtk.boxPackStartDefaults outerVbox hbox
    Gtk.boxPackStartDefaults outerVbox button
    Gtk.containerAdd window outerVbox

    -- Standard Gtk stuff.
    Gtk.onDestroy window Gtk.mainQuit
    Gtk.widgetShowAll window
    Gtk.mainGUI

getButtonText Basic = "Switch to Scientific"
getButtonText Scientific = "Switch to Basic"


toggleMode button modeRef scibox = do
    mode <- IORef.readIORef modeRef
    case mode of
        Basic -> do
            IORef.writeIORef modeRef Scientific
            Gtk.buttonSetLabel button $ getButtonText Scientific
            Gtk.widgetShowAll scibox
        Scientific -> do
            IORef.writeIORef modeRef Basic
            Gtk.buttonSetLabel button $ getButtonText Basic
            Gtk.widgetHideAll scibox
m p
  • 11
  • 2