Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Script Editor +

I've been playing around with Wx::Ruby and made a quick little editor. It's really nothing more than a basic Scintilla editor where I added "quick buttons" that allow you to create classes, modules, methods, etc. with formatting really quick like without having to copy and paste headings and such. Yes, scripters are too lazy to copy and paste! (understandable when you program thousands of lines of code like me :wink: )

Anyways, its not very advanced, or really complete, and I don't see myself doing much more work with this. It serves its purpose for me.

Features:
- Load .rb files
- Save .rb files
- Can show/hide classes/modules/methods/blocks with the left margin
- Adds headings and stuff automatically

Anyways, below is the zip of the exe. I guess I could add some screens to this as well:

SEP 1.0

Screenshots


The indention isn't perfect. I just got annoyed and threw together what I could come up with in a few seconds.

Here is the source code for it. I used Wx::Ruby to make this, and OCRA to compile it together.
Code:
#==============================================================================

# ** Script Editor Plus

#------------------------------------------------------------------------------

# SephirothSpawn

# Version 1.0

# 2010-03-01

#==============================================================================

 

#------------------------------------------------------------------------------

# * Require Rubygems & WX::Ruby

#------------------------------------------------------------------------------

require 'rubygems'

require 'wx'

 

#==============================================================================

# * Script Editor Plus

#==============================================================================

 

module SEP

  #--------------------------------------------------------------------------

  # * Frame Sizes

  #--------------------------------------------------------------------------

  List_Width   = 180

  Editor_Width = 700

  #--------------------------------------------------------------------------

  # * Constants

  #--------------------------------------------------------------------------

  Menu_New          = 1000

  Menu_Load         = 1002

  Menu_Save         = 1003

  Menu_About        = 1004

  Menu_Exit         = 1005

  Heading_Class     = 2000

  Heading_Module    = 2001

  Heading_Constants = 2002

  Heading_PIM       = 2003

  Heading_OI        = 2004

  Heading_SMeth     = 2005

  Heading_Meth      = 2006

  Attr_Reader       = 3000

  Attr_Writer       = 3001

  Attr_Accessor     = 3002

  Loop_LoopDo       = 4000

  Loop_Begin        = 4001

  Loop_While        = 4002

  Loop_Until        = 4003

  Loop_For          = 4004

  Exp_If            = 5000

  Exp_Unless        = 5001

  Exp_Case          = 5002

  #--------------------------------------------------------------------------

  # * Keywords

  #--------------------------------------------------------------------------

  Keywords = "begin break elsif module retry unless end case next return until class ensure nil self self. when def false not super while alias defined? for or then yield and do if redo true else in rescue undef"

  #--------------------------------------------------------------------------

  # * Event to Text

  #--------------------------------------------------------------------------

  Text = {}

  Text[Heading_Class] = [

    '#==============================================================================',

    '# ** %s',

    '#==============================================================================',

    '',

    'class %s',

    '',

    'end # End class %s'

  ]

  Text[Heading_Module] = [

    '#==============================================================================',

    '# ** %s',

    '#==============================================================================',

    '',

    'module %s',

    '',

    'end # End module %s'

  ]

  Text[Heading_Constants] = [

    '  #--------------------------------------------------------------------------',

    '  # * Constants',

    '  #--------------------------------------------------------------------------'

  ]

  Text[Heading_PIM] = [

    '  #--------------------------------------------------------------------------',

    '  # * Public Instance Methods',

    '  #--------------------------------------------------------------------------'

  ]

  Text[Heading_OI] = [

    '  #--------------------------------------------------------------------------',

    '  # * Object Initialization',

    '  #--------------------------------------------------------------------------',

    '  def initialize',

    '',

    '  end # End Initialization'

  ]

  Text[Heading_SMeth] = [

    '  #--------------------------------------------------------------------------',

    '  # * %s',

    '  #--------------------------------------------------------------------------',

    '  def self.%s',

    '',

    '  end # End %s'

  ]

  Text[Heading_Meth] = [

    '  #--------------------------------------------------------------------------',

    '  # * %s',

    '  #--------------------------------------------------------------------------',

    '  def %s',

    '',

    '  end # End %s'

  ]

  Text[Loop_LoopDo] = [

    'loop do',

    '  ',

    'end'

  ]

  Text[Loop_Begin] = [

    'begin',

    '  ',

    'end'

  ]

  Text[Loop_While] = [

    'while ',

    '  ',

    'end'

  ]

  Text[Loop_Until] = [

    'until  ',

    '  ',

    'end'

  ]

  Text[Loop_For] = [

    'for _ in ',

    '  ',

    'end'

  ]

  Text[Exp_If] = [

    'if ',

    '  ',

    'end'

  ]

  Text[Exp_Unless] = [

    'unless ',

    '  ',

    'end'

  ]

  Text[Exp_Case] = [

    'case ',

    'when ',

    '  ',

    'end'

  ]

  Text[Attr_Reader] = [

    '  attr_reader :',

  ]

  Text[Attr_Writer] = [

    '  attr_writer :',

  ]

  Text[Attr_Accessor] = [

    '  attr_accessor :',

  ]

end

 

#==============================================================================

# * Script Editor Plus::App

#==============================================================================

 

class SEP::App < Wx::App

  #--------------------------------------------------------------------------

  # * On Initialization

  #--------------------------------------------------------------------------

  def on_init

    SEP::Frame.new('Script Editor Plus').show

  end

end

 

#==============================================================================

# * Script Editor Plus::Frame

#==============================================================================

 

class SEP::Frame < Wx::Frame

  include SEP

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(title)

    super(nil,-1, title)

    # Setup Menu

    menuFile = Wx::Menu.new()

    menuFile.append(Menu_New,   "&New\tAlt-N",   'New Script')

    menuFile.append(Menu_Load,  "&Load\tAlt-L",  'Load Script')

    menuFile.append(Menu_Save,  "&Save\tAlt-S",  'Save Script')

    menuFile.append(Menu_About, "&About\tAlt-A", 'About')

    menuFile.append(Menu_Exit,  "E&xit\tAlt-X",  'Close Program')

    menuBar = Wx::MenuBar.new()

    menuBar.append(menuFile, "&File")

    set_menu_bar(menuBar)

    evt_menu(Menu_New)   {onNew}

    evt_menu(Menu_Load)  {onLoad}

    evt_menu(Menu_Save)  {onSave}

    evt_menu(Menu_About) {onAbout}

    evt_menu(Menu_Exit)  {onExit}

    # Setup Status Bar

    create_status_bar()

    set_status_text("Welcome to Script Editor Plus!")

    # Create Panels & Adjust Size

    @left_panel= Wx::Panel.new(self, :size => [List_Width, 768], :pos => [0, 0])

    @right_panel = Wx::Panel.new(self, :size => [Editor_Width, 768], :pos => [List_Width, 0])

    self.fit

    centre

    # Create Auto-List

    @list = SEP::List.new(@left_panel, self)

    # Create Editor

    @sci = Wx::StyledTextCtrl.new(@right_panel)

    @sci.style_set_font(Wx::STC_STYLE_DEFAULT, Wx::Font.new(10, Wx::TELETYPE, Wx::NORMAL, Wx::NORMAL))

    @sci.set_size([Editor_Width, 768])

    @sci.set_edge_mode(Wx::STC_EDGE_LINE)

    @sci.set_margin_width(0, @sci.text_width(Wx::STC_STYLE_LINENUMBER, " 9999"))

    @sci.set_tab_width(4)

    @sci.set_use_tabs(true)

    @sci.set_tab_indents(true)

    @sci.set_back_space_un_indents(true)

    @sci.set_indent(4)

    @sci.style_set_foreground(Wx::STC_STYLE_DEFAULT, Wx::BLACK)

    @sci.style_set_background(Wx::STC_STYLE_DEFAULT, Wx::WHITE)

    @sci.style_set_foreground(Wx::STC_STYLE_LINENUMBER, Wx::BLACK);

    @sci.style_set_background(Wx::STC_STYLE_LINENUMBER, Wx::WHITE)

    @sci.style_set_foreground(Wx::STC_STYLE_INDENTGUIDE, Wx::LIGHT_GREY)

    @sci.set_lexer(Wx::STC_LEX_RUBY)

    @sci.style_clear_all

    @sci.style_set_foreground(2, Wx::Colour.new(0, 100, 0))

    @sci.style_set_foreground(3, Wx::RED)

    @sci.style_set_foreground(5, Wx::BLUE)

    @sci.style_set_foreground(6, Wx::Colour.new(150, 10, 110))

    @sci.style_set_foreground(7, Wx::Colour.new(150, 10, 110))

    @sci.set_key_words(0, SEP::Keywords)

    @sci.set_property("fold","1")

    @sci.set_property("fold.compact", "0")

    @sci.set_property("fold.comment", "1")

    @sci.set_property("fold.preprocessor", "1")

    @sci.set_margin_width(1, 0)

    @sci.set_margin_type(1, Wx::STC_MARGIN_SYMBOL)

    @sci.set_margin_mask(1, Wx::STC_MASK_FOLDERS)

    @sci.set_margin_width(1, 20)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDER, Wx::STC_MARK_PLUS)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDEROPEN, Wx::STC_MARK_MINUS)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDEREND, Wx::STC_MARK_EMPTY)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDERMIDTAIL, Wx::STC_MARK_EMPTY)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDEROPENMID, Wx::STC_MARK_EMPTY)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDERSUB, Wx::STC_MARK_EMPTY)

    @sci.marker_define(Wx::STC_MARKNUM_FOLDERTAIL, Wx::STC_MARK_EMPTY)

    @sci.set_fold_flags(16)

    @sci.set_margin_sensitive(1,1)

    # Events

    evt_stc_charadded(@sci.get_id) {|evt| onCharadded(evt)}

    evt_stc_marginclick(@sci.get_id) {|evt| onMarginClick(evt)}

  end

  #--------------------------------------------------------------------------

  # * Menu: New

  #--------------------------------------------------------------------------

  def onNew

    @sci.clear_all

  end

  #--------------------------------------------------------------------------

  # * Menu: Load

  #--------------------------------------------------------------------------

  def onLoad

    dlg = Wx::FileDialog.new(self,  "Choose a file",  '.', :wildcard => '*.rb')

    if dlg.show_modal == Wx::ID_OK

      lines = IO.readlines(dlg.get_path)

      for line in lines

        @sci.add_text(line)

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Menu: Save

  #--------------------------------------------------------------------------

  def onSave

    dlg = Wx::FileDialog.new(self, "Save file as...", '.', "", '*.rb', Wx::SAVE)

    if dlg.show_modal() == Wx::ID_OK

      File.open(dlg.get_path().to_s, 'w+') do |file|

        file.write(@sci.get_text)

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Menu: About

  #--------------------------------------------------------------------------

  def onAbout

    Wx::about_box(:name => self.title, :version => "1.0", 

 

        :description => "\nCreate your scripts with Format!", :developers => ['SephirothSpawn'])

  end

  #--------------------------------------------------------------------------

  # * Menu: Exit

  #--------------------------------------------------------------------------

  def onExit

    close(true)

  end

  #--------------------------------------------------------------------------

  # * Item Activated

  #--------------------------------------------------------------------------

  def item_activated(id)

    # Get Class, Module or Method Name

    string = ''

    if [Heading_Class, Heading_Module, Heading_SMeth, Heading_Meth].include?(id)

      dlg = Wx::TextEntryDialog.new(self, 'Please Type Class/Module/Method Name', :default_value => '')

      if dlg.show_modal() == Wx::ID_OK

        string = dlg.get_value.to_s

      elsif dlg.show_modal() == Wx::ID_CANCEL

        return

      end

    end

    # Get Current Indent

    line = @sci.get_line(@sci.get_current_line)

    stripped = line.lstrip

    indent = ' ' * (line.length - stripped.length)

    # For Each Text Line

    lines = Text[id]

    for i in 0...(lines.size)

      line = lines[i]

      @sci.add_text(indent) unless i == 0

      if line.include?('%s')

        @sci.add_text(sprintf(line, string))

      else

        @sci.add_text(line)

      end

      @sci.add_text("\n")

    end

  end

  #--------------------------------------------------------------------------

  # * Event: Character Added

  #--------------------------------------------------------------------------

  def onCharadded(evt)

    chr =  evt.get_key

    curr_line = @sci.get_current_line

    if chr == 13

        if curr_line > 0

          line_ind = @sci.get_line_indentation(curr_line - 1)

          if line_ind > 0

            @sci.set_line_indentation(curr_line, line_ind)

            @sci.goto_pos(@sci.position_from_line(curr_line)+line_ind)

          end

        end

    end

  end

  #--------------------------------------------------------------------------

  # * Event: On Margin Click

  #--------------------------------------------------------------------------

  def onMarginClick(evt)

    line_num = @sci.line_from_position(evt.get_position)

    margin = evt.get_margin

    if margin == 1

      @sci.toggle_fold(line_num)

    end

  end

end

 

#==============================================================================

# * Script Editor Plus::List

#==============================================================================

 

class SEP::List < Wx::TreeCtrl

  include SEP

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(parent, frame)

    super(parent, 9999, :size => [List_Width, 600])

    @frame = frame

    @list = {}

    root = add_root('Auto-Generators')

    headings = append_item(root, 'Headings')

    attrs = append_item(root, 'Attrs')

    loops = append_item(root, 'Loops')

    exp = append_item(root, 'Expressions')

    @list[append_item(headings, 'Class')] = Heading_Class

    @list[append_item(headings, 'Module')] = Heading_Module

    @list[append_item(headings, 'Constants')] = Heading_Constants

    @list[append_item(headings, 'Public Instance Methods')] = Heading_PIM

    @list[append_item(headings, 'Object Initialization')] = Heading_OI

    @list[append_item(headings, 'Method (self.method)')] = Heading_SMeth

    @list[append_item(headings, 'Method')] = Heading_Meth

    @list[append_item(attrs, 'Reader')] = Attr_Reader

    @list[append_item(attrs, 'Writer')] = Attr_Writer

    @list[append_item(attrs, 'Accessor')] = Attr_Accessor

    @list[append_item(loops, 'Loop Do')] = Loop_LoopDo

    @list[append_item(loops, 'Begin')] = Loop_Begin

    @list[append_item(loops, 'While')] = Loop_While

    @list[append_item(loops, 'Until')] = Loop_Until

    @list[append_item(loops, 'For')] = Loop_For

    @list[append_item(exp, 'If')] = Exp_If

    @list[append_item(exp, 'Unless')] = Exp_Unless

    @list[append_item(exp, 'Case')] = Exp_Case

    expand_all

    evt_tree_sel_changed(9999) {|event| on_select(event)}

    evt_tree_item_activated(9999) {|event| on_activate(event)}    

  end

  #--------------------------------------------------------------------------

  # * On Select

  #--------------------------------------------------------------------------

  def on_select(event)

    @item = event.get_item()

  end

  #--------------------------------------------------------------------------

  # * On Activate

  #--------------------------------------------------------------------------

  def on_activate(event)

    @frame.item_activated(@list[@item]) if @list.has_key?(@item)

  end

end

 

# Run App

SEP::App.new.main_loop()

GC.start

I am not very familiar with Wx::Ruby, so I've probably screwed some areas up and coded more than what I really needed. Feel free to leave whatever comments you wish.
 
Heh, if you want to make an external script editor, there's really one thing you need for it to be worth it: an intellisense equivalent. That and a resizable editor window >.>
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top