Class: Studium::GUI::Gtk::VBox

Inherits:
Gtk::VBox
  • Object
show all
Includes:
Gtk::BaseModule
Defined in:
lib/studium/gui/gtk2/vbox.rb

Overview

Studium::GUI::Gtk::VBox

Constant Summary collapse

POWDERBLUE =
#

POWDERBLUE

#
Gdk::Color.parse('powderblue')
STEELBLUE =
Gdk::Color.parse('steelblue')
HIGHLIGHT_COLOUR =

Alias.

STEELBLUE
DATASET =
#

DATASET

#
::Studium::Statistics
USE_THIS_TOPIC =

Else use a default topic.

'biotech1'
LEFT_INDENT =
#

LEFT_INDENT

#
6
BORDER_WIDTH =
#

BORDER_WIDTH

#
2
SLEEP_FOR_N_SECONDS_BEFORE_REVEALING_THE_ANSWER =
#

SLEEP_FOR_N_SECONDS_BEFORE_REVEALING_THE_ANSWER

#
4
ENABLE_STATUS_BAR_NOTIFICATION =
#

ENABLE_STATUS_BAR_NOTIFICATION

#
true
APPEND_PERCENTAGE =
#

APPEND_PERCENTAGE

#
false

Instance Method Summary collapse

Constructor Details

#initialize(optional_parent = nil, run_already = true) ⇒ VBox

#

initialize

First argument should be Studium::GUI::Gtk::Frame. It will become the @parent widget then.

#


98
99
100
101
102
103
104
105
106
107
108
# File 'lib/studium/gui/gtk2/vbox.rb', line 98

def initialize(
    optional_parent = nil,
    run_already     = true
  )
  super()
  reset # First, reset everything.
  set_parent(optional_parent) if optional_parent

  show_all
  run if run_already
end

Instance Method Details

#add_buttonsObject



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/studium/gui/gtk2/vbox.rb', line 203

def add_buttons
  # ======================================================================= #
  # alt+1 asks a new question. (alt1)
  # ======================================================================= #
  @accel_group.connect( Gdk::Keyval::GDK_1, Gdk::Window::MOD1_MASK, ::Gtk::ACCEL_VISIBLE) {
    do_click_button_ask_a_new_question
  }
  @button_reveal_the_answer = gtk_button
  @button_reveal_the_answer.border_width = BORDER_WIDTH
  @button_reveal_the_answer.signal_connect(:clicked) {
    reveal_or_hide_the_answer
  }
  @button_reveal_the_answer.modify_bg(::Gtk::StateType::PRELIGHT, HIGHLIGHT_COLOUR)
  @button_reveal_the_answer.modify_background(:normal, :powderblue)
  # ======================================================================= #
  # Add a tooltip to this button:
  # ======================================================================= #
  hint = 'Press this button to show the answer to the question (Shortcut: Alt+2)'
  @button_reveal_the_answer.tooltip(hint)
  # ======================================================================= #
  # alt+2 reveals the answer. (alt2)
  # ======================================================================= #
  @accel_group.connect( Gdk::Keyval::GDK_2, Gdk::Window::MOD1_MASK, ::Gtk::ACCEL_VISIBLE) {
    @button_reveal_the_answer.signal_emit :clicked
  }
  # ======================================================================= #
  # === The Solved button and the Random Question button
  #
  # This button shares its widget-space with the random-question button.
  #
  # button_solved = Gtk::Button.new('solved')
  # ======================================================================= #
  @hbox_for_button_solved = gtk_hbox
  @button_solved = gtk_button('_Solved')
  @button_random_question = gtk_button('_Random Question')
  @button_random_question.background_colours(POWDERBLUE, HIGHLIGHT_COLOUR)
  @button_random_question.signal_connect(:clicked) {
    do_click_button_ask_a_new_question(:random_topic)
  }
  # ======================================================================= #
  # alt+3 asks a random question. (alt3)
  # ======================================================================= #
  @accel_group.connect(Gdk::Keyval::GDK_3, Gdk::Window::MOD1_MASK, ::Gtk::ACCEL_VISIBLE) {
    @button_random_question.signal_emit :clicked
  }
  @hbox_for_button_solved << @button_solved
  @hbox_for_button_solved << @button_random_question
  @button_solved.border_width = BORDER_WIDTH
  @button_solved.signal_connect(:clicked) {
    mark_question_as_solved
    update_how_many_questions_are_available
  }
  @button_solved.background_colours(POWDERBLUE, HIGHLIGHT_COLOUR)
  @button_solved.tooltip(
    'Press this button to set the "solved tag" to this question'
  )
  # ======================================================================= #
  # alt+4 sets to solved the answer. (alt4)
  # ======================================================================= #
  @accel_group.connect(Gdk::Keyval::GDK_4, Gdk::Window::MOD1_MASK, ::Gtk::ACCEL_VISIBLE) {
    @button_solved.signal_emit :clicked
  }
  @text_buffer.set_text question?
  # ======================================================================= #
  # The spin button comes next. This spin button will contain the
  # different titles for the respective topic, such as "Basic Chemistry".
  # Since as of 21.02.2016 we may also display the percentage there.
  # ======================================================================= #
  @button_spin = gtk_combo_box_entry(true) # (spin tag)
  @sanitized_topics = Studium.available_topics?
  # ======================================================================= #
  # === Append the Percentage
  #
  # Append the percentage next. Unfortunately, this breaks a bit of the
  # other functionality, so we may have to rethink this - and perhaps
  # re-enable it at a later time.
  # ======================================================================= #
  @sanitized_topics.map! {|entry|
    percentage_value = Studium::Exams.dataset[entry.to_sym]
    entry << ' ('+percentage_value.to_s+'%)'
    entry
  } if APPEND_PERCENTAGE
  # ======================================================================= #
  # === Append the title to the spin-button next
  # ======================================================================= #
  @sanitized_topics.each { |val|
    @button_spin.append_text(val)
  }
  # ======================================================================= #
  # Next, we select the active tab.
  #
  # In order to do this, we will refer to the above Array called array,
  # and try to obtain the position.
  # ======================================================================= #
  find_this_topic = USE_THIS_TOPIC # This is the default topic to use.
  # ======================================================================= #
  # This topic must be sanitized though:
  # ======================================================================= #
  find_this_topic = sanitize_topic(find_this_topic)
  index = @sanitized_topics.index(find_this_topic)
  if index.nil?
    find_this_topic = Studium.sanitize_topic(find_this_topic).first
    index = @sanitized_topics.index(find_this_topic)
  end
  if index
    @button_spin.active = index
  else # Else we default to some other entry.
    @button_spin.active = 40
  end
  @button_check.set_active(true)
  name_tip = 'If this check button is selected, then we will ask only '+
    'questions pertaining to the topic at hand (the entry to the left '+
    'side of this check button).'
  @button_check.tooltip(name_tip)
  # ======================================================================= #
  # Next, add the quit-botton.
  # ======================================================================= #
  @button_quit = gtk_button(::Gtk::Stock::QUIT)
  @button_quit.signal_connect_after(:clicked) { ::Gtk.main_quit }
  # ======================================================================= #
  # Next, the VBox will have three buttons.
  # ======================================================================= #
  vbox = gtk_vbox
  vbox.pack_start(@button_new_question,      false, true, 0)
  vbox.pack_start(@button_reveal_the_answer, false, true, 0)
  # ======================================================================= #
  # === Add the @button_solved hbox
  # ======================================================================= #
  vbox.pack_start(@hbox_for_button_solved,   false, true, 0)
  # ======================================================================= #
  # And the quit-button will come next.
  # ======================================================================= #
  hbox_for_four_buttons = gtk_hbox
  hbox_for_four_buttons.add(vbox)
  hbox_for_four_buttons.pack_start(@button_quit, false, false, 0)
  pack_start(hbox_for_four_buttons,              false, true,  0)
  # ======================================================================= #
  # The next box contains the spin-button to the left, and the
  # check-button to the right.
  # ======================================================================= #
  hbox = gtk_hbox
  hbox.pack_start(@button_spin,  true,  true, 0)
  hbox.pack_start(@button_check, false, true, 0)
  pack_start(hbox,               false, true, 0)
  @entry_search_for_proper_topic = gtk_entry('')
  @entry_search_for_proper_topic.signal_connect(:button_press_event) { |widget, event|
    @entry_search_for_proper_topic.set_focus(true)
    @entry_search_for_proper_topic.select_region(0, -1)
  }
  add_entry_search_for_proper_topic_and_button_on_the_right_side
end

#add_entry_search_for_proper_topic_and_button_on_the_right_sideObject

#

add_entry_search_for_proper_topic_and_button_on_the_right_side

#


358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/studium/gui/gtk2/vbox.rb', line 358

def add_entry_search_for_proper_topic_and_button_on_the_right_side
  hbox = gtk_hbox
  hbox.pack_start(@entry_search_for_proper_topic, true, true, 0)
  @entry_search_for_proper_topic.signal_connect(:key_press_event) { |w, event|
    if ::Gtk.enter_key?(event)
      @button_set_proper_topic.signal_emit(:clicked)
    end
  }
  # ======================================================================= #
  # Next the button on the right hand side. The purpose of this button
  # is to set the proper topic.
  # ======================================================================= #
  @button_set_proper_topic = gtk_button('Set proper topic')
  @button_set_proper_topic.signal_connect(:clicked) {
    do_set_the_proper_topic
    # ===================================================================== #
    # Also trigger the new-question button next.
    # ===================================================================== #
    @button_new_question.signal_emit(:clicked)
  }
  @button_set_proper_topic.tooltip('Press this button to set a new topic')
  hbox.pack_start(@button_set_proper_topic, false, true,0)
  pack_start(hbox, false, true, 0)
end

#add_status_iconObject

#

add_status_icon

#


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/studium/gui/gtk2/vbox.rb', line 177

def add_status_icon
  title           = Studium::GUI::Gtk.title? #
  icon_name       = ::Gtk::Stock::DIALOG_INFO
  tooltip         = Studium::GUI::Gtk.title?
  pixbuf_location = Studium::GUI::Gtk.favicon?
  @status_icon = ::Gtk.create_status_icon(
    title, icon_name, tooltip, pixbuf_location
  )
  # ======================================================================= #
  # Next, we add a small popup-window to the status icon.
  # ======================================================================= #
  info = ::Gtk.image_menu_item_info
  quit = ::Gtk::ImageMenuItem.new(::Gtk::Stock::QUIT) # quit button.
  quit.signal_connect(:activate){ gtk_main_quit }
  menu = ::Gtk::Menu.new # Here comes the Gtk Menu.
  menu.append(::Gtk::SeparatorMenuItem.new)
  menu.append(info)
  menu.append(::Gtk::SeparatorMenuItem.new)
  menu.append(quit)
  menu.show_all
  # Show menu on right click.
  @status_icon.signal_connect(:popup_menu) {|tray, button, time|
    menu.popup(nil, nil, button, time)
  }
end

#check_status_of_check_buttonObject

#

check_status_of_check_button

This will either return the currently selected topic, or it will use the Symbol :random_topic, so that we can fetch a random topic.

#


396
397
398
399
400
401
402
# File 'lib/studium/gui/gtk2/vbox.rb', line 396

def check_status_of_check_button
  if @button_check.active?
    obtain_currently_selected_topic 
  else # else we fetch a random topic.
    :random_topic
  end
end

#do_click_button_ask_a_new_question(i = check_status_of_check_button) ⇒ Object Also known as: click_main_button

#

do_click_button_ask_a_new_question

This method collects what we will do when we ask a new question.

This is the prominent button called “New Question”.

#


411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/studium/gui/gtk2/vbox.rb', line 411

def do_click_button_ask_a_new_question(i = check_status_of_check_button)
  fetch_new_question(i)
  change_header_for_first_tab(topic?)
  change_header_for_second_tab
  set_topic_for_button_reveal_the_answer '_Reveal the answer'
  # ======================================================================= #
  # Next, we check if the parent widget has selected the check
  # button to be true. If this is the case, then we will reveal
  # the answer after a delay of 6 seconds.
  # ======================================================================= #
  if parent?.check_button_reveal_answer_after_a_delay?.active? # Means checkbutton is active.
    Thread.new {
      sleep SLEEP_FOR_N_SECONDS_BEFORE_REVEALING_THE_ANSWER
      reveal_the_answer
    }
  end
  if ENABLE_STATUS_BAR_NOTIFICATION
    @status_bar.push(@status_bar_context_id, 'Thema: '+topic?)
  end 
end

#fetch_new_question(i = :random_topic) ⇒ Object

#

fetch_new_question

Use this method to fetch a question.

Either we fetch a random topic, which is the default.

Or we fetch the entry that is given to us via the spinbutton entry.

#


441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/studium/gui/gtk2/vbox.rb', line 441

def fetch_new_question(i = :random_topic)
  case i
  when :random_topic
    i = ::Studium.available_topics_as_short_names.sample
  end
  i = i.to_s unless i.is_a? String
  unless i.encoding.to_s == USE_THIS_ENCODING
    i = i.force_encoding(Studium.encoding?)
  end
  @n_questions_in_total = ::Studium.return_n_questions_in_this_topic(i)
  @n_questions_answered = ::Studium.return_n_questions_were_answered_for_this_topic(i)
  # ======================================================================= #
  # Next, we need to determine the question, the answer, and the
  # topic at hand. The topic is easy so we start with it.
  # ======================================================================= #
  topic = ::Studium.beautiful_topic(i)
  set_topic(topic)
  # ======================================================================= #
  # Now, we must determine the question and the answer.
  # ======================================================================= #
  dataset = File.readlines(DIRECTORY_EXAM_TOPICS+File.basename(i))
  dataset = ::Studium.filter_away_invalid_questions(dataset)
  dataset.reject! {|entry| entry.end_with?('[]'+N) }
  line = dataset.sample
  question_answer = Exams.question_answer(line)
  set_question(question_answer.question?)
  set_answer(question_answer.answer?)
  show_the_question # The question will be shown in a GTK widget here.
end

#hide_the_answerObject

#

hide_the_answer

#


148
149
150
151
# File 'lib/studium/gui/gtk2/vbox.rb', line 148

def hide_the_answer
  _ = question?
  @text_buffer.set_text _
end

#n_questions_in_total?Boolean

#

n_questions_in_total?

#

Returns:

  • (Boolean)


124
125
126
# File 'lib/studium/gui/gtk2/vbox.rb', line 124

def n_questions_in_total?
  @n_questions_in_total
end

#return_status_bar_notificationObject

#

return_status_bar_notification

#


114
115
116
117
118
119
# File 'lib/studium/gui/gtk2/vbox.rb', line 114

def return_status_bar_notification
  @status_bar = gtk_statusbar
  @status_bar.has_resize_grip = true
  @status_bar_context_id = @status_bar.get_context_id('Exams')
  return @status_bar
end

#reveal_or_hide_the_answerObject

#

reveal_or_hide_the_answer

#


156
157
158
159
160
161
162
163
164
# File 'lib/studium/gui/gtk2/vbox.rb', line 156

def reveal_or_hide_the_answer
  if @text_buffer.text.size > question?.size+1
    hide_the_answer
    set_topic_for_button_reveal_the_answer '_Reveal the answer'
  else
    reveal_the_answer
    set_topic_for_button_reveal_the_answer '_Hide the answer'
  end
end

#reveal_the_answerObject

#

reveal_the_answer

#


169
170
171
172
# File 'lib/studium/gui/gtk2/vbox.rb', line 169

def reveal_the_answer
  _ = question?+N+answer?
  @text_buffer.set_text _
end

#runObject

#

run

#


474
475
476
477
478
479
480
481
# File 'lib/studium/gui/gtk2/vbox.rb', line 474

def run
  # ======================================================================= #
  # Whether to enable status-bar notifications or whether we don't.
  # ======================================================================= #
  if ENABLE_STATUS_BAR_NOTIFICATION
    pack_start(return_status_bar_notification, false, false, 0)
  end
end

#set_answer(i) ⇒ Object

#

set_answer

#


386
387
388
# File 'lib/studium/gui/gtk2/vbox.rb', line 386

def set_answer(i)
  @answer = i
end

#set_topic(i) ⇒ Object

#

set_topic

#


131
132
133
# File 'lib/studium/gui/gtk2/vbox.rb', line 131

def set_topic(i)
  @topic = i # Simply assign to the @topic variable.
end

#set_topic_for_button_reveal_the_answer(i = '_Reveal the answer') ⇒ Object

#

set_topic_for_button_reveal_the_answer

#


138
139
140
141
142
143
# File 'lib/studium/gui/gtk2/vbox.rb', line 138

def set_topic_for_button_reveal_the_answer(
    i = '_Reveal the answer'
  )
  @button_reveal_the_answer.label = i
  @button_reveal_the_answer.use_underline = true
end