Implementing more of new code editor design. Removed ThangList, EditorConfigModal, and a few other obsolete things.
BIN
app/assets/images/common/button-background-active-border.png
Normal file
After ![]() (image error) Size: 4.2 KiB |
BIN
app/assets/images/common/button-background-active.png
Normal file
After ![]() (image error) Size: 3.5 KiB |
BIN
app/assets/images/common/button-background-disabled-border.png
Normal file
After ![]() (image error) Size: 3.7 KiB |
BIN
app/assets/images/common/button-background-disabled.png
Normal file
After ![]() (image error) Size: 3.1 KiB |
BIN
app/assets/images/common/button-background-pressed-border.png
Normal file
After ![]() (image error) Size: 4.1 KiB |
BIN
app/assets/images/common/button-background-pressed.png
Normal file
After ![]() (image error) Size: 3.7 KiB |
BIN
app/assets/images/level/code_editor_background_border.png
Normal file
After ![]() (image error) Size: 34 KiB |
BIN
app/assets/images/level/code_editor_top_bar_hinge.png
Normal file
After ![]() (image error) Size: 1.7 KiB |
BIN
app/assets/images/level/code_editor_top_bar_wood_background.png
Normal file
After ![]() (image error) Size: 25 KiB |
BIN
app/assets/images/level/code_palette_wood_background.png
Normal file
After ![]() (image error) Size: 65 KiB |
BIN
app/assets/images/level/code_toolbar_background.png
Normal file
After ![]() (image error) Size: 7.6 KiB |
BIN
app/assets/images/level/code_toolbar_run_button_active.png
Normal file
After ![]() (image error) Size: 4.8 KiB |
After ![]() (image error) Size: 4.7 KiB |
BIN
app/assets/images/level/code_toolbar_run_button_zazz.png
Normal file
After ![]() (image error) Size: 5.3 KiB |
BIN
app/assets/images/level/code_toolbar_run_button_zazz_pressed.png
Normal file
After ![]() (image error) Size: 5.2 KiB |
BIN
app/assets/images/level/code_toolbar_submit_button_active.png
Normal file
After ![]() (image error) Size: 5.2 KiB |
After ![]() (image error) Size: 5.2 KiB |
BIN
app/assets/images/level/code_toolbar_submit_button_zazz.png
Normal file
After ![]() (image error) Size: 5.5 KiB |
After ![]() (image error) Size: 5.5 KiB |
BIN
app/assets/images/level/hud_hinge.png
Normal file
After ![]() (image error) Size: 2.1 KiB |
BIN
app/assets/images/level/thang_avatar_frame.png
Normal file
After ![]() (image error) Size: 4.7 KiB |
|
@ -198,6 +198,7 @@
|
||||||
failing: "Failing"
|
failing: "Failing"
|
||||||
action_timeline: "Action Timeline"
|
action_timeline: "Action Timeline"
|
||||||
click_to_select: "Click on a unit to select it."
|
click_to_select: "Click on a unit to select it."
|
||||||
|
reload: "Reload"
|
||||||
reload_title: "Reload All Code?"
|
reload_title: "Reload All Code?"
|
||||||
reload_really: "Are you sure you want to reload this level back to the beginning?"
|
reload_really: "Are you sure you want to reload this level back to the beginning?"
|
||||||
reload_confirm: "Reload All"
|
reload_confirm: "Reload All"
|
||||||
|
@ -447,7 +448,7 @@
|
||||||
enter: "Enter"
|
enter: "Enter"
|
||||||
escape: "Escape"
|
escape: "Escape"
|
||||||
shift: "Shift"
|
shift: "Shift"
|
||||||
cast_spell: "Cast current spell."
|
run_code: "Run current code."
|
||||||
run_real_time: "Run in real time."
|
run_real_time: "Run in real time."
|
||||||
continue_script: "Continue past current script."
|
continue_script: "Continue past current script."
|
||||||
skip_scripts: "Skip past all skippable scripts."
|
skip_scripts: "Skip past all skippable scripts."
|
||||||
|
|
|
@ -85,9 +85,6 @@ module.exports =
|
||||||
problems: {type: 'array'}
|
problems: {type: 'array'}
|
||||||
isCast: {type: 'boolean'}
|
isCast: {type: 'boolean'}
|
||||||
|
|
||||||
'tome:thang-list-entry-popover-shown': c.object {title: 'Thang List Entry Popover Shown', description: 'Published when we show the popover for a thang in the master list', required: ['entry']},
|
|
||||||
entry: {type: 'object'}
|
|
||||||
|
|
||||||
'tome:spell-shown': c.object {title: 'Spell Shown', description: 'Published when we show a spell', required: ['thang', 'spell']},
|
'tome:spell-shown': c.object {title: 'Spell Shown', description: 'Published when we show a spell', required: ['thang', 'spell']},
|
||||||
thang: {type: 'object'}
|
thang: {type: 'object'}
|
||||||
spell: {type: 'object'}
|
spell: {type: 'object'}
|
||||||
|
|
|
@ -312,9 +312,56 @@ kbd
|
||||||
.arrow
|
.arrow
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
|
.btn.btn-illustrated
|
||||||
|
background: 0
|
||||||
|
border: 0
|
||||||
|
border-radius: 0
|
||||||
|
@include box-shadow(none)
|
||||||
|
border-image: url(/images/common/button-background-active-border.png) 14 20 20 20 fill round
|
||||||
|
border-width: 7px 10px 10px 10px
|
||||||
|
padding: 0
|
||||||
|
font-family: Open Sans Condensed
|
||||||
|
text-transform: uppercase
|
||||||
|
font-weight: bold
|
||||||
|
color: rgb(248, 197, 146)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border-image: url(/images/common/button-background-pressed-border.png) 14 16 16 20 fill round
|
||||||
|
padding: 2px 0 0 2px
|
||||||
|
border-width: 7px 8px 8px 10px
|
||||||
|
|
||||||
|
&.disabled, &:disabled
|
||||||
|
border-image: url(/images/common/button-background-disabled-border.png) 14 20 20 20 fill round
|
||||||
|
@include opacity(1)
|
||||||
|
|
||||||
|
> *
|
||||||
|
@include opacity(0.5)
|
||||||
|
|
||||||
|
> *
|
||||||
|
@include opacity(0.75)
|
||||||
|
|
||||||
|
&:hover > *
|
||||||
|
@include opacity(1)
|
||||||
|
|
||||||
|
|
||||||
html.no-borderimage
|
html.no-borderimage
|
||||||
.popover
|
.popover
|
||||||
border: 0
|
border: 0
|
||||||
background: transparent url(/images/level/popover_background.png)
|
background: transparent url(/images/level/popover_background.png)
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
padding: 10px 20px
|
padding: 10px 20px
|
||||||
|
|
||||||
|
.btn.btn-illustrated
|
||||||
|
border: 0
|
||||||
|
background-image: url(/images/common/button-background-active.png)
|
||||||
|
background-size: 100% 100%
|
||||||
|
padding: 7px 10px 10px 10px
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background-image: url(/images/common/button-background-pressed.png)
|
||||||
|
padding: 9px 8px 8px 12px
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
&.disabled, &:disabled
|
||||||
|
background-image: url(/images/common/button-background-disabled.png)
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ $level-resize-transition-time: 0.5s
|
||||||
top: 0px
|
top: 0px
|
||||||
bottom: 0
|
bottom: 0
|
||||||
@include transition(width $level-resize-transition-time ease-in-out, right $level-resize-transition-time ease-in-out)
|
@include transition(width $level-resize-transition-time ease-in-out, right $level-resize-transition-time ease-in-out)
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
// Level Docs
|
// Level Docs
|
||||||
.ui-effects-transfer
|
.ui-effects-transfer
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#level-editor-config-modal
|
|
||||||
.select-group
|
|
||||||
display: block
|
|
||||||
min-height: 20px
|
|
||||||
margin-top: 10px
|
|
||||||
margin-bottom: 10px
|
|
||||||
padding-left: 20px
|
|
||||||
vertical-align: middle
|
|
||||||
|
|
||||||
label
|
|
||||||
font-weight: normal
|
|
||||||
margin-right: 20px
|
|
|
@ -28,9 +28,9 @@
|
||||||
|
|
||||||
.avatar-frame
|
.avatar-frame
|
||||||
position: absolute
|
position: absolute
|
||||||
left: -13%
|
left: -18%
|
||||||
top: -14%
|
top: -19%
|
||||||
width: 132%
|
width: 145%
|
||||||
|
|
||||||
.badge
|
.badge
|
||||||
$radius: 8px
|
$radius: 8px
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
@include box-shadow(0px 0px 8px #333)
|
@include box-shadow(0px 0px 8px #333)
|
||||||
color: white
|
color: white
|
||||||
50%
|
50%
|
||||||
@include box-shadow(0px 0px 35px #87FFCE)
|
@include box-shadow(0px 0px 35px #87CEFF)
|
||||||
color: #87FFFF
|
color: #87CEFF
|
||||||
to
|
to
|
||||||
@include box-shadow(0px 0px 8px #333)
|
@include box-shadow(0px 0px 8px #333)
|
||||||
color: white
|
color: white
|
||||||
|
@ -31,40 +31,113 @@
|
||||||
width: 100%
|
width: 100%
|
||||||
border-radius: 6px
|
border-radius: 6px
|
||||||
|
|
||||||
.btn
|
background: transparent url(/images/level/code_toolbar_background.png)
|
||||||
padding: 3px 10px
|
background-size: 100% 100%
|
||||||
height: 40px
|
left: -15px
|
||||||
font-size: 22px
|
right: 15px
|
||||||
|
height: 94px
|
||||||
|
margin-top: -8px
|
||||||
|
padding: 20px 2.8%
|
||||||
|
|
||||||
.submit-button
|
.btn.btn-illustrated
|
||||||
margin-left: 20px
|
height: 46px
|
||||||
min-width: 150px
|
font-size: 24px
|
||||||
|
line-height: 24px
|
||||||
|
width: 45%
|
||||||
|
width: -webkit-calc(50% - 10px)
|
||||||
|
width: calc(50% - 10px)
|
||||||
|
border-image: url(/images/level/code_toolbar_run_button_active.png) 14 20 20 20 fill round
|
||||||
|
border-width: 7px 10px 10px 10px
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border-image: url(/images/level/code_toolbar_run_button_active_pressed.png) 14 20 20 20 fill round
|
||||||
|
padding: 2px 0 0 2px
|
||||||
|
|
||||||
|
&.submit-button
|
||||||
|
margin-left: 10px
|
||||||
|
border-image: url(/images/level/code_toolbar_submit_button_active.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border-image: url(/images/level/code_toolbar_submit_button_active_pressed.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
.cast-button
|
.cast-button
|
||||||
margin-left: 10px
|
|
||||||
min-width: 150px
|
|
||||||
@include opacity(0.77)
|
@include opacity(0.77)
|
||||||
|
|
||||||
&:hover, &.castable
|
&:hover, &.castable
|
||||||
@include opacity(1)
|
@include opacity(1)
|
||||||
|
|
||||||
|
.submit-button > *
|
||||||
|
@include opacity(0.9)
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
@include opacity(1)
|
||||||
|
|
||||||
&:not(.winnable)
|
&:not(.winnable)
|
||||||
|
|
||||||
.cast-button.castable
|
.btn.btn-illustrated
|
||||||
font-weight: bold
|
|
||||||
-webkit-animation-name: castablePulse
|
|
||||||
-webkit-animation-duration: 3s
|
|
||||||
-webkit-animation-iteration-count: infinite
|
|
||||||
|
|
||||||
.submit-button
|
&.cast-button.castable
|
||||||
font-size: 16px
|
font-weight: bold
|
||||||
|
@include animation(castablePulse 3s infinite)
|
||||||
|
border-image: url(/images/level/code_toolbar_run_button_zazz.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border-image: url(/images/level/code_toolbar_run_button_zazz_pressed.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
|
&.submit-button
|
||||||
|
font-size: 16px
|
||||||
|
|
||||||
&.winnable
|
&.winnable
|
||||||
.submit-button
|
|
||||||
font-weight: bold
|
|
||||||
-webkit-animation-name: winnablePulse
|
|
||||||
-webkit-animation-duration: 3s
|
|
||||||
-webkit-animation-iteration-count: infinite
|
|
||||||
|
|
||||||
.cast-button
|
.btn.btn-illustrated
|
||||||
font-size: 16px
|
&.submit-button
|
||||||
|
font-weight: bold
|
||||||
|
@include animation(winnablePulse 3s infinite)
|
||||||
|
|
||||||
|
border-image: url(/images/level/code_toolbar_submit_button_zazz.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png) 14 20 20 20 fill round
|
||||||
|
|
||||||
|
&.cast-button
|
||||||
|
font-size: 16px
|
||||||
|
|
||||||
|
html.no-borderimage #cast-button-view
|
||||||
|
.btn.btn-illustrated
|
||||||
|
border: 0
|
||||||
|
background-image: url(/images/level/code_toolbar_run_button_active.png)
|
||||||
|
background-size: 100% 100%
|
||||||
|
padding: 7px 10px 10px 10px
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background-image: url(/images/level/code_toolbar_run_button_active_pressed.png)
|
||||||
|
padding: 9px 8px 8px 12px
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
&.submit-button
|
||||||
|
background-image: url(/images/level/code_toolbar_submit_button_active_pressed.png)
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background-image: url(/images/level/code_toolbar_submit_button_active_pressed.png)
|
||||||
|
border: 0
|
||||||
|
|
||||||
|
&:not(.winnable)
|
||||||
|
.btn.btn-illustrated
|
||||||
|
&.cast-button.castable
|
||||||
|
border: 0
|
||||||
|
background-image: url(/images/level/code_toolbar_run_button_zazz.png)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background-image: url(/images/level/code_toolbar_run_button_zazz_pressed.png)
|
||||||
|
|
||||||
|
&.winnable
|
||||||
|
.btn.btn-illustrated
|
||||||
|
&.submit-button
|
||||||
|
border: 0
|
||||||
|
background-image: url(/images/level/code_toolbar_submit_button_zazz.png)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
border: 0
|
||||||
|
background-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png)
|
||||||
|
|
||||||
|
|
|
@ -2,38 +2,37 @@
|
||||||
@import "app/styles/bootstrap/variables"
|
@import "app/styles/bootstrap/variables"
|
||||||
|
|
||||||
@mixin editor-height($extraHeight)
|
@mixin editor-height($extraHeight)
|
||||||
@include box-sizing(border-box)
|
|
||||||
width: 98%
|
width: 98%
|
||||||
height: 83%
|
height: 83%
|
||||||
height: unquote("-webkit-calc(100% - 60px -")$extraHeight unquote(")")
|
height: unquote("-webkit-calc(100% - 100px -")$extraHeight unquote(")")
|
||||||
height: unquote("calc(100% - 60px -")$extraHeight unquote(")")
|
height: unquote("calc(100% - 100px -")$extraHeight unquote(")")
|
||||||
|
|
||||||
#spell-view
|
#spell-view
|
||||||
position: absolute
|
margin-top: 10px
|
||||||
left: 10px
|
padding-top: 20px
|
||||||
top: 140px
|
padding-left: 30px
|
||||||
//top: 48px
|
padding-bottom: 95px
|
||||||
right: 10px
|
|
||||||
padding-bottom: 10px
|
|
||||||
z-index: 1
|
|
||||||
// Set z-index above palette
|
|
||||||
display: none
|
display: none
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
&.shown
|
&.shown
|
||||||
display: block
|
display: block
|
||||||
|
|
||||||
.code-background
|
.code-background
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: -68px
|
||||||
|
left: 0px
|
||||||
height: 100%
|
height: 100%
|
||||||
width: 100%
|
right: -10px
|
||||||
|
|
||||||
span.code-background
|
span.code-background
|
||||||
border-width: 40px
|
border-width: 124px 76px 64px 40px
|
||||||
border-image: url(/images/level/code_editor_background.png) 40 fill round
|
border-image: url(/images/level/code_editor_background_border.png) 124 76 64 40 fill round
|
||||||
|
|
||||||
img.code-background
|
img.code-background
|
||||||
display: none
|
display: none
|
||||||
|
width: 100%
|
||||||
|
|
||||||
.save-status
|
.save-status
|
||||||
display: none
|
display: none
|
||||||
|
@ -44,7 +43,7 @@
|
||||||
.firepad
|
.firepad
|
||||||
// When Firepad is active, it wraps .ace_editor in .firepad.
|
// When Firepad is active, it wraps .ace_editor in .firepad.
|
||||||
@include editor-height(0px)
|
@include editor-height(0px)
|
||||||
width: 98%
|
width: 94%
|
||||||
|
|
||||||
.ace_editor
|
.ace_editor
|
||||||
width: 100%
|
width: 100%
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
.ace_editor
|
.ace_editor
|
||||||
// When Firepad isn't active, .ace_editor needs the width/height set itself.
|
// When Firepad isn't active, .ace_editor needs the width/height set itself.
|
||||||
@include editor-height(0px)
|
@include editor-height(0px)
|
||||||
width: 98%
|
width: 94%
|
||||||
position: relative
|
position: relative
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
line-height: 20px
|
line-height: 20px
|
||||||
|
@ -70,14 +69,18 @@
|
||||||
@include opacity(20)
|
@include opacity(20)
|
||||||
|
|
||||||
.ace_gutter
|
.ace_gutter
|
||||||
background-color: rgba(255, 255, 255, 0.25)
|
background-color: transparent
|
||||||
|
border-right: 1px solid rgb(195, 178, 156)
|
||||||
|
//background-color: rgba(255, 255, 255, 0.25)
|
||||||
width: 47px
|
width: 47px
|
||||||
margin-left: 4px
|
margin-left: 4px
|
||||||
border-bottom: 1px dotted #2f261d
|
|
||||||
|
|
||||||
.ace_scroller
|
.ace_scroller
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
border-bottom: 1px dotted #2f261d
|
//padding-left: 10px // Interrupts gutter and line highlighting
|
||||||
|
|
||||||
|
.ace_active-line, .ace_gutter-active-line
|
||||||
|
background-color: rgba(255, 255, 255, 0.4)
|
||||||
|
|
||||||
.ace_content
|
.ace_content
|
||||||
.executing, .executed, .problem-marker-info, .problem-marker-warning, .problem-marker-error
|
.executing, .executed, .problem-marker-info, .problem-marker-warning, .problem-marker-error
|
||||||
|
@ -147,10 +150,10 @@
|
||||||
.ace_searchbtn, .ace_replacebtn
|
.ace_searchbtn, .ace_replacebtn
|
||||||
padding: 0px 4px
|
padding: 0px 4px
|
||||||
|
|
||||||
|
|
||||||
html.no-borderimage
|
html.no-borderimage
|
||||||
#spell-view
|
#spell-view
|
||||||
span.code-background
|
span.code-background
|
||||||
display: none
|
display: none
|
||||||
img.code-background
|
img.code-background
|
||||||
display: block
|
display: block
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
$height: 87px
|
$height: 87px
|
||||||
$paddingTop: 10px
|
$paddingTop: 10px
|
||||||
$paddingBottom: 25px
|
$paddingBottom: 25px
|
||||||
$childMargin: 2px
|
|
||||||
$childSize: $height - $paddingTop - $paddingBottom
|
$childSize: $height - $paddingTop - $paddingBottom
|
||||||
width: 100%
|
width: 100%
|
||||||
height: $height
|
height: $height
|
||||||
|
@ -22,6 +21,7 @@
|
||||||
position: relative
|
position: relative
|
||||||
background: transparent url(/images/level/code_editor_top_bar_wood_background.png)
|
background: transparent url(/images/level/code_editor_top_bar_wood_background.png)
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
|
z-index: 2
|
||||||
|
|
||||||
.hinge
|
.hinge
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -30,7 +30,6 @@
|
||||||
width: 24px
|
width: 24px
|
||||||
height: 20px
|
height: 20px
|
||||||
background-size: contain
|
background-size: contain
|
||||||
z-index: 100
|
|
||||||
|
|
||||||
.hinge-0
|
.hinge-0
|
||||||
left: 20%
|
left: 20%
|
||||||
|
@ -45,15 +44,24 @@
|
||||||
background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0.5) 100%), url(/images/level/code_editor_top_bar_wood_background.png)
|
background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0.5) 100%), url(/images/level/code_editor_top_bar_wood_background.png)
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
|
|
||||||
.spell-list-button, .thang-avatar-view, .reload-code, .beautify-code, .fullscreen-code
|
.thang-avatar-view
|
||||||
width: $childSize
|
width: $childSize - 10px
|
||||||
height: $childSize
|
margin: 5px
|
||||||
margin: 0 $childMargin
|
|
||||||
display: inline-block
|
display: inline-block
|
||||||
|
|
||||||
.spell-list-button, .thang-avatar-view
|
|
||||||
float: left
|
float: left
|
||||||
|
|
||||||
|
.btn.btn-small
|
||||||
|
margin-top: 15px
|
||||||
|
margin-right: 15px
|
||||||
|
font-size: 18px
|
||||||
|
|
||||||
|
.glyphicon
|
||||||
|
font-size: 16px
|
||||||
|
|
||||||
|
.btn.btn-small.spell-list-button
|
||||||
|
float: left
|
||||||
|
margin-top: 5px
|
||||||
|
|
||||||
.spell-tool-buttons
|
.spell-tool-buttons
|
||||||
position: absolute
|
position: absolute
|
||||||
right: 0px
|
right: 0px
|
||||||
|
@ -69,43 +77,32 @@
|
||||||
.fullscreen-code
|
.fullscreen-code
|
||||||
float: right
|
float: right
|
||||||
&:not(.maximized)
|
&:not(.maximized)
|
||||||
.icon-resize-small
|
.glyphicon-resize-small
|
||||||
display: none
|
display: none
|
||||||
&.maximized
|
&.maximized
|
||||||
.icon-fullscreen
|
.glyphicon-fullscreen
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
.btn.btn-small
|
|
||||||
background: transparent
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
&:not(:hover)
|
|
||||||
border-color: transparent
|
|
||||||
@include box-shadow(none)
|
|
||||||
|
|
||||||
.icon-chevron-down, .icon-repeat, .icon-magnet, .icon-fullscreen, .icon-resize-small
|
|
||||||
margin-top: 7px
|
|
||||||
|
|
||||||
.thang-avatar-wrapper
|
.thang-avatar-wrapper
|
||||||
border-width: 0
|
border-width: 0
|
||||||
|
|
||||||
.method-label
|
.method-name-area
|
||||||
margin-left: 10px
|
margin-left: 10px
|
||||||
line-height: $childSize
|
margin-top: 10px
|
||||||
font-size: 1vw
|
|
||||||
display: inline-block
|
|
||||||
font-weight: bold
|
|
||||||
color: white
|
|
||||||
text-transform: uppercase
|
text-transform: uppercase
|
||||||
|
display: inline-block
|
||||||
|
font-family: Open Sans Condensed
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
.method-signature
|
.method-label
|
||||||
margin-left: 10px
|
font-size: 12px
|
||||||
line-height: $childSize
|
color: rgb(243, 211, 59)
|
||||||
font-size: 1vw
|
margin-bottom: -5px
|
||||||
display: inline-block
|
|
||||||
font-weight: bold
|
.method-signature
|
||||||
color: white
|
color: white
|
||||||
text-transform: uppercase
|
font-size: 18px
|
||||||
|
padding: 0
|
||||||
|
|
||||||
.spell-list-entry-view:not(.spell-tab)
|
.spell-list-entry-view:not(.spell-tab)
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
|
@ -3,55 +3,44 @@
|
||||||
|
|
||||||
#spell-palette-view
|
#spell-palette-view
|
||||||
position: absolute
|
position: absolute
|
||||||
padding-bottom: 10px
|
|
||||||
left: 10px
|
left: 10px
|
||||||
right: 10px
|
right: 10px
|
||||||
//height: 140px
|
padding: 0 4px 10px 40px
|
||||||
// Height relates to .tab-content height
|
|
||||||
padding-top: 35px
|
|
||||||
padding-left: 12px
|
|
||||||
padding-right: 4px
|
|
||||||
color: #333
|
|
||||||
// Get crazy with the backgrounds so that we can lower the opacity on the editor background above it, making a gradient of the disabled background color on the top around where it's usually covered
|
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
z-index: 0
|
z-index: 2
|
||||||
//overflow-y: auto
|
//overflow-y: auto
|
||||||
|
|
||||||
.code-palette-background
|
|
||||||
position: absolute
|
|
||||||
left: 0
|
|
||||||
top: 0
|
|
||||||
width: 100%
|
|
||||||
height: 100%
|
|
||||||
z-index: -1
|
|
||||||
|
|
||||||
span.code-palette-background
|
|
||||||
border-width: 25px
|
|
||||||
border-image: url(/images/level/code_palette_background.png) 25 fill round
|
|
||||||
|
|
||||||
img.code-palette-background
|
.code-palette-background
|
||||||
display: none
|
width: 100%
|
||||||
|
position: absolute
|
||||||
|
left: 0px
|
||||||
|
z-index: -1
|
||||||
|
|
||||||
&.disabled
|
&.disabled
|
||||||
@include opacity(0.80)
|
@include opacity(0.80)
|
||||||
|
|
||||||
h4
|
h4
|
||||||
color: #333
|
color: white
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
line-height: 16px
|
line-height: 16px
|
||||||
margin: 0 4px
|
margin: 25px 0 5px 2px
|
||||||
font-weight: normal
|
font-weight: normal
|
||||||
|
text-transform: uppercase
|
||||||
|
|
||||||
.nav > li > a
|
.nav > li > a
|
||||||
padding: 2px 20px 0px 20px
|
padding: 2px 20px 0px 20px
|
||||||
margin-bottom: 3px
|
margin-bottom: 3px
|
||||||
|
|
||||||
ul.nav.nav-pills
|
ul.nav.nav-pills
|
||||||
|
margin-top: 15px
|
||||||
|
|
||||||
|
h4
|
||||||
|
margin-top: 2px
|
||||||
li.active a
|
li.active a
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
&.multiple-tabs li.active a
|
&.multiple-tabs li.active a
|
||||||
background-color: lighten(rgb(230, 212, 146), 10%)
|
background-color: darken(rgb(230, 212, 146), 30%)
|
||||||
&.multiple-tabs li:not(.active) a
|
&.multiple-tabs li:not(.active) a
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
||||||
|
@ -82,8 +71,9 @@
|
||||||
@include flexbox()
|
@include flexbox()
|
||||||
@include flex-wrap()
|
@include flex-wrap()
|
||||||
@include flex-center()
|
@include flex-center()
|
||||||
outline: 1px dashed #b86
|
|
||||||
position: relative
|
position: relative
|
||||||
|
background-color: rgb(20, 13, 8)
|
||||||
|
margin: 1px
|
||||||
|
|
||||||
img.item-image
|
img.item-image
|
||||||
width: 38px
|
width: 38px
|
||||||
|
@ -91,49 +81,11 @@
|
||||||
position: absolute
|
position: absolute
|
||||||
|
|
||||||
&:not(:hover) img.item-image
|
&:not(:hover) img.item-image
|
||||||
-webkit-filter: sepia(100%)
|
-webkit-filter: contrast(50%) sepia(100%) saturate(500%) hue-rotate(7deg)
|
||||||
filter: sepia(100%)
|
filter: contrast(50%) sepia(100%) saturate(1000%) hue-rotate(7deg)
|
||||||
|
|
||||||
.spell-palette-entry-view
|
.spell-palette-entry-view
|
||||||
margin-left: 38px
|
margin-left: 38px
|
||||||
width: 174px
|
width: 174px
|
||||||
width: -webkit-calc(100% - 38px)
|
width: -webkit-calc(100% - 38px)
|
||||||
width: calc(100% - 38px)
|
width: calc(100% - 38px)
|
||||||
|
|
||||||
.code-language-logo
|
|
||||||
position: absolute
|
|
||||||
width: 16px
|
|
||||||
height: 16px
|
|
||||||
left: 16px
|
|
||||||
top: 36px
|
|
||||||
z-index: 10
|
|
||||||
background-color: transparent
|
|
||||||
background-repeat: no-repeat
|
|
||||||
background-size: contain
|
|
||||||
cursor: pointer
|
|
||||||
|
|
||||||
&.javascript
|
|
||||||
background-image: url(/images/common/code_languages/javascript_icon.png)
|
|
||||||
&.python
|
|
||||||
background-image: url(/images/common/code_languages/python_icon.png)
|
|
||||||
&.coffeescript
|
|
||||||
background-image: url(/images/common/code_languages/coffeescript_icon.png)
|
|
||||||
&.clojure
|
|
||||||
background-image: url(/images/common/code_languages/clojure_icon.png)
|
|
||||||
&.lua
|
|
||||||
background-image: url(/images/common/code_languages/lua_icon.png)
|
|
||||||
&.io
|
|
||||||
background-image: url(/images/common/code_languages/io_icon.png)
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
outline: 1px outset #ccc
|
|
||||||
|
|
||||||
&:active
|
|
||||||
outline: 1px inset #ccc
|
|
||||||
|
|
||||||
html.no-borderimage
|
|
||||||
#spell-palette-view
|
|
||||||
span.code-palette-background
|
|
||||||
display: none
|
|
||||||
img.code-palette-background
|
|
||||||
display: block
|
|
||||||
|
|
|
@ -25,20 +25,21 @@
|
||||||
background-color: darken(#FFFFFF, 25%)
|
background-color: darken(#FFFFFF, 25%)
|
||||||
|
|
||||||
// Originally pulled these colors from the most relevant textmate-theme classes, but then fudged them a lot.
|
// Originally pulled these colors from the most relevant textmate-theme classes, but then fudged them a lot.
|
||||||
&.function
|
//&.function
|
||||||
color: black
|
// color: black
|
||||||
&.object
|
//&.object
|
||||||
color: rgb(6, 150, 14)
|
// color: rgb(6, 150, 14)
|
||||||
&.string
|
//&.string
|
||||||
color: rgb(3, 106, 7)
|
// color: rgb(3, 106, 7)
|
||||||
&.number
|
//&.number
|
||||||
color: rgb(0, 0, 205)
|
// color: rgb(0, 0, 205)
|
||||||
&.boolean
|
//&.boolean
|
||||||
color: rgb(88, 92, 246)
|
// color: rgb(88, 92, 246)
|
||||||
&.snippet
|
//&.snippet
|
||||||
color: blue
|
// color: blue
|
||||||
&.undefined
|
//&.undefined
|
||||||
color: rgb(197, 6, 11)
|
// color: rgb(197, 6, 11)
|
||||||
|
color: rgb(243, 169, 49)
|
||||||
|
|
||||||
.spell-palette-popover.popover
|
.spell-palette-popover.popover
|
||||||
// Only those popovers which are our direct children (spell documentation)
|
// Only those popovers which are our direct children (spell documentation)
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
@import "app/styles/mixins"
|
|
||||||
@import "app/styles/bootstrap/variables"
|
|
||||||
|
|
||||||
#thang-list-view
|
|
||||||
margin: 50px 15px 15px 15px
|
|
||||||
overflow: auto
|
|
||||||
height: 80%
|
|
||||||
height: -webkit-calc(100% - 65px)
|
|
||||||
height: calc(100% - 65px)
|
|
||||||
|
|
||||||
h3
|
|
||||||
line-height: 25px
|
|
||||||
margin: 0
|
|
||||||
text-align: center
|
|
||||||
letter-spacing: 0.1em
|
|
||||||
|
|
||||||
.thang-list-section
|
|
||||||
margin: 5px
|
|
||||||
padding: 5px
|
|
||||||
background-color: rgba(200, 200, 200, 0.25)
|
|
||||||
border-radius: 5px
|
|
||||||
overflow: hidden
|
|
|
@ -1,38 +0,0 @@
|
||||||
@import "app/styles/mixins"
|
|
||||||
@import "app/styles/bootstrap/variables"
|
|
||||||
|
|
||||||
.thang-list-entry-view
|
|
||||||
@include opacity(0.90)
|
|
||||||
cursor: pointer
|
|
||||||
float: left
|
|
||||||
box-sizing: border-box
|
|
||||||
width: 20%
|
|
||||||
max-width: 100px
|
|
||||||
position: relative
|
|
||||||
|
|
||||||
&.dead
|
|
||||||
@include opacity(0.75)
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content: "×"
|
|
||||||
font-size: 160px
|
|
||||||
color: red
|
|
||||||
@include opacity(0.75)
|
|
||||||
position: absolute
|
|
||||||
bottom: 0
|
|
||||||
height: 100%
|
|
||||||
width: 100%
|
|
||||||
text-align: center
|
|
||||||
line-height: 100px
|
|
||||||
font-family: monospace
|
|
||||||
|
|
||||||
.thang-name
|
|
||||||
text-decoration: line-through
|
|
||||||
|
|
||||||
&.disabled
|
|
||||||
@include opacity(0.25)
|
|
||||||
cursor: default
|
|
||||||
|
|
||||||
&:hover:not(.disabled)
|
|
||||||
@include opacity(1)
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
@import "app/styles/mixins"
|
|
||||||
@import "app/styles/bootstrap/variables"
|
|
||||||
|
|
||||||
.thang-list-entry-spells
|
|
||||||
|
|
||||||
.thang-list-entry-spell
|
|
||||||
padding: 4px
|
|
||||||
cursor: pointer
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background-color: hsla(240, 40, 80, 0.25)
|
|
||||||
|
|
||||||
code
|
|
||||||
background-color: transparent
|
|
||||||
border: 0
|
|
||||||
font-size: 1.1em
|
|
|
@ -1,55 +0,0 @@
|
||||||
extends /templates/modal/modal_base
|
|
||||||
|
|
||||||
block modal-header-content
|
|
||||||
h3(data-i18n="play_level.editor_config_title") Editor Configuration
|
|
||||||
|
|
||||||
block modal-body-content
|
|
||||||
.form
|
|
||||||
.form-group.select-group
|
|
||||||
label.control-label(for="tome-session-language" data-i18n="play_level.editor_config_level_language_label") Language for This Level
|
|
||||||
select#tome-session-language(name="language")
|
|
||||||
for option in languages
|
|
||||||
option(value=option.id selected=(sessionLanguage === option.id))= option.name
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_level_language_description") Define the programming language for this particular level.
|
|
||||||
|
|
||||||
.form-group.select-group
|
|
||||||
label.control-label(for="tome-language" data-i18n="play_level.editor_config_default_language_label") Default Programming Language
|
|
||||||
select#tome-language(name="language")
|
|
||||||
for option in languages
|
|
||||||
option(value=option.id selected=(language === option.id))= option.name
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_default_language_description") Define the programming language you want to code in when starting new levels.
|
|
||||||
|
|
||||||
.form-group.select-group
|
|
||||||
label.control-label(for="tome-key-bindings" data-i18n="play_level.editor_config_keybindings_label") Key Bindings
|
|
||||||
select#tome-key-bindings(name="keyBindings")
|
|
||||||
option(value="default" selected=(keyBindings === "default") data-i18n="play_level.editor_config_keybindings_default") Default (Ace)
|
|
||||||
option(value="vim" selected=(keyBindings === "vim")) Vim
|
|
||||||
option(value="emacs" selected=(keyBindings === "emacs")) Emacs
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_keybindings_description") Adds additional shortcuts known from the common editors.
|
|
||||||
|
|
||||||
.form-group.checkbox
|
|
||||||
label(for="tome-live-completion")
|
|
||||||
input#tome-live-completion(name="liveCompletion", type="checkbox", checked=liveCompletion)
|
|
||||||
span(data-i18n="play_level.editor_config_livecompletion_label") Live Autocompletion
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_livecompletion_description") Displays autocomplete suggestions while typing.
|
|
||||||
|
|
||||||
.form-group.checkbox
|
|
||||||
label(for="tome-invisibles")
|
|
||||||
input#tome-invisibles(name="invisibles", type="checkbox", checked=invisibles)
|
|
||||||
span(data-i18n="play_level.editor_config_invisibles_label") Show Invisibles
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_invisibles_description") Displays invisibles such as spaces or tabs.
|
|
||||||
|
|
||||||
.form-group.checkbox
|
|
||||||
label(for="tome-indent-guides")
|
|
||||||
input#tome-indent-guides(name="indentGuides", type="checkbox", checked=indentGuides)
|
|
||||||
span(data-i18n="play_level.editor_config_indentguides_label") Show Indent Guides
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_indentguides_description") Displays vertical lines to see indentation better.
|
|
||||||
|
|
||||||
.form-group.checkbox
|
|
||||||
label(for="tome-behaviors")
|
|
||||||
input#tome-behaviors(name="behaviors", type="checkbox", checked=behaviors)
|
|
||||||
span(data-i18n="play_level.editor_config_behaviors_label") Smart Behaviors
|
|
||||||
span.help-block(data-i18n="play_level.editor_config_behaviors_description") Autocompletes brackets, braces, and quotes.
|
|
||||||
|
|
||||||
block modal-footer-content
|
|
||||||
a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="modal.close").btn.btn-primary Close
|
|
|
@ -19,7 +19,7 @@ block modal-body-content
|
||||||
dl.dl-horizontal
|
dl.dl-horizontal
|
||||||
dt(title=shift + " " + enter)
|
dt(title=shift + " " + enter)
|
||||||
kbd ⇧ #{enter}
|
kbd ⇧ #{enter}
|
||||||
dd(data-i18n="keyboard_shortcuts.cast_spell") Cast current spell.
|
dd(data-i18n="keyboard_shortcuts.run_code") Run current code.
|
||||||
dl.dl-horizontal
|
dl.dl-horizontal
|
||||||
dt(title=ctrlName + " " + shift + " " + enter)
|
dt(title=ctrlName + " " + shift + " " + enter)
|
||||||
kbd #{ctrl} ⇧ #{enter}
|
kbd #{ctrl} ⇧ #{enter}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
button.btn.btn-lg.btn-inverse.banner.cast-button(title=castVerbose, data-i18n="play_level.tome_run_button_ran") Ran
|
button.btn.btn-lg.btn-illustrated.cast-button(title=castVerbose)
|
||||||
|
span(data-i18n="play_level.tome_run_button_ran") Ran
|
||||||
|
|
||||||
if testSubmitText != null && testSubmitText.length > 0
|
button.btn.btn-lg.btn-illustrated.submit-button(title=castRealTimeVerbose)
|
||||||
button.btn.btn-lg.btn-success.banner.submit-button(title=castRealTimeVerbose) #{testSubmitText}
|
if testSubmitText != null && testSubmitText.length > 0
|
||||||
else
|
span= testSubmitText
|
||||||
button.btn.btn-lg.btn-success.banner.submit-button(title=castRealTimeVerbose, data-i18n="play_level.tome_submit_button") Submit
|
else
|
||||||
|
span(data-i18n="play_level.tome_submit_button") Submit
|
||||||
|
|
|
@ -4,25 +4,27 @@
|
||||||
.hinge.hinge-3
|
.hinge.hinge-3
|
||||||
|
|
||||||
if includeSpellList
|
if includeSpellList
|
||||||
.btn.btn-small.spell-list-button(data-i18n="[title]play_level.tome_see_all_methods", title="See all methods you can edit")
|
.btn.btn-small.btn-illustrated.spell-list-button(data-i18n="[title]play_level.tome_see_all_methods", title="See all methods you can edit")
|
||||||
i.icon-chevron-down
|
.glyphicon.glyphicon-chevron-down
|
||||||
|
|
||||||
.thang-avatar-placeholder
|
.thang-avatar-placeholder
|
||||||
|
|
||||||
.method-label(data-i18n="play_level.tome_current_method") Current Method
|
.method-name-area
|
||||||
.method-signature #{methodSignature}
|
.method-label(data-i18n="play_level.tome_current_method") Current Method
|
||||||
|
.method-signature #{methodSignature}
|
||||||
|
|
||||||
.spell-tool-buttons
|
.spell-tool-buttons
|
||||||
if levelType !== 'hero'
|
.btn.btn-small.btn-illustrated.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
|
||||||
.btn.btn-small.fullscreen-code(title=maximizeShortcutVerbose)
|
.glyphicon.glyphicon-repeat
|
||||||
i.icon-fullscreen
|
span.spl(data-i18n="play_level.reload") Reload
|
||||||
i.icon-resize-small
|
|
||||||
|
|
||||||
.btn.btn-small.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
|
|
||||||
i.icon-repeat
|
|
||||||
|
|
||||||
if codeLanguage === 'javascript'
|
if levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
|
||||||
.btn.btn-small.beautify-code(title=beautifyShortcutVerbose)
|
.btn.btn-small.btn-illustrated.fullscreen-code(title=maximizeShortcutVerbose)
|
||||||
i.icon-magnet
|
.glyphicon.glyphicon-fullscreen
|
||||||
|
.glyphicon.glyphicon-resize-small
|
||||||
|
|
||||||
|
if codeLanguage === 'javascript' && levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
|
||||||
|
.btn.btn-small.btn-illustrated.beautify-code(title=beautifyShortcutVerbose)
|
||||||
|
.glyphicon.glyphicon-magnet
|
||||||
|
|
||||||
.clearfix
|
.clearfix
|
|
@ -1,8 +1,7 @@
|
||||||
img(src="/images/level/code_palette_background.png").code-palette-background
|
img(src="/images/level/code_palette_wood_background.png").code-palette-background
|
||||||
span.code-palette-background
|
span.code-palette-background
|
||||||
if entryGroupSlugs
|
if entryGroupSlugs
|
||||||
// Non-hero; group by entry groups, or maybe nothing.
|
// Non-hero; group by entry groups, or maybe nothing.
|
||||||
.code-language-logo
|
|
||||||
ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : ''))
|
ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : ''))
|
||||||
each slug, group in entryGroupSlugs
|
each slug, group in entryGroupSlugs
|
||||||
li(class=group == "this" || slug == "available-spells" ? "active" : "")
|
li(class=group == "this" || slug == "available-spells" ? "active" : "")
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#readwrite-thangs.thang-list-section
|
|
||||||
h3(data-i18n="play_level.tome_minion_spells") Your Minions' Spells
|
|
||||||
.thang-list
|
|
||||||
.clearfix
|
|
||||||
|
|
||||||
#read-thangs.thang-list-section
|
|
||||||
h3(data-i18n="play_level.tome_read_only_spells") Read-Only Spells
|
|
||||||
.thang-list
|
|
||||||
.clearfix
|
|
||||||
|
|
||||||
#muggle-thangs.thang-list-section
|
|
||||||
h3(data-i18n="play_level.tome_other_units") Other Units
|
|
||||||
.thang-list
|
|
||||||
.clearfix
|
|
|
@ -1,5 +0,0 @@
|
||||||
h4.not-code(data-i18n="play_level.tome_select_spell") Select a Spell
|
|
||||||
.thang-list-entry-spells
|
|
||||||
for spell in spells
|
|
||||||
div.thang-list-entry-spell
|
|
||||||
code(data-spell-name=spell.name) #{spell.name}(#{parameters})
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#spell-list-view
|
#spell-list-view
|
||||||
|
|
||||||
#thang-list-view
|
|
||||||
|
|
||||||
#cast-button-view
|
#cast-button-view
|
||||||
|
|
||||||
#spell-view
|
#spell-view
|
||||||
|
|
|
@ -2,9 +2,6 @@ CocoView = require 'views/kinds/CocoView'
|
||||||
template = require 'templates/play/level/playback'
|
template = require 'templates/play/level/playback'
|
||||||
{me} = require 'lib/auth'
|
{me} = require 'lib/auth'
|
||||||
|
|
||||||
EditorConfigModal = require './modal/EditorConfigModal'
|
|
||||||
KeyboardShortcutsModal = require './modal/KeyboardShortcutsModal'
|
|
||||||
|
|
||||||
module.exports = class LevelPlaybackView extends CocoView
|
module.exports = class LevelPlaybackView extends CocoView
|
||||||
id: 'playback-view'
|
id: 'playback-view'
|
||||||
template: template
|
template: template
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
ModalView = require 'views/kinds/ModalView'
|
|
||||||
template = require 'templates/play/level/modal/editor_config'
|
|
||||||
{me} = require 'lib/auth'
|
|
||||||
|
|
||||||
module.exports = class EditorConfigModal extends ModalView
|
|
||||||
id: 'level-editor-config-modal'
|
|
||||||
template: template
|
|
||||||
aceConfig: {}
|
|
||||||
|
|
||||||
defaultConfig:
|
|
||||||
language: 'python'
|
|
||||||
keyBindings: 'default'
|
|
||||||
invisibles: false
|
|
||||||
indentGuides: false
|
|
||||||
behaviors: false
|
|
||||||
liveCompletion: true
|
|
||||||
|
|
||||||
events:
|
|
||||||
'change #tome-invisibles': 'updateInvisibles'
|
|
||||||
'change #tome-language': 'updateLanguage'
|
|
||||||
'change #tome-key-bindings': 'updateKeyBindings'
|
|
||||||
'change #tome-indent-guides': 'updateIndentGuides'
|
|
||||||
'change #tome-behaviors': 'updateBehaviors'
|
|
||||||
'change #tome-live-completion': 'updateLiveCompletion'
|
|
||||||
|
|
||||||
constructor: (options) ->
|
|
||||||
super(options)
|
|
||||||
@session = options.session
|
|
||||||
|
|
||||||
getRenderData: ->
|
|
||||||
@aceConfig = _.cloneDeep me.get('aceConfig') ? {}
|
|
||||||
@aceConfig = _.defaults @aceConfig, @defaultConfig
|
|
||||||
c = super()
|
|
||||||
c.languages = [
|
|
||||||
{id: 'python', name: 'Python'}
|
|
||||||
{id: 'javascript', name: 'JavaScript'}
|
|
||||||
{id: 'coffeescript', name: 'CoffeeScript'}
|
|
||||||
{id: 'clojure', name: 'Clojure (Experimental)'}
|
|
||||||
{id: 'lua', name: 'Lua (Experimental)'}
|
|
||||||
{id: 'io', name: 'Io (Experimental)'}
|
|
||||||
]
|
|
||||||
c.sessionLanguage = @session.get('codeLanguage') ? @aceConfig.language
|
|
||||||
c.language = @aceConfig.language
|
|
||||||
c.keyBindings = @aceConfig.keyBindings
|
|
||||||
c.invisibles = @aceConfig.invisibles
|
|
||||||
c.indentGuides = @aceConfig.indentGuides
|
|
||||||
c.behaviors = @aceConfig.behaviors
|
|
||||||
c.liveCompletion = @aceConfig.liveCompletion
|
|
||||||
c
|
|
||||||
|
|
||||||
updateSessionLanguage: ->
|
|
||||||
@session.set 'codeLanguage', @$el.find('#tome-session-language').val()
|
|
||||||
|
|
||||||
updateLanguage: ->
|
|
||||||
@aceConfig.language = @$el.find('#tome-language').val()
|
|
||||||
|
|
||||||
updateInvisibles: ->
|
|
||||||
@aceConfig.invisibles = @$el.find('#tome-invisibles').prop('checked')
|
|
||||||
|
|
||||||
updateKeyBindings: ->
|
|
||||||
@aceConfig.keyBindings = @$el.find('#tome-key-bindings').val()
|
|
||||||
|
|
||||||
updateIndentGuides: ->
|
|
||||||
@aceConfig.indentGuides = @$el.find('#tome-indent-guides').prop('checked')
|
|
||||||
|
|
||||||
updateBehaviors: ->
|
|
||||||
@aceConfig.behaviors = @$el.find('#tome-behaviors').prop('checked')
|
|
||||||
|
|
||||||
updateLiveCompletion: ->
|
|
||||||
@aceConfig.liveCompletion = @$el.find('#tome-live-completion').prop('checked')
|
|
||||||
|
|
||||||
afterRender: ->
|
|
||||||
super()
|
|
||||||
|
|
||||||
onHidden: ->
|
|
||||||
oldLanguage = @session.get('codeLanguage') ? @aceConfig.language
|
|
||||||
newLanguage = @$el.find('#tome-session-language').val()
|
|
||||||
@session.set 'codeLanguage', newLanguage
|
|
||||||
@aceConfig.language = @$el.find('#tome-language').val()
|
|
||||||
@aceConfig.invisibles = @$el.find('#tome-invisibles').prop('checked')
|
|
||||||
@aceConfig.keyBindings = @$el.find('#tome-key-bindings').val()
|
|
||||||
@aceConfig.indentGuides = @$el.find('#tome-indent-guides').prop('checked')
|
|
||||||
@aceConfig.behaviors = @$el.find('#tome-behaviors').prop('checked')
|
|
||||||
@aceConfig.liveCompletion = @$el.find('#tome-live-completion').prop('checked')
|
|
||||||
me.set 'aceConfig', @aceConfig
|
|
||||||
Backbone.Mediator.publish 'tome:change-config', {}
|
|
||||||
Backbone.Mediator.publish 'tome:change-language', language: newLanguage unless newLanguage is oldLanguage
|
|
||||||
@session.save() unless newLanguage is oldLanguage
|
|
||||||
me.patch()
|
|
||||||
|
|
||||||
destroy: ->
|
|
||||||
super()
|
|
|
@ -33,7 +33,7 @@ module.exports = class CastButtonView extends CocoView
|
||||||
enter = $.i18n.t 'keyboard_shortcuts.enter'
|
enter = $.i18n.t 'keyboard_shortcuts.enter'
|
||||||
castShortcutVerbose = "#{shift}+#{enter}"
|
castShortcutVerbose = "#{shift}+#{enter}"
|
||||||
castRealTimeShortcutVerbose = (if @isMac() then 'Cmd' else 'Ctrl') + '+' + castShortcutVerbose
|
castRealTimeShortcutVerbose = (if @isMac() then 'Cmd' else 'Ctrl') + '+' + castShortcutVerbose
|
||||||
context.castVerbose = castShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.cast_spell')
|
context.castVerbose = castShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_code')
|
||||||
context.castRealTimeVerbose = castRealTimeShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_real_time')
|
context.castRealTimeVerbose = castRealTimeShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_real_time')
|
||||||
# A/B test submit button text
|
# A/B test submit button text
|
||||||
context.testSubmitText = @testButtonsText.submit if @testGroup? and @testGroup isnt 0
|
context.testSubmitText = @testButtonsText.submit if @testGroup? and @testGroup isnt 0
|
||||||
|
@ -105,7 +105,7 @@ module.exports = class CastButtonView extends CocoView
|
||||||
, (castable) =>
|
, (castable) =>
|
||||||
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
||||||
@castButton.toggleClass('castable', castable).toggleClass('casting', @casting)
|
@castButton.toggleClass('castable', castable).toggleClass('casting', @casting)
|
||||||
|
|
||||||
# A/B testing cast button text for en-US
|
# A/B testing cast button text for en-US
|
||||||
if $.i18n.lng() isnt 'en-US' or not @testGroup? or @testGroup is 0
|
if $.i18n.lng() isnt 'en-US' or not @testGroup? or @testGroup is 0
|
||||||
if @casting
|
if @casting
|
||||||
|
@ -160,5 +160,3 @@ module.exports = class CastButtonView extends CocoView
|
||||||
Action: 'Loaded'
|
Action: 'Loaded'
|
||||||
levelID: @levelID
|
levelID: @levelID
|
||||||
castButtonText: @testButtonsText.run + ' ' + @testButtonsText.submit
|
castButtonText: @testButtonsText.run + ' ' + @testButtonsText.submit
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ module.exports = class SpellListEntryView extends CocoView
|
||||||
context
|
context
|
||||||
|
|
||||||
createMethodSignature: ->
|
createMethodSignature: ->
|
||||||
|
return @spell.name if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
parameters = (@spell.parameters or []).slice()
|
parameters = (@spell.parameters or []).slice()
|
||||||
if @spell.language in ['python', 'lua']
|
if @spell.language in ['python', 'lua']
|
||||||
parameters.unshift 'self'
|
parameters.unshift 'self'
|
||||||
|
|
|
@ -61,7 +61,7 @@ module.exports = class SpellListView extends CocoView
|
||||||
theseThangs = _.keys(spell.thangs)
|
theseThangs = _.keys(spell.thangs)
|
||||||
changedThangs = not lastThangs or not _.isEqual theseThangs, lastThangs
|
changedThangs = not lastThangs or not _.isEqual theseThangs, lastThangs
|
||||||
lastThangs = theseThangs
|
lastThangs = theseThangs
|
||||||
newEntries.push entry = new SpellListEntryView spell: spell, showTopDivider: changedThangs, supermodel: @supermodel, includeSpellList: @spells.length > 1
|
newEntries.push entry = new SpellListEntryView spell: spell, showTopDivider: changedThangs, supermodel: @supermodel, includeSpellList: @spells.length > 1, level: @options.level
|
||||||
@entries.push entry
|
@entries.push entry
|
||||||
for entry in newEntries
|
for entry in newEntries
|
||||||
@$el.append entry.el
|
@$el.append entry.el
|
||||||
|
|
|
@ -5,7 +5,6 @@ filters = require 'lib/image_filter'
|
||||||
SpellPaletteEntryView = require './SpellPaletteEntryView'
|
SpellPaletteEntryView = require './SpellPaletteEntryView'
|
||||||
LevelComponent = require 'models/LevelComponent'
|
LevelComponent = require 'models/LevelComponent'
|
||||||
ThangType = require 'models/ThangType'
|
ThangType = require 'models/ThangType'
|
||||||
EditorConfigModal = require '../modal/EditorConfigModal'
|
|
||||||
|
|
||||||
N_ROWS = 4
|
N_ROWS = 4
|
||||||
|
|
||||||
|
@ -20,9 +19,6 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
'surface:frame-changed': 'onFrameChanged'
|
'surface:frame-changed': 'onFrameChanged'
|
||||||
'tome:change-language': 'onTomeChangedLanguage'
|
'tome:change-language': 'onTomeChangedLanguage'
|
||||||
|
|
||||||
events:
|
|
||||||
'click .code-language-logo': 'onEditEditorConfig'
|
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
@thang = options.thang
|
@thang = options.thang
|
||||||
|
@ -54,7 +50,7 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
@entryGroupElements = {}
|
@entryGroupElements = {}
|
||||||
for group, entries of @entryGroups
|
for group, entries of @entryGroups
|
||||||
@entryGroupElements[group] = itemGroup = $('<div class="property-entry-item-group"></div>').appendTo @$el.find('.properties')
|
@entryGroupElements[group] = itemGroup = $('<div class="property-entry-item-group"></div>').appendTo @$el.find('.properties')
|
||||||
itemGroup.append $('<img class="item-image"></img>').attr('src', entries[0].options.item.getPortraitURL()).css('top', Math.max(0, 19 * (entries.length - 2) / 2)) if entries[0].options.item?.getPortraitURL
|
itemGroup.append $('<img class="item-image"></img>').attr('src', entries[0].options.item.getPortraitURL()).css('top', Math.max(0, 19 * (entries.length - 2) / 2) + 2) if entries[0].options.item?.getPortraitURL
|
||||||
for entry in entries
|
for entry in entries
|
||||||
itemGroup.append entry.el
|
itemGroup.append entry.el
|
||||||
entry.render() # Render after appending so that we can access parent container for popover
|
entry.render() # Render after appending so that we can access parent container for popover
|
||||||
|
@ -67,7 +63,6 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
|
|
||||||
updateCodeLanguage: (language) ->
|
updateCodeLanguage: (language) ->
|
||||||
@options.language = language
|
@options.language = language
|
||||||
@$el.find('.code-language-logo').removeClass().addClass 'code-language-logo ' + language
|
|
||||||
|
|
||||||
updateMaxHeight: ->
|
updateMaxHeight: ->
|
||||||
return unless @isHero
|
return unless @isHero
|
||||||
|
@ -266,9 +261,6 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
@createPalette()
|
@createPalette()
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
onEditEditorConfig: (e) ->
|
|
||||||
@openModalView new EditorConfigModal session: @options.session
|
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
entry.destroy() for entry in @entries
|
entry.destroy() for entry in @entries
|
||||||
@toggleBackground = null
|
@toggleBackground = null
|
||||||
|
|
|
@ -360,10 +360,10 @@ module.exports = class SpellView extends CocoView
|
||||||
spellPaletteHeight = $('#spell-palette-view').outerHeight()
|
spellPaletteHeight = $('#spell-palette-view').outerHeight()
|
||||||
maxHeight = tomeHeight - spellListTabEntryHeight - spellToolbarHeight - spellPaletteHeight
|
maxHeight = tomeHeight - spellListTabEntryHeight - spellToolbarHeight - spellPaletteHeight
|
||||||
linesAtMaxHeight = Math.floor(maxHeight / lineHeight)
|
linesAtMaxHeight = Math.floor(maxHeight / lineHeight)
|
||||||
lines = Math.max 8, Math.min(screenLineCount + 4, linesAtMaxHeight)
|
lines = Math.max 8, Math.min(screenLineCount + 2, linesAtMaxHeight)
|
||||||
# 2 lines buffer is nice, but 4 leaves room to put problem alerts.
|
# 2 lines buffer is nice
|
||||||
@ace.setOptions minLines: lines, maxLines: lines
|
@ace.setOptions minLines: lines, maxLines: lines
|
||||||
$('#spell-palette-view').css('top', 38 + 45 + lineHeight * lines) # Move spell palette up, slightly underlapping us.
|
$('#spell-palette-view').css('top', 175 + lineHeight * lines) # Move spell palette up, slightly overlapping us.
|
||||||
|
|
||||||
onManualCast: (e) ->
|
onManualCast: (e) ->
|
||||||
cast = @$el.parent().length
|
cast = @$el.parent().length
|
||||||
|
|
|
@ -1,178 +0,0 @@
|
||||||
# TODO: be useful to add error indicator states to the spellsPopoverTemplate
|
|
||||||
# TODO: reordering based on errors isn't working yet
|
|
||||||
|
|
||||||
CocoView = require 'views/kinds/CocoView'
|
|
||||||
ThangAvatarView = require 'views/play/level/ThangAvatarView'
|
|
||||||
template = require 'templates/play/level/tome/thang_list_entry'
|
|
||||||
spellsPopoverTemplate = require 'templates/play/level/tome/thang_list_entry_spells'
|
|
||||||
{me} = require 'lib/auth'
|
|
||||||
|
|
||||||
module.exports = class ThangListEntryView extends CocoView
|
|
||||||
tagName: 'div' #'li'
|
|
||||||
className: 'thang-list-entry-view'
|
|
||||||
template: template
|
|
||||||
controlsEnabled: true
|
|
||||||
reasonsToBeDisabled: {}
|
|
||||||
|
|
||||||
subscriptions:
|
|
||||||
'tome:problems-updated': 'onProblemsUpdated'
|
|
||||||
'level:disable-controls': 'onDisableControls'
|
|
||||||
'level:enable-controls': 'onEnableControls'
|
|
||||||
'surface:frame-changed': 'onFrameChanged'
|
|
||||||
'level:set-letterbox': 'onSetLetterbox'
|
|
||||||
'tome:thang-list-entry-popover-shown': 'onThangListEntryPopoverShown'
|
|
||||||
'surface:coordinates-shown': 'onSurfaceCoordinatesShown'
|
|
||||||
|
|
||||||
events:
|
|
||||||
'click': 'onClick'
|
|
||||||
'mouseenter': 'onMouseEnter'
|
|
||||||
'mouseleave': 'onMouseLeave'
|
|
||||||
|
|
||||||
constructor: (options) ->
|
|
||||||
super options
|
|
||||||
@thang = options.thang
|
|
||||||
@spells = options.spells
|
|
||||||
@permission = options.permission
|
|
||||||
@reasonsToBeDisabled = {}
|
|
||||||
@sortSpells()
|
|
||||||
|
|
||||||
getRenderData: (context={}) ->
|
|
||||||
context = super context
|
|
||||||
context.thang = @thang
|
|
||||||
context.spell = @spells
|
|
||||||
context
|
|
||||||
|
|
||||||
afterRender: ->
|
|
||||||
super()
|
|
||||||
@avatar?.destroy()
|
|
||||||
@avatar = new ThangAvatarView thang: @thang, includeName: true, supermodel: @supermodel
|
|
||||||
@$el.append @avatar.el # Before rendering, so render can use parent for popover
|
|
||||||
@avatar.render()
|
|
||||||
@avatar.setSharedThangs @spells.length # A bit weird to call it sharedThangs; could refactor if we like this
|
|
||||||
@$el.toggle Boolean(@thang.exists)
|
|
||||||
@$el.popover(
|
|
||||||
animation: false
|
|
||||||
html: true
|
|
||||||
placement: 'bottom'
|
|
||||||
trigger: 'manual'
|
|
||||||
content: @getSpellListHTML()
|
|
||||||
container: @$el.parent().parent().parent()
|
|
||||||
)
|
|
||||||
|
|
||||||
sortSpells: ->
|
|
||||||
return if @sorted
|
|
||||||
# Keep only spells for which we have permissions
|
|
||||||
spells = _.filter @spells, (s) => @options.permission and me.team in s.permissions[@options.permission]
|
|
||||||
@spells = _.sortBy spells, @sortScoreForSpell
|
|
||||||
@sorted = true
|
|
||||||
|
|
||||||
sortScoreForSpell: (s) =>
|
|
||||||
# Sort by errored-out spells first, then spells shared with fewest other Thangs
|
|
||||||
# Lower comes first
|
|
||||||
score = 0
|
|
||||||
# My errors are highest priority
|
|
||||||
score -= 9001900190019001 * (s.thangs[@thang.id].aether?.getAllProblems().length or 0)
|
|
||||||
# Other shared Thangs errors are also high priority
|
|
||||||
score -= _.reduce s.thangs, (spellThang, num) -> 900190019001 * (spellThang.aether?.getAllProblems().length or 0)
|
|
||||||
# Read-only spells at the bottom
|
|
||||||
score += 90019001 unless s.canWrite()
|
|
||||||
# The more Thangs sharing a spell, the lower
|
|
||||||
score += 9001 * _.size(s.thangs)
|
|
||||||
score
|
|
||||||
|
|
||||||
select: ->
|
|
||||||
@sortSpells()
|
|
||||||
Backbone.Mediator.publish 'level:select-sprite', thangID: @thang.id, spellName: @spells[0]?.name
|
|
||||||
|
|
||||||
onClick: (e) ->
|
|
||||||
return unless @controlsEnabled
|
|
||||||
@select()
|
|
||||||
|
|
||||||
onMouseEnter: (e) ->
|
|
||||||
return unless @controlsEnabled and @spells.length
|
|
||||||
@clearTimeouts()
|
|
||||||
@showSpellsTimeout = _.delay @showSpells, 100
|
|
||||||
|
|
||||||
onMouseLeave: (e) ->
|
|
||||||
return unless @controlsEnabled and @spells.length
|
|
||||||
@clearTimeouts()
|
|
||||||
@hideSpellsTimeout = _.delay @hideSpells, 100
|
|
||||||
|
|
||||||
clearTimeouts: ->
|
|
||||||
clearTimeout @showSpellsTimeout if @showSpellsTimeout
|
|
||||||
clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
|
|
||||||
@showSpellsTimeout = @hideSpellsTimeout = null
|
|
||||||
|
|
||||||
onThangListEntryPopoverShown: (e) ->
|
|
||||||
# I couldn't figure out how to get the mouseenter / mouseleave to always work, so this is a fallback
|
|
||||||
# to hide our popover if another Thang's popover gets shown.
|
|
||||||
return if e.entry is @
|
|
||||||
@hideSpells()
|
|
||||||
|
|
||||||
onSurfaceCoordinatesShown: (e) ->
|
|
||||||
# Definitely aren't hovering over this.
|
|
||||||
@hideSpells()
|
|
||||||
|
|
||||||
showSpells: =>
|
|
||||||
@clearTimeouts()
|
|
||||||
@sortSpells()
|
|
||||||
@$el.data('bs.popover').options.content = @getSpellListHTML()
|
|
||||||
@$el.popover('setContent').popover('show')
|
|
||||||
@$el.parent().parent().parent().i18n()
|
|
||||||
@popover = @$el.parent().parent().parent().find('.popover')
|
|
||||||
@popover.off 'mouseenter mouseleave'
|
|
||||||
@popover.mouseenter (e) => @showSpells() if @controlsEnabled
|
|
||||||
@popover.mouseleave (e) => @hideSpells()
|
|
||||||
thangID = @thang.id
|
|
||||||
@popover.find('code').click (e) ->
|
|
||||||
Backbone.Mediator.publish 'level:select-sprite', thangID: thangID, spellName: $(@).data 'spell-name'
|
|
||||||
Backbone.Mediator.publish 'tome:thang-list-entry-popover-shown', entry: @
|
|
||||||
|
|
||||||
hideSpells: =>
|
|
||||||
@clearTimeouts()
|
|
||||||
@$el.popover('hide')
|
|
||||||
|
|
||||||
getSpellListHTML: ->
|
|
||||||
spellsPopoverTemplate {spells: @spells}
|
|
||||||
|
|
||||||
onProblemsUpdated: (e) ->
|
|
||||||
return unless e.spell in @spells
|
|
||||||
@sorted = false
|
|
||||||
|
|
||||||
onSetLetterbox: (e) ->
|
|
||||||
if e.on then @reasonsToBeDisabled.letterbox = true else delete @reasonsToBeDisabled.letterbox
|
|
||||||
@updateControls()
|
|
||||||
|
|
||||||
onDisableControls: (e) ->
|
|
||||||
return if e.controls and not ('surface' in e.controls) # disable selection?
|
|
||||||
@reasonsToBeDisabled.controls = true
|
|
||||||
@updateControls()
|
|
||||||
|
|
||||||
onEnableControls: (e) ->
|
|
||||||
delete @reasonsToBeDisabled.controls
|
|
||||||
@updateControls()
|
|
||||||
|
|
||||||
updateControls: ->
|
|
||||||
enabled = _.keys(@reasonsToBeDisabled).length is 0
|
|
||||||
return if enabled is @controlsEnabled
|
|
||||||
@controlsEnabled = enabled
|
|
||||||
@$el.toggleClass('disabled', not enabled)
|
|
||||||
|
|
||||||
onFrameChanged: (e) ->
|
|
||||||
# Optimize
|
|
||||||
return unless currentThang = e.world.thangMap[@thang.id]
|
|
||||||
exists = Boolean currentThang.exists
|
|
||||||
if @thangDidExist isnt exists
|
|
||||||
@$el.toggle exists
|
|
||||||
@thangDidExist = exists
|
|
||||||
dead = exists and currentThang.health <= 0
|
|
||||||
if @thangWasDead isnt dead
|
|
||||||
@$el.toggleClass 'dead', dead
|
|
||||||
@thangWasDead = dead
|
|
||||||
|
|
||||||
destroy: ->
|
|
||||||
@avatar?.destroy()
|
|
||||||
@popover?.remove()
|
|
||||||
@popover?.off 'mouseenter mouseleave'
|
|
||||||
@popover?.find('code').off 'click'
|
|
||||||
super()
|
|
|
@ -1,95 +0,0 @@
|
||||||
# The ThangListView lives in the code area behind the SpellView, so that when you don't have a spell, you can select any Thang.
|
|
||||||
# It just ha a bunch of ThangListEntryViews (which are mostly ThangAvatarViews) in a few sections.
|
|
||||||
|
|
||||||
CocoView = require 'views/kinds/CocoView'
|
|
||||||
template = require 'templates/play/level/tome/thang_list'
|
|
||||||
{me} = require 'lib/auth'
|
|
||||||
ThangListEntryView = require './ThangListEntryView'
|
|
||||||
|
|
||||||
module.exports = class ThangListView extends CocoView
|
|
||||||
className: 'thang-list-view'
|
|
||||||
id: 'thang-list-view'
|
|
||||||
template: template
|
|
||||||
|
|
||||||
constructor: (options) ->
|
|
||||||
super options
|
|
||||||
@spells = options.spells
|
|
||||||
@thangs = _.filter options.thangs, 'isSelectable'
|
|
||||||
@sortThangs()
|
|
||||||
|
|
||||||
sortThangs: ->
|
|
||||||
@readwriteThangs = _.sortBy _.filter(@thangs, (thang) =>
|
|
||||||
return true for spellKey, spell of @spells when thang.id of spell.thangs and spell.canWrite()
|
|
||||||
false
|
|
||||||
), @sortScoreForThang
|
|
||||||
@readThangs = _.sortBy _.filter(@thangs, (thang) =>
|
|
||||||
return true for spellKey, spell of @spells when thang.id of spell.thangs and spell.canRead() and not spell.canWrite()
|
|
||||||
false
|
|
||||||
), @sortScoreForThang
|
|
||||||
@muggleThangs = _.sortBy _.without(@thangs, @readwriteThangs..., @readThangs...), @sortScoreForThang
|
|
||||||
if @muggleThangs.length > 15
|
|
||||||
@muggleThangs = [] # Don't render a zillion of these. Slow, too long, maybe not useful.
|
|
||||||
|
|
||||||
sortScoreForThang: (t) =>
|
|
||||||
# Sort by my team, then most spells and fewest shared Thangs per spell,
|
|
||||||
# then by thang.spriteName alpha, then by thang.id alpha.
|
|
||||||
# Lower comes first
|
|
||||||
score = 0
|
|
||||||
# Thangs on my team are highest priority
|
|
||||||
score -= 9001900190019001 if t.team is me.team
|
|
||||||
# The more spells per Thang, the lower
|
|
||||||
score -= 900190019001 for spellKey, spell of @spells when t.id of spell.thangs and spell.canRead()
|
|
||||||
# The more Thangs per spell, the higher
|
|
||||||
score += 90019001 for t2 of spell.thangs for spellKey, spell of @spells when t.id of spell.thangs
|
|
||||||
alpha = (s) -> _.reduce [0 ... s.length], ((acc, i) -> acc + s.charCodeAt(i) / Math.pow(100, i)), 0
|
|
||||||
# Alpha by spriteName
|
|
||||||
score += 9001 * alpha t.spriteName
|
|
||||||
# Alpha by id
|
|
||||||
score += alpha t.id
|
|
||||||
score
|
|
||||||
|
|
||||||
afterRender: ->
|
|
||||||
super()
|
|
||||||
@addThangListEntries()
|
|
||||||
|
|
||||||
addThangListEntries: ->
|
|
||||||
@entries = []
|
|
||||||
for [thangs, section, permission] in [
|
|
||||||
[@readwriteThangs, '#readwrite-thangs', 'readwrite'] # Your Minions
|
|
||||||
[@readThangs, '#read-thangs', 'read'] # Read-Only
|
|
||||||
[@muggleThangs, '#muggle-thangs', null] # Non-Castable
|
|
||||||
]
|
|
||||||
section = @$el.find(section).toggle thangs.length > 0
|
|
||||||
for thang in thangs
|
|
||||||
spells = _.filter @spells, (s) -> thang.id of s.thangs
|
|
||||||
entry = new ThangListEntryView thang: thang, spells: spells, permission: permission, supermodel: @supermodel
|
|
||||||
section.find('.thang-list').append entry.el # Render after appending so that we can access parent container for popover
|
|
||||||
entry.render()
|
|
||||||
@entries.push entry
|
|
||||||
|
|
||||||
topSpellForThang: (thang) ->
|
|
||||||
for entry in @entries when entry.thang.id is thang.id
|
|
||||||
return entry.spells[0]
|
|
||||||
null
|
|
||||||
|
|
||||||
selectPrimarySprite: ->
|
|
||||||
@entries[0]?.select()
|
|
||||||
|
|
||||||
adjustThangs: (spells, thangs) ->
|
|
||||||
# TODO: it would be nice to not have to do this any more, like if we migrate to the hero levels.
|
|
||||||
# Recreating all the ThangListEntryViews and their ThangAvatarViews is pretty slow.
|
|
||||||
# So they aren't even kept up-to-date during world streaming.
|
|
||||||
# Updating the existing subviews? Would be kind of complicated to get all the new thangs and spells propagated.
|
|
||||||
# I would do it, if I didn't think we were perhaps soon to not do the ThangList any more.
|
|
||||||
# Will temporary reduce the number of muggle thangs we're willing to draw.
|
|
||||||
@spells = @options.spells = spells
|
|
||||||
for entry in @entries
|
|
||||||
entry.$el.remove()
|
|
||||||
entry.destroy()
|
|
||||||
@thangs = @options.thangs = thangs
|
|
||||||
@sortThangs()
|
|
||||||
@addThangListEntries()
|
|
||||||
|
|
||||||
destroy: ->
|
|
||||||
entry.destroy() for entry in @entries
|
|
||||||
super()
|
|
|
@ -32,7 +32,6 @@ template = require 'templates/play/level/tome/tome'
|
||||||
{me} = require 'lib/auth'
|
{me} = require 'lib/auth'
|
||||||
Spell = require './Spell'
|
Spell = require './Spell'
|
||||||
SpellListView = require './SpellListView'
|
SpellListView = require './SpellListView'
|
||||||
ThangListView = require './ThangListView'
|
|
||||||
SpellPaletteView = require './SpellPaletteView'
|
SpellPaletteView = require './SpellPaletteView'
|
||||||
CastButtonView = require './CastButtonView'
|
CastButtonView = require './CastButtonView'
|
||||||
|
|
||||||
|
@ -62,8 +61,7 @@ module.exports = class TomeView extends CocoView
|
||||||
#programmableThangs = _.filter @options.thangs, (t) -> t.isProgrammable and t.spriteName isnt 'Hero Placeholder'
|
#programmableThangs = _.filter @options.thangs, (t) -> t.isProgrammable and t.spriteName isnt 'Hero Placeholder'
|
||||||
programmableThangs = _.filter @options.thangs, 'isProgrammable'
|
programmableThangs = _.filter @options.thangs, 'isProgrammable'
|
||||||
@createSpells programmableThangs, programmableThangs[0]?.world # Do before spellList, thangList, and castButton
|
@createSpells programmableThangs, programmableThangs[0]?.world # Do before spellList, thangList, and castButton
|
||||||
@spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel
|
@spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel, level: @options.level
|
||||||
@thangList = @insertSubView new ThangListView spells: @spells, thangs: @options.thangs, supermodel: @supermodel unless @options.level.get('type', true) is 'hero'
|
|
||||||
@castButton = @insertSubView new CastButtonView spells: @spells, levelID: @options.levelID
|
@castButton = @insertSubView new CastButtonView spells: @spells, levelID: @options.levelID
|
||||||
@teamSpellMap = @generateTeamSpellMap(@spells)
|
@teamSpellMap = @generateTeamSpellMap(@spells)
|
||||||
unless programmableThangs.length
|
unless programmableThangs.length
|
||||||
|
@ -77,7 +75,6 @@ module.exports = class TomeView extends CocoView
|
||||||
thangs = _.filter e.world.thangs, 'inThangList'
|
thangs = _.filter e.world.thangs, 'inThangList'
|
||||||
programmableThangs = _.filter thangs, 'isProgrammable'
|
programmableThangs = _.filter thangs, 'isProgrammable'
|
||||||
@createSpells programmableThangs, e.world
|
@createSpells programmableThangs, e.world
|
||||||
@thangList?.adjustThangs @spells, thangs
|
|
||||||
@spellList.adjustSpells @spells
|
@spellList.adjustSpells @spells
|
||||||
|
|
||||||
onCommentMyCode: (e) ->
|
onCommentMyCode: (e) ->
|
||||||
|
@ -187,7 +184,6 @@ module.exports = class TomeView extends CocoView
|
||||||
@spellPaletteView = null
|
@spellPaletteView = null
|
||||||
@$el.find('#spell-palette-view').hide()
|
@$el.find('#spell-palette-view').hide()
|
||||||
@castButton?.$el.hide()
|
@castButton?.$el.hide()
|
||||||
@thangList?.$el.show()
|
|
||||||
|
|
||||||
onSpriteSelected: (e) ->
|
onSpriteSelected: (e) ->
|
||||||
return if @spellView and @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] # Never deselect the hero in the Tome.
|
return if @spellView and @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] # Never deselect the hero in the Tome.
|
||||||
|
@ -207,7 +203,6 @@ module.exports = class TomeView extends CocoView
|
||||||
@$el.find('#' + @spellView.id).after(@spellView.el).remove()
|
@$el.find('#' + @spellView.id).after(@spellView.el).remove()
|
||||||
@$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
|
@$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
|
||||||
@castButton.attachTo @spellView
|
@castButton.attachTo @spellView
|
||||||
@thangList?.$el.hide()
|
|
||||||
Backbone.Mediator.publish 'tome:spell-shown', thang: thang, spell: spell
|
Backbone.Mediator.publish 'tome:spell-shown', thang: thang, spell: spell
|
||||||
@updateSpellPalette thang, spell
|
@updateSpellPalette thang, spell
|
||||||
@spellList.setThangAndSpell thang, spell
|
@spellList.setThangAndSpell thang, spell
|
||||||
|
@ -217,7 +212,7 @@ module.exports = class TomeView extends CocoView
|
||||||
updateSpellPalette: (thang, spell) ->
|
updateSpellPalette: (thang, spell) ->
|
||||||
return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties
|
return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties
|
||||||
@spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell?.language ? @options.session.get('codeLanguage'), session: @options.session, level: @options.level
|
@spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell?.language ? @options.session.get('codeLanguage'), session: @options.session, level: @options.level
|
||||||
@spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell # TODO: know when palette should have been disabled but didn't exist
|
@spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell?.view # TODO: know when palette should have been disabled but didn't exist
|
||||||
|
|
||||||
spellFor: (thang, spellName) ->
|
spellFor: (thang, spellName) ->
|
||||||
return null unless thang?.isProgrammable
|
return null unless thang?.isProgrammable
|
||||||
|
@ -225,9 +220,6 @@ module.exports = class TomeView extends CocoView
|
||||||
selectedThangSpells = (@spells[spellKey] for spellKey in @thangSpells[thang.id])
|
selectedThangSpells = (@spells[spellKey] for spellKey in @thangSpells[thang.id])
|
||||||
if spellName
|
if spellName
|
||||||
spell = _.find selectedThangSpells, {name: spellName}
|
spell = _.find selectedThangSpells, {name: spellName}
|
||||||
else if @thangList
|
|
||||||
spell = @thangList.topSpellForThang thang
|
|
||||||
#spell = selectedThangSpells[0] # TODO: remember last selected spell for this thang
|
|
||||||
else
|
else
|
||||||
spell = _.find selectedThangSpells, (spell) -> true # Just grab one
|
spell = _.find selectedThangSpells, (spell) -> true # Just grab one
|
||||||
spell
|
spell
|
||||||
|
@ -241,10 +233,8 @@ module.exports = class TomeView extends CocoView
|
||||||
@cast()
|
@cast()
|
||||||
|
|
||||||
onSelectPrimarySprite: (e) ->
|
onSelectPrimarySprite: (e) ->
|
||||||
if @thangList
|
# TODO: this may not be correct
|
||||||
@thangList.selectPrimarySprite()
|
Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder'
|
||||||
else
|
|
||||||
Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder'
|
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
spell.destroy() for spellKey, spell of @spells
|
spell.destroy() for spellKey, spell of @spells
|
||||||
|
|